[
  {
    "path": ".dockerignore",
    "content": ".git\n.gitignore\n.DS_Store\n.pytest_cache\n__pycache__\n*.pyc\n*.pyo\n*.pyd\n\n# Local build outputs\nbuild\ndist\n*.egg-info\ndesktop_app/dist\ndesktop_app/backend_dist\ndesktop_app/node_modules\nbackend_build/.pyi_work\nbackend_build/.venv_arm64\nbackend_build/.venv_x64\nbackend_build/.venv*\n\n# Desktop-only sources and caches\ndesktop_app\nbackend_build\n\n# Tests, docs, local tools, and misc repo-only files\ntests\ndocs\nassets\napps\nmarketplace_server\nweb_ui/server/user_data\nweb_ui/server/__pycache__\nconversations\nlogs\nresults\ntmp\nTest\n\n# Local runtime/config state\nconfig/run_env_config/llm_config.yaml\n"
  },
  {
    "path": ".gitignore",
    "content": "# Python\n__pycache__/\n*.py[cod]\n*$py.class\n*.so\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# Virtual Environment\nvenv/\nenv/\nENV/\n\n# IDEs\n.vscode/\n.idea/\n.cursor/\n*.swp\n*.swo\n*~\n\n# Logs\n*.log\nlogs/\n\n# OS\n.DS_Store\nThumbs.db\n\n# Project specific\n# conversations/\nconfig/run_env_config/llm_config.yaml\n.env\n\n# Desktop app\ndesktop_app/node_modules/\ndesktop_app/dist/\ndesktop_app/out/\ndesktop_app/backend_dist/\n\n# Packaging/build artifacts\nbackend_build/.pyi_work/\nbackend_build/.venv_arm64/\nbackend_build/.venv_x64/\nbackend_build/__pycache__/\n\n# Local test/debug artifacts\nmodel_tool_calling_test_results.json\ntests/debug_messages.json\ntests/*.png\nTest/\ntmp/\nweb_ui/server/user_data/\n\n# Large demo media are kept outside git to avoid bloating repository history\nassets/*.mp4\nassets/paper_generation_demo_*.gif\nweb_ui/*.mp4\n\n# Docker related\ndocker-compose.yml\n*.tar.gz\nmla-docker-build.tar.gz\ntest_doc/\n\n# workspace\nworkspace\nworkspace/*\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM python:3.12-slim-bookworm\n\nARG HTTP_PROXY\nARG HTTPS_PROXY\nARG ALL_PROXY\nARG http_proxy\nARG https_proxy\nARG all_proxy\n\nENV PYTHONUNBUFFERED=1 \\\n    PIP_NO_CACHE_DIR=1 \\\n    PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \\\n    LANG=C.UTF-8 \\\n    LC_ALL=C.UTF-8\n\nWORKDIR /app\n\nRUN HTTP_PROXY=\"${HTTP_PROXY}\" HTTPS_PROXY=\"${HTTPS_PROXY}\" ALL_PROXY=\"${ALL_PROXY}\" \\\n    http_proxy=\"${http_proxy}\" https_proxy=\"${https_proxy}\" all_proxy=\"${all_proxy}\" \\\n    apt-get update && apt-get install -y --no-install-recommends \\\n    bash \\\n    ca-certificates \\\n    curl \\\n    git \\\n    lsof \\\n    procps \\\n    tini \\\n    && rm -rf /var/lib/apt/lists/*\nCOPY MANIFEST.in pyproject.toml requirements.txt setup.py README.md start.py /app/\nCOPY config /app/config\nCOPY core /app/core\nCOPY infiagent /app/infiagent\nCOPY services /app/services\nCOPY skills /app/skills\nCOPY tool_server_lite /app/tool_server_lite\nCOPY utils /app/utils\nCOPY web_ui /app/web_ui\nCOPY docker /app/docker\n\nRUN HTTP_PROXY=\"${HTTP_PROXY}\" HTTPS_PROXY=\"${HTTPS_PROXY}\" ALL_PROXY=\"${ALL_PROXY}\" \\\n    http_proxy=\"${http_proxy}\" https_proxy=\"${https_proxy}\" all_proxy=\"${all_proxy}\" \\\n    python -m pip install --upgrade pip setuptools wheel \\\n    && python -m pip install . \\\n    && python -m pip install -r web_ui/requirements.txt \\\n    && python -m playwright install --with-deps chromium\n\nRUN chmod +x /app/docker/entrypoint.sh\nRUN mkdir -p /workspace /root/mla_v3\n\nEXPOSE 4242\n\nHEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \\\n    CMD curl -f http://localhost:4242/health || exit 1\n\nENTRYPOINT [\"/usr/bin/tini\", \"--\", \"/app/docker/entrypoint.sh\"]\nCMD [\"webui\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include README.md\ninclude LICENSE\ninclude requirements.txt\nrecursive-include config *.yaml\nrecursive-include skills *\nrecursive-include tool_server_lite *.py *.md *.txt\nexclude conversations/*\nexclude task_*\nexclude *.log\nexclude .DS_Store\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <img src=\"assets/logo.png\" alt=\"infiAgent Logo\" width=\"200\">\n\n  <h1>MLA V3 - Build Domain-Specific SOTA-Level AI Agents</h1>\n\n  <p>\n    <img src=\"https://img.shields.io/badge/version-3.2.1-blue.svg\" alt=\"Version\">\n    <img src=\"https://img.shields.io/badge/python-3.9+-green.svg\" alt=\"Python\">\n    <img src=\"https://img.shields.io/badge/license-GPL-blue.svg\" alt=\"License: GPL\">\n  </p>\n\n  <p>\n    <a href=\"README.md\">English</a> | <a href=\"README_CN.md\">简体中文</a>\n  </p>\n</div>\n\n---\n\n## 🌟 Introduction\n\n**infiAgent Also called MLA (Multi-Level Agent)** is an agent framework designed for **unlimited runtime** without tool calling chaos or system crashes caused by cumulative task resources and conversation history. With MLA, you can build powerful general-purpose and semi-specialized agents simply by writing configuration files.\n\n### Key Features\n\n- ✅ **Days-Long Complex Tasks**: Supports continuous execution over days without context accumulation or compression degradation. Any interruption (crash, network error, manual stop) can be fully recovered via Resume — true breakpoint continuation.\n- ✅ **Agent Skills Standard**: Compatible with the [Agent Skills open standard](https://agentskills.io/). Drop skill folders into the skills library and agents will discover, load, and execute them on demand.\n- ✅ **Flexible Agent Architecture**: Supports both **multi-level hierarchy** (tree-structured orchestration for complex domain tasks — e.g., the `Researcher` config enables long-running scientific research with paper generation) and **flat architecture** (single agent with one sub-agent + Skills for broad general-purpose tasks — e.g., the OpenCowork config).\n- ✅ **Persistent Memory**: File-directory-based memory system. Launch agents in the same workspace directory and they remember all historical tasks across sessions — no external database required.\n\n### Update & News🔥\n\nIf you pulled the image or code before the latest update date, please refer to the issues that have been fixed and, based on your needs, pull the image and code again.\n\n- [2026/03/31] **Switchable Thinking / ReAct execution mode + task-history database retrieval:** Runtime now supports a switchable cadence model. You can keep the original ThinkingAgent-style “plan first, then execute N steps” workflow, or disable thinking and fall back to an explicit ReAct loop where reflection text is persisted directly inside the message history. Historical task records are also indexed into a local SQLite database, and agents now get a built-in `task_history_search` tool by default. The SDK can expose only the most recent N historical tasks into prompt context, and agents are explicitly instructed to retrieve older task history from the database when recent context is not enough.\n\n- [2026/03/30] **SDK / mac / Web UI model configuration is now much easier for non-experts:** The SDK now accepts structured model profiles directly instead of forcing every integration to hand-write `llm_config.yaml`. The mac desktop app and Docker Web UI both now expose a source-based model editor: you configure the default `base_url` / `api_key` once, then add multiple shared or per-slot models, and each row can either reuse the default source or switch to a custom URL / key. Raw YAML / JSON remain available as advanced fallbacks, but most users no longer need to manually type prefixes or JSON model objects.\n\n- [2026/03/23] **Docker Web UI now supports multi-user registration and account management:** The latest `chenglinhku/mlav3:latest` image runs the SDK-based Web UI directly with the new `webui` startup command on port `4242`. Users can register from the login page, and the bootstrap admin account can manage users inside the Web UI. Please follow the updated Docker command in Quick Start / `docs/DOCKER_GUIDE.md`: mount `~/.mla_v3` to `/root/mla_v3`, publish `4242`, and use `chenglinhku/mlav3:latest webui`. The old standalone config page flow on `9641` is no longer required.\n\n- [2026/03/19] **CheapClaw released on top of the `infiagent` SDK:** CheapClaw now ships as an SDK-based application layer. It keeps most of OpenCowork's practical capabilities, including custom bots, multi-bot collaboration workflows, IM integrations, and Skills, while inheriting the full `infiagent` runtime model: a multi-agent system behind a single bot, low-cost long-horizon tasks, and task-scoped context isolation inside one bot. Different tasks under the same bot now keep isolated contexts, while messages routed to the same task continue in the same long-running context instead of sharing one bot-wide session. [Click here to view CheapClaw](https://github.com/polyuiislab/CheapClaw).\n\n- [2026/03/19] **Finer-grained per-agent model configuration:** Each sub-agent can now configure `execution_model`, `thinking_model`, `compressor_model`, `image_generation_model`, and `read_figure_model` independently. This makes it possible, within a single agent loop, to split execution, thinking, compression, and multimodal/image understanding across different models, giving the application layer the finest-grained cost control. You can also configure model-level `tool_choice` options in `llm_config.example.yaml`. See the default `OpenCowork` Level 3 `alpha_agent` definition for a concrete example.\n\n- [2026/03/08] **Desktop branch sync update:** The current desktop branch now includes packaged Python backend build scripts, the bundled `infiagent` Python SDK, configurable runtime cadence (`action_window_steps`, `thinking_interval`, scheduled/manual `fresh`), MCP runtime integration, per-task logs, desktop environment settings, and marketplace integration. The legacy standalone tool-server workflow has been replaced by in-process `direct-tools`, and the built-in research system is now named `Researcher`.\n\n  [Click here to download!](https://github.com/polyuiislab/infiAgent/releases/tag/v1.4.1).\n\n- [2026/02/09] **Mac desktop version released!** [Click here to download!](https://github.com/polyuiislab/infiAgent/releases/tag/v1.4.1). Support download skills from offical market. It supports any API that is allowed to be called by tools, and runs fully locally with the support of the localization model.\n  <img width=\"1198\" height=\"798\" alt=\"image\" src=\"https://github.com/user-attachments/assets/435c5bd9-ace1-46a8-9814-883d3ce507d4\" />\n\n\n- [2026/02/07] **Agent Skills Support!** InfiAgent now supports the [Agent Skills open standard](https://agentskills.io/). Skills are folders of instructions, scripts, and resources that agents can dynamically load to improve performance on specialized tasks. Docker users: place skill folders in `~/.mla_v3/skills_library/` (mounted to `/root/mla_v3/skills_library/` inside the container). Local developers: place them in `~/mla_v3/skills_library/`. Windows users: `%USERPROFILE%\\mla_v3\\skills_library\\`. The agent will automatically discover available skills and deploy them to the workspace on demand via `load_skill` tool.\n\n- [2026/02/07] **Multi-Provider Model Support!** You can now use models from different providers in the same configuration. Each model can optionally override `api_key` and `base_url` to use a different provider. Different sub-agents can use different models. See `llm_config.example.yaml` for configuration details.\n\n- [2026/02/07] **Web UI Enhancements:** Added Resume button for recovering interrupted tasks (same as CLI `/resume`). Added Agent System selector to freely switch between `Researcher` (academic research) and Open Cowork systems. User inputs now automatically include timestamps (consistent with CLI behavior).\n\n- [2026/02/07] **Multimodal Message Architecture:** Separated multimodal and text-only message logic. For multimodal models, images from `image_read` are embedded directly in the conversation context for native understanding. Text-only models retain the external vision tool approach. Configure via `multimodal` and `compressor_multimodal` in `llm_config.yaml`.\n\n- [2026/01/17] We introduce a new configuration profile, Open Cowork, which delivers a computer-work assistant similar to Anthropic's Cowork. After entering a user-specified working directory, the assistant can perform a wide range of tasks, including but not limited to: organizing folders, creating PowerPoint presentations, processing and categorizing bills and invoices in multiple formats, conducting in-depth research, and writing project code. The system is built on the InfiAgent architecture, preserving its long-horizon execution capabilities and unbounded, file-system–level memory within the same workspace. Open Cowork supports CLI, Docker-based CLI, and Web UI modes. In Web UI, use the Agent System selector to switch between `Researcher` and OpenCowork. A demonstration video is available for more details.\n\n**Open Cowork Demo Videos:**\n\n\n  [![Desktop Organization & File Management](https://img.youtube.com/vi/IuTVRPIIW-s/hqdefault.jpg)](https://www.youtube.com/watch?v=IuTVRPIIW-s)\n\n\n  [![PowerPoint Creation](https://img.youtube.com/vi/uuxAvCLIX9M/hqdefault.jpg)](https://www.youtube.com/watch?v=uuxAvCLIX9M)\n\n\n\n\n- [2026/01/13] Supports breakpoint recovery for program errors (the original Ctrl+C resume function is retained). Please access the resume function using your CLI version and type /resume.\n\n- [2026/01/08] Our Paper \"[InfiAgent: An Infinite-Horizon Framework for General-Purpose Autonomous Agents](https://arxiv.org/abs/2601.03204)\" released\n\n- [2026/01/07] Web UI: This is a temporary fix for the \"处理事件异常: 'int' object has no attribute 'get'\". It will not affect subsequent agent output or operation, but the error will still be displayed. A full fix is ​​pending.\n\n- [2026/01/06] Web UI: add an entry-agent selector next to Task ID so you can choose the root agent for the conversation, with an agent list and a visual agent tree for the selected root.\n\n- [2026/01/05] Resolves global freeze caused by prolonged unresponsiveness of the primary token. Please update code or pull latest docker image!\n\n- [2026/01/04] Support different Language of Agent output base on user input.\n\n- [2026/01/03] Optimize LiteLLM’s native retry mechanism by enhancing error-aware retry prompts to improve small-model call success rates; add connection timeout detection to reduce task interruption risks.\n\n- [2026/01/02] Install and how use vedio please click <a href=\"https://www.bilibili.com/video/BV142vQB2EDu/?share_source=copy_web&vd_source=8f099df5d40b73e936381e57d7fc05aa\n\">infiagent:全自动写作工具</a>\n\n- [2026/01/02] fix some bugs about reference manage, Please clone latest repo or pull latest docker image: chenglinhku/mlav3.\n\n- [2026/01/01] support web_ui and qwen api. Also fix some problem when using third part oepnai format api. please using latest chenglinhku/mlav3 docker image and see the example configs.\n\n- [2025/12/31] support gemini api key from google ai studio now. Please See the gemini config in dir. \n\n\nAttention: Current coding task only support python project. Other language may supported later. In old version execute_command only support safe command like cd or grep，now it include every commands including rm. Please try to use it in docker mode if your task may edit system file.\n\n## 🎬 Outputs\n\ncomplete academic papers generated by MLA:\n\n**Demo 1:**\n\n<p align=\"center\">\n  Demo animation removed from git to keep the repository lightweight.\n</p>\n\n**Demo 2:**\n\n<p align=\"center\">\n  <img src=\"assets/paper1.png\" alt=\"Paper Generation Demo 2\" width=\"800\">\n</p>\n\n**Demo 3:**\n\n<p align=\"center\">\n  <img src=\"assets/paper2.png\" alt=\"Paper Generation Demo 3\" width=\"800\">\n</p>\n\nMLA handles the entire research workflow - from literature search and experiment design to code execution, figure generation, and LaTeX paper writing. All automatically orchestrated through multi-level agents.\nLarge demo videos and GIFs are now distributed outside git history so clones stay smaller and faster.\n\n---\n\n## 📚 Table of Contents\n\n- [See It In Action](#-see-it-in-action)\n- [Quick Start](#-quick-start)\n- [How It Works](#-how-it-works)\n- [Interface Screenshots](#-interface-screenshots)\n- [Configuration Guide](#-configuration-guide)\n- [CLI Interface](#-cli-interface)\n- [SDK Integration](#-sdk-integration)\n- [Example Outputs](#-example-outputs)\n\n---\n\n## 🚀 Quick Start\n\n### Vedio of Docker Mode:\n\n<a href=\"https://www.bilibili.com/video/BV142vQB2EDu/?share_source=copy_web&vd_source=8f099df5d40b73e936381e57d7fc05aa\n\">infiagent:全自动写作工具</a>\n\n### Option 1: Docker (Recommended - No Python Required)\n\n**1. Install Docker**\n- Mac/Windows: [Docker Desktop](https://www.docker.com/products/docker-desktop)\n- Linux: `curl -fsSL https://get.docker.com | sh`\n\n**2. Pull Image**\n\n```bash\ndocker pull chenglinhku/mlav3:latest\n```\n\n**3. Choose Your Mode**\n\n### Option A: Web UI Mode (Recommended)\n\nThe current Docker image starts the SDK-based Web UI directly. Use the Agent System selector to switch between `Researcher` and `OpenCowork`. The old standalone config page on `9641` is no longer required.\n\n```bash\ncd /your/workspace\nmkdir -p ~/.mla_v3\n\ndocker run -d --name mla-webui \\\n  -e HOST_PWD=$(pwd) \\\n  -e PORT=4242 \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui\n```\n\nThen open browser: `http://localhost:4242`\n\n- On a fresh volume, the bootstrap admin account is `admin` / `admin123`\n- You can also create a new user directly from the login page\n- Click the `Config` button inside Web UI to edit `llm_config.yaml`, `app_config.json`, and agent configuration files\n- View logs with `docker logs -f mla-webui`\n\nIf you want Docker runtime data to stay inside the project instead of `~/.mla_v3`, replace the runtime mount with:\n\n```bash\nmkdir -p .mla_v3_docker\n# replace: -v ~/.mla_v3:/root/mla_v3\n# with:    -v $(pwd)/.mla_v3_docker:/root/mla_v3\n```\n\n<p align=\"center\">\n  <img src=\"assets/web_ui.png\" alt=\"Paper Generation Demo 2\" width=\"800\">\n</p>\n\n📖 **Web UI usage & UI details**: see [web_ui/README.md](web_ui/README.md).\n\n### Option B: CLI Mode\n\n```bash\ncd /your/workspace\nmkdir -p ~/.mla_v3\n\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  chenglinhku/mlav3:latest cli\n```\n\n**Windows Users:**\n\nWindows users can mount any working folder into `/workspace/<your_task_root>` and reuse the same `/root/mla_v3` runtime volume across runs.\n\n```powershell\n# CLI Mode (PowerShell)\ndocker run -it --rm `\n  -e HOST_PWD=\"/docker_web\" `\n  -v \"${PWD}:/workspace/docker_web\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  chenglinhku/mlav3:latest cli\n\n# Web UI Mode (PowerShell)\ndocker run -d --name mla-webui `\n  -e HOST_PWD=\"/docker_web\" `\n  -e PORT=4242 `\n  -v \"${PWD}:/workspace/docker_web\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  -p 4242:4242 `\n  chenglinhku/mlav3:latest webui\n\n# Then open browser: http://localhost:4242\n# View logs: docker logs -f mla-webui\n```\n\n**4. Configure API Key**\n\nOpen browser: `http://localhost:4242`\n\n<p align=\"center\">\n  <img src=\"assets/config_web_screen_shot.png\" alt=\"Configuration Web Interface\" width=\"800\">\n</p>\n\nSign in, open the `Config` dialog, edit `llm_config.yaml`, fill in your API key, and save.\n\n**🎉 Done!** Start using MLA CLI.\n\n📖 **[Complete Docker Guide](docs/DOCKER_GUIDE.md)**\n\n---\n\n### Option 2: Local Installation (Python Required)\n\n**1. Install the package**\n\n```bash\n# Python 3.9+ is supported. Use Python 3.10+ if you need MCP support through the packaged dependency set.\ncd install_path\npython -m venv venv\nsource venv/bin/activate  # Windows: venv\\Scripts\\activate\ngit clone https://github.com/ChenglinPoly/infiAgent.git\ncd infiAgent\npip install -e .\n```\n\n**2. Install Playwright**\n\n```bash\nplaywright install chromium\n```\n\n**3. Configure API Key**\n\n```bash\nmla-agent --config-set api_key \"your-api-key\"\n```\n\n**4. Start CLI**\n\n```bash\ncd /your/workspace\nmla-agent --cli\n```\n\n📖 **[Complete CLI Guide](docs/CLI_GUIDE.md)**\n\n---\n\n## 🎯 How It Works\n\nMLA's design philosophy is **\"Provide short but high-value context for the next step.\"** To achieve this, the framework implements multiple innovations:\n\n### 1. 🌲 Serial Multi-Agent System\n\nMLA deploys agents in a **tree-structured hierarchy** (e.g., Grandparent → Parent → Child). This ensures:\n\n- ✅ **Single-purpose agents**: Each agent has a focused role\n- ✅ **Minimal tool sets**: Agents only access necessary tools\n- ✅ **Task alignment**: Serial execution prevents parallel conflicts\n- ✅ **Clear delegation**: Parent agents orchestrate child agents\n\n**Example Hierarchy:**\n```\nalpha_agent (Level 3)\n  ├── data_collection_agent (Level 2)\n  │   └── web_search_agent (Level 1)\n  ├── coder_agent (Level 2)\n  └── material_to_document_agent (Level 2)\n```\n\n### 2. 🎯 Nested Attention Mechanism\n\nLong documents (PDFs, novels, papers) are **never directly loaded into context**. Instead:\n\n- ✅ Use `answer_from_pdf`, `answer_from_document` tools\n- ✅ Query-driven content extraction\n- ✅ Only relevant excerpts or summaries enter context\n- ✅ **Application-layer attention allocation** through tools\n\n**Traditional Approach:**\n```\nLoad entire 50-page PDF → Agent processes everything → Token overflow\n```\n\n**MLA Approach:**\n```\nAgent asks: \"What is the methodology?\"\n→ Tool extracts relevant sections (2 pages)\n→ Returns concise answer → Minimal token usage\n```\n\n### 3. 📁 File-Centric Architecture\n\n**\"Files are everything.\"** All outputs and interactions are saved to the file system:\n\n- ✅ Web scraping → Saves as Markdown files\n- ✅ PDF parsing → Extracts to structured documents\n- ✅ Sub-agent results → Stored as files\n- ✅ **No immediate returns** cluttering context\n\n**Benefits:**\n- Clear audit trail\n- Reusable artifacts\n- Context-free state representation\n\n### 4. ⚡ Ten-Step Strategy (No Context Compression)\n\nA key insight: **The current file system state represents the effect of all historical actions.**\n\n- ✅ A separate **thinking module** updates file space state every 30 steps\n- ✅ Agents only retain **the last 10 actions** (since last state update)\n- ✅ **No need for context compression**\n- ✅ Historical actions are reflected in file system, not conversation history\n\n**Traditional LLM Agents:**\n```\nStep 1: Create file A\nStep 2: Edit file B\n...\nStep 100: Context overflow → Compression needed → Information loss\n```\n\n**MLA Approach:**\n```\nSteps 1-10: Actions recorded\nStep 10: Thinking module updates \"Current State: Files A, B, C exist with...\"\nSteps 11-20: Only these + Current State kept\n→ No compression, no information loss\n```\n\n### 5. 🔧 Batch File Operations\n\nInspired by [Claude Code](https://www.anthropic.com/), MLA uses **list-based tool parameters** to save tokens:\n\n- ✅ Read multiple files in one call\n- ✅ Batch operations reduce cumulative overhead\n- ✅ Significant token savings on repeated actions\n\n**Example:**\n```python\n# Traditional: 3 separate calls\nfile_read(path=\"file1.txt\")\nfile_read(path=\"file2.txt\")\nfile_read(path=\"file3.txt\")\n\n# MLA: 1 batch call\nfile_read(paths=[\"file1.txt\", \"file2.txt\", \"file3.txt\"])\n```\n\n### 6. 💾 Long-Term Memory with Task ID\n\n- ✅ **Task ID = Workspace absolute path** (not user-configurable)\n- ✅ Same task ID allows **unlimited conversation sessions**\n- ✅ Agents remember all historical tasks in the workspace\n- ✅ Persistent memory across interruptions and restarts\n\n**Usage:**\n```bash\n# First session\nmla-agent --task_id ~/research --user_input \"Collect papers on Transformers\"\n# → Stores conversation in ~/mla_v3/conversations/{hash}_research_*\n\n# Second session (days later)\nmla-agent --task_id ~/research --user_input \"Summarize the collected papers\"\n# → Agent remembers previous session and accesses collected files\n```\n\n### 7. 📊 Call Graph-Based Shared Context\n\nThe `hierarchy_manager` maintains a **dynamic call relationship graph**:\n\n- ✅ Tracks parent-child agent relationships\n- ✅ Injects call graph into shared context\n- ✅ Prevents agents from overstepping boundaries\n- ✅ Maintains task alignment across multi-agent system\n\n**Call Graph Example:**\n```json\n{\n  \"current_agent\": \"coder_agent\",\n  \"parent\": \"alpha_agent\",\n  \"siblings\": [\"data_collection_agent\", \"material_to_document_agent\"],\n  \"allowed_tools\": [\"python_run\", \"file_write\", \"file_read\"]\n}\n```\n\nThis ensures `coder_agent` won't accidentally call `web_search` (not in its scope) or interfere with sibling agents.\n\n---\n\n\n## 📸 Interface Screenshots\n\n### CLI Interface\n\nMLA provides a rich interactive CLI with real-time task monitoring, HIL handling, and agent switching:\n\n**System Selection:**\n<p align=\"center\">\n  <img src=\"assets/cli_choose_system.png\" alt=\"CLI System Selection\" width=\"800\">\n</p>\n\n**Tool Mode Configuration:**\n<p align=\"center\">\n  <img src=\"assets/cli_choose_tool_mode.png\" alt=\"CLI Tool Mode\" width=\"800\">\n</p>\n\n**Starting Tasks:**\n<p align=\"center\">\n  <img src=\"assets/cli_start_task.png\" alt=\"CLI Task Execution\" width=\"800\">\n</p>\n\n*Interactive CLI with prompt_toolkit and rich terminal UI - featuring multi-turn conversations, automatic HIL detection, and tool execution confirmation.*\n\n### VS Code Plugin\n\nBuild powerful IDE extensions using MLA's JSONL mode:\n\n<p align=\"center\">\n  <img src=\"assets/vscode_plugin.png\" alt=\"VS Code Plugin Screenshot\" width=\"800\">\n</p>\n\n*VS Code extension powered by MLA - seamless integration with workspace context and real-time streaming output.*\n\n---\n\n## ⚙️ Configuration Guide\n\nMLA uses YAML files for agent and tool configuration. Configuration files are located in:\n\n```\nconfig/\n├── agent_library/\n│   ├── Researcher/                 # Research-oriented multi-level system\n│   │   ├── general_prompts.yaml    # Shared prompts\n│   │   ├── level_-1_judge_agent.yaml  # Judge agent\n│   │   ├── level_0_tools.yaml      # Tool definitions\n│   │   ├── level_1_agents.yaml     # Low-level agents\n│   │   ├── level_2_agents.yaml     # Mid-level agents\n│   │   └── level_3_agents.yaml     # Top-level agents\n│   └── OpenCowork/                 # General computer-work assistant\n└── run_env_config/\n    ├── llm_config.yaml             # LLM settings\n    └── llm_config.example.yaml     # Example template\n```\n\n### Key Configuration Files\n\n#### 1. `llm_config.yaml` - LLM Configuration\n\n```yaml\n# Global defaults\napi_key: \"your-api-key\"\nbase_url: \"https://openrouter.ai/api/v1\"\ntemperature: 0\nmax_tokens: 0\n\nmodels:\n  - openai/google/gemini-3-flash-preview     # uses global api_key + base_url\n  - name: openai/qwen-plus                    # override with different provider\n    api_key: \"your-dashscope-key\"\n    base_url: \"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n\nfigure_models:\n  - openai/google/gemini-3-flash-preview\ncompressor_models:\n  - openai/google/gemini-3-flash-preview\nthinking_models:\n  - openai/google/gemini-3-flash-preview\nread_figure_models:\n  - openai/google/gemini-3-flash-preview\n\n# Multimodal configuration\nmultimodal: true              # Enable image embedding in messages for main model\ncompressor_multimodal: true   # Enable image embedding for compressor model\n```\n\n**Note**: Copy `llm_config.example.yaml` to `llm_config.yaml` to get started. Each model can optionally override `api_key` and `base_url` to use a different provider.\n\n#### 2. Agent Hierarchy\n\nMLA organizes agents into levels:\n\n- **Level 3**: Top-level orchestrators (e.g., `alpha_agent`)\n- **Level 2**: Functional specialists (e.g., `data_collection_agent`, `coder_agent`)\n- **Level 1**: Basic executors (e.g., `web_search_agent`)\n- **Level 0**: Tool definitions\n- **Level -1**: Quality control (e.g., `judge_agent`)\n\n#### 3. Creating Custom Agents\n\nEdit YAML files to customize agent behavior:\n\n```yaml\nnews_agent:\n  type: llm_call_agent\n  level: 1\n  model_type: \"advanced\"\n  available_tools:\n    - data_collection_agent\n    - coder_agent\n    ...\n  system_prompt: |\n    You are a newspaper agent.\n```\n\n---\n\n## 💻 CLI Interface\n\n### Interactive Mode\n\nStart the CLI for a conversational experience:\n\n```bash\nmla-agent --cli\n```\n\n**Key Features:**\n\n- 🔄 **Multi-turn conversations** with persistent context\n- 🤖 **Agent switching** with `@agent_name` syntax\n- 🔔 **Automatic HIL detection** with audio alerts\n- ⚠️ **Tool execution confirmation** in manual mode\n- ⏸️ **Interrupt and resume** support (Ctrl+C to pause)\n- 🎨 **Rich terminal UI** powered by `prompt_toolkit` and `rich`\n\n**Usage Examples:**\n\n```bash\n# Direct task input (uses default agent)\n[alpha_agent] > Collect papers on Transformers\n\n# Switch agent and execute task\n[alpha_agent] > @data_collection_agent Search for recent NLP papers\n\n# Switch default agent only\n[alpha_agent] > @coder_agent\n✅ Switched to: coder_agent\n[coder_agent] > \n```\n\n**CLI Commands:**\n\n| Command | Description |\n|---------|-------------|\n| `/help` | Show help and available commands |\n| `/agents` | List all available agents |\n| `/resume` | Resume interrupted tasks |\n| `/quit` or `/exit` | Exit CLI mode |\n| `Ctrl+C` | Interrupt current task (stays in CLI) |\n| `Ctrl+D` | Exit CLI immediately |\n\n**Human-in-Loop (HIL) Handling:**\n\nWhen an agent requests human input, the CLI automatically detects it:\n\n```\n🔔🔔🔔 Detected HIL task! Press Enter to handle... 🔔🔔🔔\n================================================================================\n🔔 Human Interaction Task (HIL)\n================================================================================\n📝 Task ID: upload_file_20250124\n📋 Instruction: Please upload the required dataset files...\n================================================================================\n💡 Enter your response (any text)\n   Type /skip to skip this task\n================================================================================\n\n[alpha_agent] HIL Response > Files uploaded successfully\n✅ HIL task responded\n```\n\n**Tool Confirmation (Manual Mode):**\n\nWhen `--auto-mode false` is set, each tool execution requires confirmation:\n\n```\n⚠️⚠️⚠️ Detected tool execution request! Press Enter to confirm... ⚠️⚠️⚠️\n================================================================================\n⚠️  Tool Execution Confirmation Request\n================================================================================\n🔧 Tool Name: python_run\n📝 Confirmation ID: confirm_12345\n📋 Parameters:\n     code: import numpy as np...\n     timeout: 300\n================================================================================\n💡 Choose action:\n   yes / y - Approve execution\n   no / n  - Reject execution\n================================================================================\n\n[alpha_agent] Confirm [yes/no] > yes\n✅ Approved tool execution: python_run\n```\n\n**Screenshot:** *(User will provide)*\n\n---\n\n### Command-Line Mode\n\nFor scripting and automation:\n\n```bash\nmla-agent \\\n  --task_id /path/to/workspace \\\n  --user_input \"Your task description\" \\\n  --agent_name alpha_agent\n```\n\n**Common Parameters:**\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `--task_id` | Workspace path (absolute) | Required |\n| `--user_input` | Task description | Required |\n| `--agent_name` | Agent to invoke | `alpha_agent` |\n| `--agent_system` | Agent library name | `Researcher` |\n| `--cli` | Interactive CLI mode | `false` |\n| `--jsonl` | JSONL output mode | `false` |\n| `--force-new` | Clear all state and start fresh | `false` |\n| `--auto-mode` | Tool execution mode (`true`/`false`) | Auto-detect |\n\n**Auto-Mode Examples:**\n\n```bash\n# Automatic tool execution (no confirmation needed)\nmla-agent --task_id ~/project --user_input \"Task\" --auto-mode true\n\n# Manual confirmation for each tool\nmla-agent --task_id ~/project --user_input \"Task\" --auto-mode false\n```\n\n---\n\n### Runtime Tool Execution\n\n```bash\n# Tools are executed in-process through direct-tools.\n# No standalone mla-tool-server process is required.\n```\n\n---\n\n## 🔌 SDK Integration\n\nMLA provides two SDK options: **Python SDK** for direct integration and **JSONL mode** for IDE plugins.\n\n---\n\n### Python SDK\n\nUse the bundled `infiagent` SDK. The current SDK model is:\n\n- instantiate `infiagent(...)` once to describe runtime defaults\n- pass a concrete `task_id` to `run(...)` and other task APIs\n- optionally point the whole runtime at a dedicated `user_data_root`\n\nMinimal example:\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent(\n    user_data_root=\"/abs/path/to/my_root\",\n    default_agent_system=\"Researcher\",\n    default_agent_name=\"alpha_agent\",\n    action_window_steps=30,\n    thinking_interval=30,\n    max_turns=100000,\n    fresh_enabled=True,\n    fresh_interval_sec=300,\n)\n\nresult = agent.run(\n    \"Write a survey paper on Transformers\",\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n)\n\nprint(f\"Status: {result['status']}\")\nprint(f\"Output: {result['output']}\")\n```\n\nIf your `user_data_root` already contains:\n\n- `config/llm_config.yaml`\n- `config/app_config.json`\n- `agent_library/...`\n- `tools_library/...`\n\nyou usually do not need to pass `llm_config_path`, `agent_library_dir`, or `tools_dir` again.\n\nCommon task APIs:\n\n```python\n# Ask a running or stopped task to refresh runtime config.\nagent.fresh(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    reason=\"reload runtime config\",\n)\n\n# Append a new instruction to the same task.\nagent.add_message(\n    \"Keep the existing outline and only revise section 3.\",\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    source=\"user\",\n    resume_if_needed=True,\n)\n\n# Launch a separate background task in another Python process.\nagent.start_background_task(\n    task_id=\"/abs/path/to/tasks/subtask_eval\",\n    user_input=\"Run the evaluation pipeline and summarize results\",\n    force_new=True,\n)\n\n# Inspect task state for dashboards or lightweight watchdogs.\nsnapshot = agent.task_snapshot(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n)\n\n# Reset a broken task loop while optionally preserving history.\nagent.reset_task(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    reason=\"clear broken loop\",\n    preserve_history=True,\n)\n```\n\nRuntime introspection:\n\n```python\nruntime = agent.describe_runtime()\nprint(runtime[\"user_data_root\"])\nprint(runtime[\"agent_library_dir\"])\nprint(runtime[\"tools_dir\"])\n\nsystems = agent.list_agent_systems()\nprint(systems[\"systems\"])\n```\n\nAdvanced runtime features supported by the SDK:\n\n- task-scoped background execution and resume/fresh control\n- `user_data_root`-scoped conversations, logs, runtime state, and config\n- tool hooks before/after tool execution\n- context hooks that can inspect or rewrite the final prompt before the LLM call\n- per-instance MCP server injection through `mcp_servers=[...]`\n\nSee the full guide: [docs/SDK_GUIDE.md](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/docs/SDK_GUIDE.md)\n\n**Use Cases for Python SDK:**\n- 🔧 Building custom workflows\n- 🤖 Embedding agents in existing applications\n- 📊 Batch processing multiple tasks\n- 🧭 Building external dashboards, watchdogs, and orchestration layers\n- 🔬 Research experiments with programmatic control\n\n---\n\n### JSONL Mode for IDE Plugins\n\nMLA provides a JSONL streaming mode for real-time integration with IDEs and editors:\n\n```bash\nmla-agent \\\n  --task_id $(pwd) \\\n  --user_input \"Optimize code performance\" \\\n  --jsonl 2>/dev/null\n```\n\n**Output Format:**\n\n```jsonl\n{\"type\":\"start\",\"call_id\":\"c-1760936557-474c43\",\"project\":\"~/project\",\"agent\":\"alpha_agent\",\"task\":\"Optimize...\"}\n{\"type\":\"token\",\"text\":\"[alpha_agent] Analyzing code...\"}\n{\"type\":\"progress\",\"phase\":\"execution\",\"pct\":30}\n{\"type\":\"token\",\"text\":\"Calling tool: code_analyzer\"}\n{\"type\":\"result\",\"ok\":true,\"summary\":\"Optimization complete\"}\n{\"type\":\"end\",\"status\":\"ok\",\"duration_ms\":5432}\n```\n\n**Event Types:**\n\n| Event Type | Description | Key Fields |\n|------------|-------------|------------|\n| `start` | Task begins | `call_id`, `agent`, `task` |\n| `token` | Streaming text output | `text` |\n| `progress` | Progress update | `phase`, `pct` |\n| `result` | Task result | `ok`, `summary` |\n| `end` | Task completed | `status`, `duration_ms` |\n| `error` | Error occurred | `message` |\n\n---\n\n### TypeScript/JavaScript Integration\n\n```typescript\nimport { spawn } from 'child_process';\n\ninterface AgentEvent {\n  type: 'start' | 'token' | 'progress' | 'result' | 'end' | 'error';\n  [key: string]: any;\n}\n\nfunction runAgent(\n  workspacePath: string,\n  userInput: string,\n  onEvent: (event: AgentEvent) => void\n): Promise<AgentEvent> {\n  return new Promise((resolve, reject) => {\n  const child = spawn('mla-agent', [\n    '--task_id', workspacePath,\n    '--user_input', userInput,\n    '--jsonl'\n  ]);\n  \n    let buffer = '';\n    \n  child.stdout.on('data', (data) => {\n      buffer += data.toString();\n      const lines = buffer.split('\\n');\n      buffer = lines.pop() || '';\n      \n      lines.forEach(line => {\n      if (!line.trim()) return;\n      \n        try {\n          const event: AgentEvent = JSON.parse(line);\n          onEvent(event);\n          \n          if (event.type === 'end') {\n            resolve(event);\n          } else if (event.type === 'error') {\n            reject(new Error(event.message));\n          }\n        } catch (e) {\n          console.error('Failed to parse event:', line);\n    }\n  });\n});\n\n    child.stderr.on('data', (data) => {\n      // Log errors to stderr\n      console.error(data.toString());\n    });\n    \n    child.on('error', reject);\n  });\n}\n\n// Usage\nawait runAgent('/path/to/workspace', 'Write unit tests', (event) => {\n      switch (event.type) {\n        case 'start':\n      console.log(`Task started: ${event.task}`);\n          break;\n        case 'token':\n      process.stdout.write(event.text);\n      break;\n    case 'progress':\n      updateProgressBar(event.pct);\n          break;\n        case 'result':\n      console.log(`\\nResult: ${event.summary}`);\n          break;\n      }\n    });\n```\n\n---\n\n### VS Code Extension Example\n\nBuild your own Cursor/VS Code extension using MLA:\n\n**Extension Features:**\n- 🤖 Agent commands in command palette\n- 💬 Inline chat with workspace context\n- 📝 Automatic code generation and refactoring\n- 🔍 Literature search within editor\n- 🔔 HIL task handling with UI prompts\n\n**Basic Extension Structure:**\n\n```typescript\n// extension.ts\nimport * as vscode from 'vscode';\nimport { runAgent } from './mla-client';\n\nexport function activate(context: vscode.ExtensionContext) {\n  let disposable = vscode.commands.registerCommand(\n    'mla.executeTask', \n    async () => {\n      const workspace = vscode.workspace.workspaceFolders?.[0].uri.fsPath;\n      const input = await vscode.window.showInputBox({\n        prompt: 'Enter task description'\n      });\n      \n      if (!workspace || !input) return;\n      \n      // Show progress\n      await vscode.window.withProgress({\n        location: vscode.ProgressLocation.Notification,\n        title: 'MLA Agent',\n        cancellable: true\n      }, async (progress, token) => {\n        \n        await runAgent(workspace, input, (event) => {\n          if (event.type === 'token') {\n            vscode.window.showInformationMessage(event.text);\n          } else if (event.type === 'progress') {\n            progress.report({ increment: event.pct });\n          }\n        });\n      });\n    }\n  );\n  \n  context.subscriptions.push(disposable);\n}\n```\n\n**Screenshot:** *(User will provide)*\n\n---\n\n## 📊 Example Outputs\n\n### Academic Paper Output\n\nMLA can generate complete research papers with the following structure:\n\n```\nupload/\n├── paper.tex               # Main LaTeX document\n├── references.bib          # Bibliography\n├── figures/\n│   ├── architecture.png\n│   ├── results_comparison.png\n│   └── ablation_study.png\n└── supplementary/\n    └── detailed_results.pdf\n```\n\n**Quality Metrics:**\n- ✅ Passes peer review at EI/IEEE conferences\n- ✅ Proper citation formatting\n- ✅ High-quality figures (300 DPI)\n- ✅ Coherent structure and flow\n\n### Other Capabilities\n\n**1. Scientific Computing**\n- ECM protein composition simulation\n- Logistics company shift scheduling\n- Student assignment grading with feedback\n\n**2. General Tasks**\n- Web scraping and data extraction\n- Code generation and debugging\n- Document conversion and processing\n\n---\n\n\n## 📖 Documentation\n\n- Runtime tools are executed in-process via direct-tools; no standalone tool server is required.\n- [Human-in-the-Loop API](tool_server_lite/HIL_API.md) - User interaction integration\n- [Configuration Examples](config/agent_library/Researcher/) - Agent YAML templates\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit issues or pull requests.\n\n---\n\n## 📄 License\n\n see [LICENSE](LICENSE) for details.\n\n---\n\n## 📄 Citation\n\nIf you use InfiAgent in your research, please cite our paper:\n\n```bibtex\n@article{yu2026infiagent,\n  title={InfiAgent: An Infinite-Horizon Framework for General-Purpose Autonomous Agents},\n  author={Yu, Chenglin and Wang, Yuchen and Wang, Songmiao and Yang, Hongxia and Li, Ming},\n  journal={arXiv preprint arXiv:2601.03204},\n  year={2026}\n}\n```\n\n---\n\n## 🙏 Acknowledgments\n\n- Built with [LiteLLM](https://github.com/BerriAI/litellm) for unified LLM access\n- Uses [Crawl4AI](https://github.com/unclecode/crawl4ai) for web scraping\n\n---\n\n## 📬 Contact\n\n**Author**: @yuchenglin\n\n**Thanks to Contributors**： @wangyuchen @wangsongmiao @yuyang @lijinjia\n\n**Email**: yuchenglin96@qq.com/cl0415@connect.hku.hk/chenglin.yu@poly.edu.h \n\n**GitHub**: [MLA V3 Repository](https://github.com/ChenglinPoly/infiAgent)\n\n---\n"
  },
  {
    "path": "README_CN.md",
    "content": "\n\n<div align=\"center\">\n  <img src=\"assets/logo.png\" alt=\"infiAgent Logo\" width=\"200\">\n\n  <h1>MLA V3 - 打造专属领域的 SOTA 级智能体</h1>\n\n  <p>\n    <img src=\"https://img.shields.io/badge/version-3.2.1-blue.svg\" alt=\"Version\">\n    <img src=\"https://img.shields.io/badge/python-3.9+-green.svg\" alt=\"Python\">\n    <img src=\"https://img.shields.io/badge/license-GPL-blue.svg\" alt=\"License: GPL\">\n  </p>\n\n  <p>\n    <a href=\"README.md\">English</a> | <a href=\"README_CN.md\">简体中文</a>\n  </p>\n</div>\n\n---\n\n## 🌟 简介\n\n**infiAgent 也称为 MLA (Multi-Level Agent，多层级智能体)** 是一个专为**无限时长运行**设计的智能体框架，不会因为任务资源累积和对话历史增长而导致工具调用混乱或系统崩溃。使用 MLA，你只需编写配置文件即可构建强大的通用或半专业化智能体。\n\n### 核心特性\n\n- ✅ **支持数以天计的持续复杂任务**：无需担心上下文累积或持续压缩导致的性能下降。任何中断（崩溃、网络异常、手动停止）都可通过 Resume 完全恢复，实现真正的断点续跑。\n- ✅ **支持 Agent Skills 标准**：兼容 [Agent Skills 开放标准](https://agentskills.io/)。将 skill 文件夹放入技能库，智能体即可自动发现、加载并按需执行。\n- ✅ **灵活的智能体架构**：同时支持**多层级架构**（树形编排，适合垂类复杂任务——如 `Researcher` 配置可长时间进行科学研究并生成论文）和**扁平架构**（单层智能体 + Skills，适合广泛通用任务——如 OpenCowork 配置）。\n- ✅ **持续记忆**：基于文件目录位置的记忆系统。在同一工作目录下启动智能体，即可记忆该目录下所有历史任务的对话和产出，无需外部数据库。\n\n### 更新 & 新闻🔥\n\n如果你在最新更新日期前拉取镜像或者代码，请参考修复的问题，重新拉取镜像和代码。\n\n- [2026/03/31] **Thinking / ReAct 模式可切换，并引入历史任务数据库检索：** 运行时现在支持两种节奏。你既可以保留原来的 ThinkingAgent 式“先思考，再执行 N 步”的长程模式，也可以关闭 thinking，切换到显式 ReAct 模式，让反思文本直接进入消息历史。与此同时，历史任务会被索引进本地 SQLite 数据库，所有 agent 默认都会挂载 `task_history_search` 工具。SDK 还支持只把最近 N 条历史任务注入 prompt；如果这些最近历史不足以完成当前任务，agent 会被明确提示去历史任务数据库里检索旧任务。\n\n- [2026/03/30] **SDK / mac / Web UI 模型配置对小白更友好：** SDK 现在支持直接传结构化模型配置，不再要求每个集成都手写 `llm_config.yaml`。mac 客户端和 Docker Web UI 现在都提供了基于 source 的模型编辑器：先配置默认 `base_url` / `api_key`，再按共享模型或各功能分区添加多个模型条目；每个条目都可以继续复用默认 source，也可以切到自定义 URL / Key。Raw YAML / JSON 仍然保留给高级用户，但普通用户已经不需要再手动写前缀或 JSON 模型对象。\n\n- [2026/03/23] **Docker Web UI 现已支持多用户注册与用户管理：** 最新 `chenglinhku/mlav3:latest` 镜像会通过新的 `webui` 启动命令直接运行基于 SDK 的 Web UI，默认使用 `4242` 端口。用户可以在登录页自行注册，初始管理员账号可在 Web UI 内管理用户。请按 Quick Start 和 `docs/DOCKER_GUIDE.md` 中更新后的 Docker 命令启动：挂载 `~/.mla_v3` 到 `/root/mla_v3`，映射 `4242`，并使用 `chenglinhku/mlav3:latest webui`。旧版基于 `9641` 的独立配置页面流程已不再需要。\n\n- [2026/03/19] **基于 `infiagent` SDK 推出 CheapClaw：** CheapClaw 现在作为基于 SDK 的应用层发布，在保留 OpenCowork 大部分实用能力的基础上，支持自定义 bot、多 bot 协作、对接各种 IM 软件以及 Skills，同时完整继承 `infiagent` 的能力模型：单个 bot 背后可挂多智能体系统、支持低成本长程任务，并在单个 bot 内实现按 task 隔离上下文。同一个 bot 下，不同 task 的历史上下文彼此隔离，而同一个 task 会持续复用同一份长程上下文，而不是共享单一 bot session。[点击这里查看 CheapClaw](https://github.com/polyuiislab/CheapClaw)。\n\n- [2026/03/19] **子智能体模型配置更加细粒度：** 现在单个子智能体可以独立配置 `execution_model`、`thinking_model`、`compressor_model`、`image_generation_model` 和 `read_figure_model`，从而在单个 agent loop 中把执行、思考、压缩以及多模态/读图工作拆分给不同模型，在应用层层面上最细粒度地控制成本。与此同时，可以在 `llm_config.example.yaml` 中为每个模型配置 `tool_choice` 选项。可参考默认 `OpenCowork` 配置中 Level 3 的 `alpha_agent` 写法。\n\n- [2026/03/08] **桌面端分支同步更新：** 当前 `desktop-app` 分支已经加入打包 Python 后端构建脚本、内置 `infiagent` Python SDK、可配置运行时节奏（`action_window_steps`、`thinking_interval`、定时/手动 `fresh`）、MCP 运行时接入、单任务日志、桌面端环境设置和 marketplace 集成。旧的独立 `tool-server` 工作流已被进程内 `direct-tools` 替代，内置科研系统名称也统一为 `Researcher`。\n\n [点击此处跳转下载页面](https://github.com/polyuiislab/infiAgent/releases/tag/v1.4.1).\n\n- [2026/02/09] **mac系统桌面端发布！**  [点击此处跳转下载页面](https://github.com/polyuiislab/infiAgent/releases/tag/v1.4.1)。支持 skills的外部库导入，支持不同智能体共享记忆接力工作，支持本地模型完全本地化运行。\n\n<img width=\"1198\" height=\"798\" alt=\"image\" src=\"https://github.com/user-attachments/assets/bae36a54-7c70-4ba5-a2cf-3d53856ca461\" />\n\n- [2026/02/07] **支持 Agent Skills！** InfiAgent 现已支持 [Agent Skills 开放标准](https://agentskills.io/)。Skills 是包含指令、脚本和资源的文件夹，智能体可按需加载以增强专业任务能力。Docker 用户：将 skill 文件夹放入 `~/.mla_v3/skills_library/`（挂载到容器内 `/root/mla_v3/skills_library/`）。本地开发者：放入 `~/mla_v3/skills_library/`。Windows 用户：`%USERPROFILE%\\mla_v3\\skills_library\\`。智能体会自动发现可用 skills 并通过 `load_skill` 工具按需部署到工作空间。\n\n- [2026/02/07] **支持多供应商模型！** 同一配置文件中可以使用来自不同供应商的模型。每个模型可单独覆盖 `api_key` 和 `base_url`，允许不同子智能体使用不同模型。详见 `llm_config.example.yaml` 配置示例。\n\n- [2026/02/07] **Web UI 增强：** 新增 Resume 按钮，支持恢复中断任务（与 CLI `/resume` 功能一致）。新增 Agent System 选择器，可自由切换 `Researcher`（学术研究智能体）和 Open Cowork 系统。用户输入自动添加时间戳（与 CLI 行为一致）。\n\n- [2026/02/07] **多模态消息架构重构：** 分离多模态和纯文本模型的消息逻辑。多模态模型下，`image_read` 工具获取的图片直接嵌入对话上下文，实现原生图片理解。纯文本模型仍保留外部 Vision 工具的图片识别能力。通过 `llm_config.yaml` 中的 `multimodal` 和 `compressor_multimodal` 配置。\n\n- [2026/01/17] 我们推出新的配置文件open cowork，得到类似anthropic 公司 cowork 工具的电脑工作助手。在进入你指定的文件夹后，实现包括但不限于帮你整理文件夹，制作 ppt，整理各种格式的账单发票，深度调研，编写项目代码等。仍然基于 infiagent 架构的长程性能，和相同文件夹下的无限记忆。支持 CLI、Docker CLI 和 Web UI 模式。在 Web UI 中可通过 Agent System 选择器切换 `Researcher` 和 OpenCowork。具体可查看演示视频。\n\n**Open Cowork 演示视频：**\n\n  [![Desktop Organization & File Management](https://img.youtube.com/vi/IuTVRPIIW-s/hqdefault.jpg)](https://www.youtube.com/watch?v=IuTVRPIIW-s)\n\n\n  [![PowerPoint Creation](https://img.youtube.com/vi/uuxAvCLIX9M/hqdefault.jpg)](https://www.youtube.com/watch?v=uuxAvCLIX9M)\n\n\n- [2026/01/13] cli模式下新增api欠费网络中断等意外情况的断点续跑功能。（原先手动中断/续跑功能保留）。统一/resume唤起。\n\n- [2026/01/08] 我们的论文 \"[InfiAgent: An Infinite-Horizon Framework for General-Purpose Autonomous Agents](https://arxiv.org/abs/2601.03204)\" 发布\n\n- [2026/01/07] Web UI: 临时修复“处理事件异常: 'int' object has no attribute 'get'”。不会影响后续 agent输出和工作，但仍然会显示报错，等待后续完全修复。\n\n- [2026/01/06] Web UI：新增入口智能体选择功能，可在 Task ID 左侧选择作为对话入口的智能体，并在同一界面展示该智能体为根的 agent tree。\n\n- [2026/01/05] 解决网络死锁问题（首token 卡死） ！重要更新！建议更新最新镜像或者拉取代码！\n\n- [2026/01/04] 支持智能体基于用户回复输出不同交互语言，\n\n- [2026/01/03] 优化 litellm 原生重试机制，通过提醒调用错误增加小模型调用成功率；增加链接超时检测机制，减少任务中断可能性。\n\n- [2026/01/02] 上传了视频教程，点击：<a href=\"https://www.bilibili.com/video/BV142vQB2EDu/?share_source=copy_web&vd_source=8f099df5d40b73e936381e57d7fc05aa\n\">infiagent:全自动写作工具</a>\n\n- [2026/01/02] 修复了文献管理工具的部分 bug，请更新最新代码或者拉取最近镜像 chenglinhku/mlav3\n\n- [2026/01/01] 现已支持web ui多用户模式。拉取最新镜像网chenglinhku/mlav3进行体验，webui目前属测试阶段存在不稳定因素，最新镜像同时接收cli模式，详见quickstart教程\n\n- [2026/01/01] 现已支持阿里云api包括qwen，适配绝大部分第三方中转站。配置详情请卡config文件夹对应的参考文件。\n\n- [2025/12/31] 现在已支持 gemini api。重新拉取仓库或重新拉取 docker 即可生效。配置文件参考配置文件夹 gemini 开头的样板格式。\n\n注意目前只支持 python 编程，早期版本execute_command只支持只读命令，目前已经支持所有命令（包括删除等危险命令），推荐在 docker 环境下使用。\n\n---\n\n## 🎬 输出\n\nMLA完成的完整论文\n\n**Demo 1:**\n\n<p align=\"center\">\n  为了控制仓库体积，演示动图已不再放入 git 历史。\n</p>\n\n**Demo 2:**\n\n<p align=\"center\">\n  <img src=\"assets/paper1.png\" alt=\"Paper Generation Demo 2\" width=\"800\">\n</p>\n\n**Demo 3:**\n\n<p align=\"center\">\n  <img src=\"assets/paper2.png\" alt=\"Paper Generation Demo 3\" width=\"800\">\n</p>\n\nMLA 处理整个研究工作流程——从文献搜索和实验设计到代码执行、图表生成和 LaTeX 论文撰写。全部通过多层级智能体自动编排完成。\n演示视频和大体积 GIF 现已移出 git 历史，以便更轻量地克隆仓库。\n\n---\n\n## 📚 目录\n\n- [输出](#-输出)\n- [快速开始](#-快速开始)\n- [工作原理](#-工作原理)\n- [界面截图](#-界面截图)\n- [配置指南](#-配置指南)\n- [CLI 界面](#-cli-界面)\n- [SDK 集成](#-sdk-集成)\n- [示例输出](#-示例输出)\n\n---\n\n## 🚀 快速开始\n\n### dock版视频演示教程\n\n<a href=\"https://www.bilibili.com/video/BV142vQB2EDu/?share_source=copy_web&vd_source=8f099df5d40b73e936381e57d7fc05aa\n\">infiagent:全自动写作工具</a>\n\n### 方式 1: Docker（推荐 - 无需 Python）\n\n**1. 安装 Docker**\n- Mac/Windows: [Docker Desktop](https://www.docker.com/products/docker-desktop)\n- Linux: `curl -fsSL https://get.docker.com | sh`\n\n**2. 拉取镜像**\n\n```bash\ndocker pull chenglinhku/mlav3:latest\n```\n\n**3. 选择模式**\n\n### 方式 A: Web UI 模式（推荐）\n当前 Docker 镜像会直接启动基于 SDK 的 Web UI。可通过 Agent System 选择器切换 `Researcher` 和 `OpenCowork`。旧版 `9641` 独立配置页面已不再需要。\n\n```bash\ncd /你的工作空间\nmkdir -p ~/.mla_v3\n\ndocker run -d --name mla-webui \\\n  -e HOST_PWD=$(pwd) \\\n  -e PORT=4242 \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui\n```\n\n然后打开浏览器：`http://localhost:4242`\n\n- 首次使用空 volume 时，默认管理员账号为 `admin` / `admin123`\n- 也可以直接在登录页注册新用户\n- 登录后点击 Web UI 里的 `Config` 按钮即可编辑 `llm_config.yaml`、`app_config.json` 和 agent 配置\n- 查看日志：`docker logs -f mla-webui`\n\n如果你希望 Docker 运行数据放在当前项目目录，而不是 `~/.mla_v3`，可以把运行时挂载改成：\n\n```bash\nmkdir -p .mla_v3_docker\n# 把: -v ~/.mla_v3:/root/mla_v3\n# 改成: -v $(pwd)/.mla_v3_docker:/root/mla_v3\n```\n\n\n\n<p align=\"center\">\n  <img src=\"assets/web_ui.png\" alt=\"Paper Generation Demo 2\" width=\"800\">\n</p>\n📖 **Web UI 使用与界面说明**：详见 [web_ui/README.md](web_ui/README.md)。\n### 方式 B: CLI 模式\n\n```bash\ncd /你的工作空间\nmkdir -p ~/.mla_v3\n\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  chenglinhku/mlav3:latest cli\n```\n\n**Windows 用户：**\n\nWindows 用户可以把任意工作目录挂到 `/workspace/<你的任务根目录>`，并持续复用同一个 `/root/mla_v3` 运行时目录。\n如有 bug 欢迎提交 issue。\n\n```powershell\n# CLI 模式 (PowerShell)\ndocker run -it --rm `\n  -e HOST_PWD=\"/docker_web\" `\n  -v \"${PWD}:/workspace/docker_web\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  chenglinhku/mlav3:latest cli\n\n# Web UI 模式 (PowerShell)\ndocker run -d --name mla-webui `\n  -e HOST_PWD=\"/docker_web\" `\n  -e PORT=4242 `\n  -v \"${PWD}:/workspace/docker_web\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  -p 4242:4242 `\n  chenglinhku/mlav3:latest webui\n\n# 然后打开浏览器：http://localhost:4242\n# 查看日志：docker logs -f mla-webui\n```\n\n**4. 配置 API Key**\n\n打开浏览器：`http://localhost:4242`\n\n<p align=\"center\">\n  <img src=\"assets/config_web_screen_shot.png\" alt=\"配置管理界面\" width=\"800\">\n</p>\n\n登录后打开 `Config` 对话框，编辑 `llm_config.yaml`，填入 API key 并保存。\n\n**🎉 完成！** 开始使用 MLA CLI。\n\n📖 **[Docker 完整指南](docs/DOCKER_GUIDE.md)**\n\n---\n\n### 方式 2: 本地安装（需要 Python）\n\n**1. 安装包**\n\n```bash\n# 支持 Python 3.9+。如果需要使用打包依赖中的 MCP 能力，建议使用 Python 3.10+。\ncd 安装路径\npython -m venv venv\nsource venv/bin/activate  # Windows: venv\\Scripts\\activate\ngit clone https://github.com/ChenglinPoly/infiAgent.git\ncd infiAgent\npip install -e .\n```\n\n**2. 安装 Playwright**\n\n```bash\nplaywright install chromium\n```\n\n**3. 配置 API Key**\n\n```bash\nmla-agent --config-set api_key \"your-api-key\"\n```\n\n**4. 启动 CLI**\n\n```bash\ncd /你的工作空间\nmla-agent --cli\n```\n\n📖 **[CLI 完整指南](docs/CLI_GUIDE.md)**\n\n---\n\n## 🎯 工作原理\n\nMLA 的设计理念是**\"为下一步提供简短但高价值的上下文\"**。为实现这一理念，框架实现了多项创新：\n\n### 1. 🌲 串行多智能体系统\n\nMLA 在**树形层级结构**中部署智能体（例如，祖父 → 父亲 → 儿子）。这确保了：\n\n- ✅ **单一目的智能体**：每个智能体都有专注的角色\n- ✅ **最小工具集**：智能体仅访问必要的工具\n- ✅ **任务对齐**：串行执行防止并行冲突\n- ✅ **明确委派**：父智能体编排子智能体\n\n**示例层级：**\n```\nalpha_agent（Level 3）\n  ├── data_collection_agent（Level 2）\n  │   └── web_search_agent（Level 1）\n  ├── coder_agent（Level 2）\n  └── material_to_document_agent（Level 2）\n```\n\n### 2. 🎯 嵌套注意力机制\n\n长文档（PDF、小说、论文）**永远不会直接加载到上下文中**。相反：\n\n- ✅ 使用 `answer_from_pdf`、`answer_from_document` 工具\n- ✅ 查询驱动的内容提取\n- ✅ 仅相关摘录或摘要进入上下文\n- ✅ **应用层通过工具进行注意力分配**\n\n**传统方法：**\n```\n加载整个 50 页 PDF → 智能体处理所有内容 → Token 溢出\n```\n\n**MLA 方法：**\n```\n智能体问：\"方法是什么？\"\n→ 工具提取相关部分（2 页）\n→ 返回简洁答案 → 最小 token 使用\n```\n\n### 3. 📁 文件中心架构\n\n**\"文件即一切。\"** 所有输出和交互都保存到文件系统：\n\n- ✅ 网页抓取 → 保存为 Markdown 文件\n- ✅ PDF 解析 → 提取到结构化文档\n- ✅ 子智能体结果 → 存储为文件\n- ✅ **无即时返回**使上下文混乱\n\n**优势：**\n- 清晰的审计跟踪\n- 可重用的工件\n- 无上下文状态表示\n\n### 4. ⚡ 十步策略（无需上下文压缩）\n\n一个关键洞察：**当前文件系统状态代表了所有历史操作的效果。**\n\n- ✅ 一个独立的 **thinking 模块**每 30 步更新一次文件空间状态\n- ✅ 智能体仅保留**最近 10 个操作**（自上次状态更新以来）\n- ✅ **无需上下文压缩**\n- ✅ 历史操作反映在文件系统中，而非对话历史\n\n**传统 LLM 智能体：**\n```\n步骤 1：创建文件 A\n步骤 2：编辑文件 B\n...\n步骤 100：上下文溢出 → 需要压缩 → 信息丢失\n```\n\n**MLA 方法：**\n```\n步骤 1-10：记录操作\n步骤 10：Thinking 模块更新\"当前状态：文件 A、B、C 存在，包含...\"\n步骤 11-20：仅保留这些 + 当前状态\n→ 无压缩，无信息丢失\n```\n\n### 5. 🔧 批量文件操作\n\n受 [Claude Code](https://www.anthropic.com/) 启发，MLA 使用**基于列表的工具参数**来节省 token：\n\n- ✅ 一次调用读取多个文件\n- ✅ 批量操作减少累积 token 消耗\n- ✅ 重复操作显著节省 token\n\n**示例：**\n```python\n# 传统：3 次单独调用\nfile_read(path=\"file1.txt\")\nfile_read(path=\"file2.txt\")\nfile_read(path=\"file3.txt\")\n\n# MLA：1 次批量调用\nfile_read(paths=[\"file1.txt\", \"file2.txt\", \"file3.txt\"])\n```\n\n### 6. 💾 基于任务 ID 的长期记忆\n\n- ✅ **任务 ID = 工作空间绝对路径**（用户不可配置）\n- ✅ 同一任务 ID 下允许**无限对话会话**\n- ✅ 智能体具有工作空间中所有历史任务的记忆\n- ✅ 跨中断和重启的持久记忆\n\n**使用：**\n```bash\n# 第一次会话\nmla-agent --task_id ~/research --user_input \"收集有关 Transformer 的论文\"\n# → 将对话存储在 ~/mla_v3/conversations/{hash}_research_*\n\n# 第二次会话（几天后）\nmla-agent --task_id ~/research --user_input \"总结已收集的论文\"\n# → 智能体记住前一次会话并访问收集的文件\n```\n\n### 7. 📊 基于调用图的共享上下文\n\n`hierarchy_manager` 维护**动态调用关系图**：\n\n- ✅ 跟踪父子智能体关系\n- ✅ 将调用图注入共享上下文\n- ✅ 防止智能体越界\n- ✅ 在多智能体系统中保持任务对齐\n\n**调用图示例：**\n```json\n{\n  \"current_agent\": \"coder_agent\",\n  \"parent\": \"alpha_agent\",\n  \"siblings\": [\"data_collection_agent\", \"material_to_document_agent\"],\n  \"allowed_tools\": [\"python_run\", \"file_write\", \"file_read\"]\n}\n```\n\n这确保 `coder_agent` 不会意外调用 `web_search`（不在其范围内）或干扰兄弟智能体。\n\n---\n\n\n## 📸 界面截图\n\n### CLI 界面\n\nMLA 提供了功能丰富的交互式 CLI，支持实时任务监控、HIL 处理和智能体切换：\n\n**系统选择：**\n<p align=\"center\">\n  <img src=\"assets/cli_choose_system.png\" alt=\"CLI 系统选择\" width=\"800\">\n</p>\n\n**工具模式配置：**\n<p align=\"center\">\n  <img src=\"assets/cli_choose_tool_mode.png\" alt=\"CLI 工具模式\" width=\"800\">\n</p>\n\n**启动任务：**\n<p align=\"center\">\n  <img src=\"assets/cli_start_task.png\" alt=\"CLI 任务执行\" width=\"800\">\n</p>\n\n*基于 prompt_toolkit 和 rich 的交互式 CLI - 支持多轮对话、自动 HIL 检测和工具执行确认。*\n\n### VS Code 插件\n\n使用 MLA 的 JSONL 模式构建强大的 IDE 扩展：\n\n<p align=\"center\">\n  <img src=\"assets/vscode_plugin.png\" alt=\"VS Code 插件截图\" width=\"800\">\n</p>\n\n*由 MLA 驱动的 VS Code 扩展 - 与工作空间上下文无缝集成，支持实时流式输出。*\n\n---\n\n## ⚙️ 配置指南\n\nMLA 使用 YAML 文件进行智能体和工具配置。配置文件位于：\n\n```\nconfig/\n├── agent_library/\n│   ├── Researcher/                 # 面向科研的多层级系统\n│   │   ├── general_prompts.yaml    # 共享提示词\n│   │   ├── level_-1_judge_agent.yaml  # 评判智能体\n│   │   ├── level_0_tools.yaml      # 工具定义\n│   │   ├── level_1_agents.yaml     # 底层智能体\n│   │   ├── level_2_agents.yaml     # 中层智能体\n│   │   └── level_3_agents.yaml     # 顶层智能体\n│   └── OpenCowork/                 # 通用电脑工作助手\n└── run_env_config/\n    ├── llm_config.yaml             # LLM 设置\n    └── llm_config.example.yaml     # 示例模板\n```\n\n### 关键配置文件\n\n#### 1. `llm_config.yaml` - LLM 配置\n\n```yaml\napi_key: \"your-api-key\"\nbase_url: \"https://openrouter.ai/api/v1\"\nmodels:\n  - \"openai/anthropic/claude-sonnet-4\"\n  - \"openai/anthropic/claude-haiku-4.5\"\ntemperature: 0.7\nmax_tokens: 8000\nfigure_models:\n  - \"google/gemini-2.0-flash-thinking-exp-01-21\"\n```\n\n**注意**：复制 `llm_config.example.yaml` 到 `llm_config.yaml` 开始使用。\n\n#### 2. 智能体层级\n\nMLA 将智能体组织成层级：\n\n- **Level 3**：顶层编排者（如 `alpha_agent`）\n- **Level 2**：功能专家（如 `data_collection_agent`、`coder_agent`）\n- **Level 1**：基础执行者（如 `web_search_agent`）\n- **Level 0**：工具定义\n- **Level -1**：质量控制（如 `judge_agent`）\n\n#### 3. 创建自定义智能体\n\n编辑 YAML 文件以自定义智能体行为：\n\n```yaml\nalpha_agent:\n  type: llm_call_agent\n  level: 3\n  model_type: \"advanced\"\n  available_tools:\n    - data_collection_agent\n    - coder_agent\n    - data_to_figures_agent\n    - material_to_document_agent\n    - judge_agent\n    - final_output\n  system_prompt: |\n    你是一个研究助手...\n```\n\n---\n\n## 💻 CLI 界面\n\n### 交互模式\n\n启动 CLI 进行对话式体验：\n\n```bash\nmla-agent --cli\n```\n\n**主要功能：**\n\n- 🔄 **多轮对话**，持久化上下文\n- 🤖 **智能体切换**，使用 `@agent_name` 语法\n- 🔔 **自动 HIL 检测**，带音频提醒\n- ⚠️ **工具执行确认**，手动模式下\n- ⏸️ **中断和恢复**支持（Ctrl+C 暂停）\n- 🎨 **丰富的终端 UI**，基于 `prompt_toolkit` 和 `rich`\n\n**使用示例：**\n\n```bash\n# 直接输入任务（使用默认智能体）\n[alpha_agent] > 收集有关 Transformer 的论文\n\n# 切换智能体并执行任务\n[alpha_agent] > @data_collection_agent 搜索最近的 NLP 论文\n\n# 仅切换默认智能体\n[alpha_agent] > @coder_agent\n✅ 已切换到：coder_agent\n[coder_agent] > \n```\n\n**CLI 命令：**\n\n| 命令 | 描述 |\n|------|------|\n| `/help` | 显示帮助和可用命令 |\n| `/agents` | 列出所有可用智能体 |\n| `/resume` | 恢复中断的任务 |\n| `/quit` 或 `/exit` | 退出 CLI 模式 |\n| `Ctrl+C` | 中断当前任务（保持在 CLI 中） |\n| `Ctrl+D` | 立即退出 CLI |\n\n**人机交互（HIL）处理：**\n\n当智能体请求人工输入时，CLI 会自动检测：\n\n```\n🔔🔔🔔 检测到 HIL 任务！按回车处理... 🔔🔔🔔\n================================================================================\n🔔 人类交互任务（HIL）\n================================================================================\n📝 任务 ID：upload_file_20250124\n📋 指令：请上传所需的数据集文件...\n================================================================================\n💡 输入你的响应（任何文本）\n   输入 /skip 跳过此任务\n================================================================================\n\n[alpha_agent] HIL 响应 > 文件已成功上传\n✅ HIL 任务已响应\n```\n\n**工具确认（手动模式）：**\n\n当设置 `--auto-mode false` 时，每次工具执行都需要确认：\n\n```\n⚠️⚠️⚠️ 检测到工具执行请求！按回车确认... ⚠️⚠️⚠️\n================================================================================\n⚠️  工具执行确认请求\n================================================================================\n🔧 工具名称：python_run\n📝 确认 ID：confirm_12345\n📋 参数：\n     code: import numpy as np...\n     timeout: 300\n================================================================================\n💡 选择操作：\n   yes / y - 批准执行\n   no / n  - 拒绝执行\n================================================================================\n\n[alpha_agent] 确认 [yes/no] > yes\n✅ 已批准执行工具：python_run\n```\n\n---\n\n### 命令行模式\n\n用于脚本和自动化：\n\n```bash\nmla-agent \\\n  --task_id /path/to/workspace \\\n  --user_input \"你的任务描述\" \\\n  --agent_name alpha_agent\n```\n\n**常用参数：**\n\n| 参数 | 描述 | 默认值 |\n|------|------|--------|\n| `--task_id` | 工作空间路径（绝对路径） | 必需 |\n| `--user_input` | 任务描述 | 必需 |\n| `--agent_name` | 调用的智能体 | `alpha_agent` |\n| `--agent_system` | 智能体库名称 | `Researcher` |\n| `--cli` | 交互式 CLI 模式 | `false` |\n| `--jsonl` | JSONL 输出模式 | `false` |\n| `--force-new` | 清空所有状态并重新开始 | `false` |\n| `--auto-mode` | 工具执行模式（`true`/`false`） | 自动检测 |\n\n**自动模式示例：**\n\n```bash\n# 自动执行工具（无需确认）\nmla-agent --task_id ~/project --user_input \"任务\" --auto-mode true\n\n# 每个工具需手动确认\nmla-agent --task_id ~/project --user_input \"任务\" --auto-mode false\n```\n\n---\n\n### 运行时工具执行\n\n```bash\n# 工具通过进程内 direct-tools 执行\n# 不再需要单独启动 mla-tool-server 进程\n```\n\n---\n\n## 🔌 SDK 集成\n\nMLA 提供两种 SDK 选项：**Python SDK** 用于直接集成，**JSONL 模式**用于 IDE 插件。\n\n---\n\n### Python SDK\n\n当前推荐直接使用内置的 `infiagent` SDK。现在的 SDK 语义是：\n\n- `infiagent(...)` 负责描述运行时默认配置\n- `run(...)`、`fresh(...)`、`add_message(...)` 等方法负责绑定具体 `task_id`\n- 可以通过 `user_data_root` 切换整套运行时目录\n\n最小示例：\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent(\n    user_data_root=\"/abs/path/to/my_root\",\n    default_agent_system=\"Researcher\",\n    default_agent_name=\"alpha_agent\",\n    action_window_steps=30,\n    thinking_interval=30,\n    max_turns=100000,\n    fresh_enabled=True,\n    fresh_interval_sec=300,\n)\n\nresult = agent.run(\n    \"写一篇关于 Transformer 的综述论文\",\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n)\n\nprint(f\"状态：{result['status']}\")\nprint(f\"输出：{result['output']}\")\n```\n\n如果你的 `user_data_root` 已经包含：\n\n- `config/llm_config.yaml`\n- `config/app_config.json`\n- `agent_library/...`\n- `tools_library/...`\n\n通常不需要再重复传入 `llm_config_path`、`agent_library_dir`、`tools_dir`。\n\n常用任务接口：\n\n```python\n# 对运行中或已停止的 task 发起 fresh / resume。\nagent.fresh(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    reason=\"reload runtime config\",\n)\n\n# 向同一个 task（不是 task_id正在运行中的智能体） 追加新指令。\nagent.add_message(\n    \"保留已有大纲，只修改第三节。\",\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    source=\"user\",\n    resume_if_needed=True,\n)\n\n# 启动新的后台 Python 进程执行另一个 task。（可以是相同 task_id，将获得此 id下之前 task的所有记忆）\nagent.start_background_task(\n    task_id=\"/abs/path/to/tasks/subtask_eval\",\n    user_input=\"后台运行评测流程并总结结果\",\n    force_new=True,\n)\n\n# 获取 task 快照，适合面板和轻量 watchdog。\nsnapshot = agent.task_snapshot(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n)\n\n# 重置损坏的 task 状态，可选保留 history。\nagent.reset_task(\n    task_id=\"/abs/path/to/tasks/transformer_survey\",\n    reason=\"clear broken loop\",\n    preserve_history=True,\n)\n```\n\n运行时自省：\n\n```python\nruntime = agent.describe_runtime()\nprint(runtime[\"user_data_root\"])\nprint(runtime[\"agent_library_dir\"])\nprint(runtime[\"tools_dir\"])\n\nsystems = agent.list_agent_systems()\nprint(systems[\"systems\"])\n```\n\nSDK 目前支持的高级能力：\n\n- 基于 `task_id` 的后台启动、resume 和 fresh\n- 基于 `user_data_root` 的 conversations、logs、runtime、config 隔离\n- 工具调用前后 hook\n- LLM 调用前的 context hook，可读取并改写最终 prompt\n- 通过 `mcp_servers=[...]` 为实例注入 MCP 运行时配置\n\n完整说明见：[docs/SDK_GUIDE.md](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/docs/SDK_GUIDE.md)\n\n**Python SDK 使用场景：**\n- 🔧 构建自定义工作流\n- 🤖 在现有应用中嵌入智能体\n- 📊 批量处理多个任务\n- 🧭 构建外部面板、watchdog 和调度层\n- 🔬 程序化控制的研究实验\n\n---\n\n### JSONL 模式（IDE 插件）\n\nMLA 提供 JSONL 流式模式，用于与 IDE 和编辑器实时集成：\n\n```bash\nmla-agent \\\n  --task_id $(pwd) \\\n  --user_input \"优化代码性能\" \\\n  --jsonl 2>/dev/null\n```\n\n**输出格式：**\n\n```jsonl\n{\"type\":\"start\",\"call_id\":\"c-1760936557-474c43\",\"project\":\"~/project\",\"agent\":\"alpha_agent\",\"task\":\"优化...\"}\n{\"type\":\"token\",\"text\":\"[alpha_agent] 正在分析代码...\"}\n{\"type\":\"progress\",\"phase\":\"execution\",\"pct\":30}\n{\"type\":\"token\",\"text\":\"调用工具：code_analyzer\"}\n{\"type\":\"result\",\"ok\":true,\"summary\":\"优化完成\"}\n{\"type\":\"end\",\"status\":\"ok\",\"duration_ms\":5432}\n```\n\n**事件类型：**\n\n| 事件类型 | 描述 | 关键字段 |\n|----------|------|----------|\n| `start` | 任务开始 | `call_id`、`agent`、`task` |\n| `token` | 流式文本输出 | `text` |\n| `progress` | 进度更新 | `phase`、`pct` |\n| `result` | 任务结果 | `ok`、`summary` |\n| `end` | 任务完成 | `status`、`duration_ms` |\n| `error` | 发生错误 | `message` |\n\n---\n\n### TypeScript/JavaScript 集成\n\n```typescript\nimport { spawn } from 'child_process';\n\ninterface AgentEvent {\n  type: 'start' | 'token' | 'progress' | 'result' | 'end' | 'error';\n  [key: string]: any;\n}\n\nfunction runAgent(\n  workspacePath: string, \n  userInput: string,\n  onEvent: (event: AgentEvent) => void\n): Promise<AgentEvent> {\n  return new Promise((resolve, reject) => {\n    const child = spawn('mla-agent', [\n      '--task_id', workspacePath,\n      '--user_input', userInput,\n      '--jsonl'\n    ]);\n    \n    let buffer = '';\n    \n    child.stdout.on('data', (data) => {\n      buffer += data.toString();\n      const lines = buffer.split('\\n');\n      buffer = lines.pop() || '';\n      \n      lines.forEach(line => {\n        if (!line.trim()) return;\n        \n        try {\n          const event: AgentEvent = JSON.parse(line);\n          onEvent(event);\n          \n          if (event.type === 'end') {\n            resolve(event);\n          } else if (event.type === 'error') {\n            reject(new Error(event.message));\n          }\n        } catch (e) {\n          console.error('解析事件失败：', line);\n        }\n      });\n    });\n    \n    child.stderr.on('data', (data) => {\n      // 将错误记录到 stderr\n      console.error(data.toString());\n    });\n    \n    child.on('error', reject);\n  });\n}\n\n// 使用示例\nawait runAgent('/path/to/workspace', '编写单元测试', (event) => {\n  switch (event.type) {\n    case 'start':\n      console.log(`任务开始：${event.task}`);\n      break;\n    case 'token':\n      process.stdout.write(event.text);\n      break;\n    case 'progress':\n      updateProgressBar(event.pct);\n      break;\n    case 'result':\n      console.log(`\\n结果：${event.summary}`);\n      break;\n  }\n});\n```\n\n---\n\n### VS Code 扩展示例\n\n使用 MLA 构建你自己的 Cursor/VS Code 扩展：\n\n**扩展功能：**\n- 🤖 命令面板中的智能体命令\n- 💬 带工作空间上下文的内联聊天\n- 📝 自动代码生成和重构\n- 🔍 编辑器内文献搜索\n- 🔔 带 UI 提示的 HIL 任务处理\n\n**基本扩展结构：**\n\n```typescript\n// extension.ts\nimport * as vscode from 'vscode';\nimport { runAgent } from './mla-client';\n\nexport function activate(context: vscode.ExtensionContext) {\n  let disposable = vscode.commands.registerCommand(\n    'mla.executeTask', \n    async () => {\n      const workspace = vscode.workspace.workspaceFolders?.[0].uri.fsPath;\n      const input = await vscode.window.showInputBox({\n        prompt: '输入任务描述'\n      });\n      \n      if (!workspace || !input) return;\n      \n      // 显示进度\n      await vscode.window.withProgress({\n        location: vscode.ProgressLocation.Notification,\n        title: 'MLA 智能体',\n        cancellable: true\n      }, async (progress, token) => {\n        \n        await runAgent(workspace, input, (event) => {\n          if (event.type === 'token') {\n            vscode.window.showInformationMessage(event.text);\n          } else if (event.type === 'progress') {\n            progress.report({ increment: event.pct });\n          }\n        });\n      });\n    }\n  );\n  \n  context.subscriptions.push(disposable);\n}\n```\n\n---\n\n## 📊 示例输出\n\n### 学术论文输出\n\nMLA 可以生成具有以下结构的完整研究论文：\n\n```\nupload/\n├── paper.tex               # 主 LaTeX 文档\n├── references.bib          # 参考文献\n├── figures/\n│   ├── architecture.png\n│   ├── results_comparison.png\n│   └── ablation_study.png\n└── supplementary/\n    └── detailed_results.pdf\n```\n\n**质量指标：**\n- ✅ 通过 EI/IEEE 会议的同行评审\n- ✅ 正确的引用格式\n- ✅ 高质量图表（300 DPI）\n- ✅ 连贯的结构和流程\n\n### 其他能力\n\n**1. 科学计算**\n- ECM 蛋白质组成仿真\n- 物流公司排班调度\n- 学生作业批改与反馈\n\n**2. 通用任务**\n- 网页抓取和数据提取\n- 代码生成和调试\n- 文档转换和处理\n\n---\n\n\n## 📖 文档\n\n- 运行时工具通过 direct-tools 进程内执行，不再需要单独的 tool server。\n- [人机交互 API](tool_server_lite/HIL_API.md) - 用户交互集成\n- [配置示例](config/agent_library/Researcher/) - 智能体 YAML 模板\n\n---\n\n## 🤝 贡献\n\n欢迎贡献！请随时提交问题或拉取请求。\n\n---\n\n## 📄 许可证\n\n详见 [LICENSE](LICENSE)\n\n---\n\n## 📄 引用\n\n如果您在研究中使用了 InfiAgent，请引用我们的论文：\n\n```bibtex\n@article{yu2026infiagent,\n  title={InfiAgent: An Infinite-Horizon Framework for General-Purpose Autonomous Agents},\n  author={Yu, Chenglin and Wang, Yuchen and Wang, Songmiao and Yang, Hongxia and Li, Ming},\n  journal={arXiv preprint arXiv:2601.03204},\n  year={2026}\n}\n```\n\n---\n\n## 🙏 致谢\n\n- 使用 [LiteLLM](https://github.com/BerriAI/litellm) 统一 LLM 访问\n- 使用 [Crawl4AI](https://github.com/unclecode/crawl4ai) 进行网页抓取\n\n---\n\n## 📬 联系方式\n\n**作者**：@yuchenglin\n\n**感谢贡献者**：@wangyuchen @wangsongmiao @yuyang @lijinjia\n\n**邮箱**：yuchenglin96@qq.com/cl0415@connect.hku.hk/chenglin.yu@poly.edu.h \n\n**GitHub**：[MLA V3 仓库](https://github.com/ChenglinPoly/infiAgent)\n\n---\n\n**使用 MLA V3 开始构建专属领域的 SOTA 智能体！** 🚀\n"
  },
  {
    "path": "apps/__init__.py",
    "content": ""
  },
  {
    "path": "apps/cheapclaw/README.md",
    "content": "# CheapClaw\n\nCheapClaw is a social-message orchestration app built on top of the `infiagent/mla` SDK.\n\nIt started from a practical judgment about OpenClaw-style systems: the idea is good, but the operating cost is too high if you push everything through large models for long-running work. CheapClaw is aimed at the opposite direction. It tries to make weaker and cheaper models hold long tasks better by leaning on InfiAgent's runtime design instead of turning every message into a giant single-shot agent loop.\n\nThe core problem it solves is not \"how to connect one more chat channel\". The real problem is:\n\n- a user sends a new request while several agents are already running\n- sometimes the new message should continue an old task\n- sometimes it should inject a new requirement into a running task\n- sometimes it should start a parallel branch\n- and the system needs to choose that path automatically without losing context\n\nCheapClaw is built around that decision layer.\n\n## Why CheapClaw exists\n\nCompared with OpenClaw-like systems, the main motivation here is cost and long-horizon stability.\n\nOpenClaw is impressive, but for many practical deployments it is expensive. CheapClaw uses `infiagent` as the execution substrate because `infiagent` already has several properties that matter for weaker models:\n\n- short-step execution instead of giant long-context monologues\n- resumable task memory keyed by `task_id`\n- configurable fresh / resume behavior\n- agent-system level composition\n- SDK-level control over runtime, task state, and tool execution\n\nThat makes it much more suitable for small-model orchestration, especially when tasks are long and iterative.\n\n## What is different\n\n### 1. Instant message insertion into existing work\n\nThis is the main feature, not a side feature.\n\nCheapClaw has a supervisor agent that decides how a new message should be routed:\n\n- continue an old task by reusing the same `task_id`\n- append a requirement to a currently running task without stopping it\n- fork into a new task when the work is genuinely different\n\nThese are different operations and they are handled differently.\n\n#### Continue an old task\n\nIf the work is still the same deliverable, CheapClaw can restart a new worker on the same `task_id`.\n\nThat matters because the old task keeps:\n\n- workspace\n- share context\n- historical outputs\n- prior task memory\n\nSo \"modify the old report\", \"redo that script\", \"continue the previous result\" does not have to become a brand new task.\n\n#### Append to a running task\n\nIf a worker is still running, CheapClaw can inject a new requirement into that running task.\n\nThis does not require stopping the worker first. The requirement is appended and absorbed on the next safe loop boundary.\n\nThat is a different behavior from resuming an old task, and it is one of the main pain points CheapClaw is designed to solve.\n\n### 2. Built on the InfiAgent SDK, not a closed custom runtime\n\nCheapClaw is not a monolithic framework. It is an application built on the `infiagent` SDK.\n\nThat means it inherits several useful runtime capabilities:\n\n- different thinking and execution models\n- different models for different sub-agents\n- mixed local models and provider models\n- mixed API vendors in one overall system\n- task-level runtime control through the SDK\n\nIn practice, this means you can build a system where:\n\n- the supervisor uses one model\n- the worker uses another\n- a compression model is different again\n- some parts use local inference and others use hosted APIs\n\nThis is configured at the agent-system level and in the model config.\n\n### 3. Better behavior for weaker models\n\nCheapClaw benefits from InfiAgent's short-step execution strategy.\n\nFor weak or small models, that matters a lot. With the same model, total cost can go either way depending on the exact task, but on long-running tasks the short-step strategy is often more stable and more cost-efficient than trying to force a weak model through a giant single planning loop.\n\nPractical rule:\n\n- the weaker the model, the shorter the step window should be\n- do not set it below 10\n- a good default is 20\n\n### 4. Skills are not the only extension mechanism\n\nCheapClaw supports normal skills, but it also treats full agent systems as a reusable extension layer.\n\nIn the default CheapClaw layout there are only two systems:\n\n- `CheapClawSupervisor`\n- `CheapClawWorkerGeneral`\n\nBut `infiagent` itself also ships with other agent systems, for example:\n\n- `Researcher`\n- `OpenCowork`\n\nIf you want to reuse them in this kind of setup, remove `human_in_loop` from their config first.\n\nUsing a full agent system as a reusable capability is sometimes better than a narrow skill:\n\n- a skill is good for a compact workflow or tool pattern\n- an agent system is good for a whole class of related tasks with a stronger internal role design\n\nYou can think of an agent system as a kind of \"skill pro\": broader coverage, more prompt budget, more specialization.\n\n## Architecture\n\nCheapClaw has three layers:\n\n1. Channel adapters\n2. A supervisor agent\n3. Worker tasks running on InfiAgent\n\nThe supervisor does not do the real work. It decides:\n\n- direct reply\n- reuse old `task_id`\n- append to running task\n- start a new task\n- restart / fresh / reset when needed\n\nWorkers do the execution.\n\n## Current capabilities\n\n- Telegram integration\n- Feishu integration through long connection mode\n- WhatsApp adapter scaffolding\n- dashboard and panel view\n- conversation-to-task binding\n- task completion observation\n- watchdog observation\n- task-level visible skill filtering\n- task-level message append\n- task-level restart on the same `task_id`\n- file sending for Telegram\n\n## Skills behavior\n\nCheapClaw uses task-level visible-skill filtering for worker agents.\n\nBy default, workers only see:\n\n- `docx`\n- `pptx`\n- `xlsx`\n- `find-skills`\n\nThe supervisor can expose more skills to a worker when needed.\n\nThis is implemented by filtering what the model sees in `<available_skills>`, not by breaking the global skill installation mechanism. That means normal skill installation still works.\n\n## Install and run\n\nThe intended model is:\n\n1. install `infiagent`\n2. install CheapClaw's extra runtime dependencies\n3. place CheapClaw in a separate repo\n4. point it at a `user_data_root`\n5. run it as an app\n\n### 1. Install InfiAgent\n\nUse the published package first:\n\n```bash\npython -m pip install -U infiagent==3.0.1\n```\n\n### 2. Install CheapClaw's extra dependencies\n\nCheapClaw itself is an app layer on top of `infiagent`, so it still needs a few app-specific packages:\n\n```bash\npython -m pip install -U requests lark-oapi\n```\n\nIf you only test Telegram first, `requests` is enough.  \nIf you want Feishu long-connection mode, install `lark-oapi` too.\n\n### Bootstrap assets\n\n```bash\npython cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --bootstrap\n```\n\n### Show runtime\n\n```bash\npython cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --show-runtime\n```\n\n### Run one cycle\n\n```bash\npython cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --run-once\n```\n\n### Run as a long-lived service\n\n```bash\npython cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --run-loop\n```\n\n### Start the local dashboard\n\n```bash\npython cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --serve-webhooks --host 127.0.0.1 --port 8765 \\\n  --run-loop\n```\n\nThen open:\n\n- `http://127.0.0.1:8765/dashboard`\n\n## Channel credentials\n\n### Telegram\n\n- `bot_token`\n\n### Feishu\n\n- `app_id`\n- `app_secret`\n- `verify_token`\n- optional: `encrypt_key`\n\nCheapClaw uses Feishu long connection mode, so it does not require a public webhook endpoint.\n\n### WhatsApp Cloud API\n\n- `access_token`\n- `phone_number_id`\n- `verify_token`\n\n## Repository layout\n\n- `cheapclaw_service.py`: main service entry\n- `tool_runtime_helpers.py`: panel, task, and runtime helpers\n- `assets/agent_library/`: supervisor and worker systems\n- `assets/config/`: example config files\n- `tools_library/`: CheapClaw-specific tools\n- `skills/`: CheapClaw-specific skills\n- `web/`: dashboard\n\n## Notes for separate release\n\nCheapClaw is intended to live in its own repository.\n\nThe framework-level changes that made it possible are mostly SDK and runtime improvements in `infiagent`, especially:\n\n- SDK task control\n- task snapshotting\n- fresh / resume support\n- tool hooks\n- context hooks\n- skill visibility filtering\n\nIf you publish `infiagent` to PyPI, CheapClaw can then be shipped as a clean separate application repo on top of that package.\n"
  },
  {
    "path": "apps/cheapclaw/__init__.py",
    "content": ""
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawSupervisor/general_prompts.yaml",
    "content": "system_prompt_xml: |\n  <系统角色>\n  你是 CheapClawSupervisor 系统中的主调度智能体。你负责理解社交消息、维护会话状态、派发/续跑后台任务、安排计划任务、处理 watchdog 观测以及组织对用户的回复。\n  你不是业务执行 worker。你不直接做长任务，不自己产出复杂交付物。\n  </系统角色>\n\n  <面板语义>\n  CheapClaw 面板是调度的单一事实来源。任务输入只会给你当前 trigger_reason 和 dirty conversations 的事件摘要，不会把完整 panel、完整路径、完整 bindings、全量 linked_tasks 全部塞进来。\n  每个 dirty conversation 摘要主要包含：\n  - 所有新的用户消息\n  - 所有新的任务事件（尤其是 task_completed）\n  不会直接附带完整任务列表。你需要自己决定何时继续查。\n  如果你需要完整 panel、完整 bindings、完整 linked_tasks、message history 的完整范围、或 task 的文件路径和详细状态，必须主动调用工具：\n  - cheapclaw_read_panel\n  - cheapclaw_read_social_history\n  - cheapclaw_list_conversation_tasks\n  - cheapclaw_get_task_status\n  message_task_bindings 表示“哪条用户消息已经绑定到哪个 task_id”。一个 task_id 可以绑定多条用户消息；多条用户消息共同组成同一工作的连续需求。\n  </面板语义>\n\n  <核心决策流程>\n  处理每个 dirty conversation 时，必须按下面顺序思考：\n  1. 先识别这次触发来自什么：新用户消息、计划任务、watchdog、task 完成、还是系统状态变化。\n  2. 如果是用户消息，先判断是否只是普通聊天、澄清、确认、或无需调用 worker 就能直接回复。\n  3. 如果是明显的任务型需求，在不需要额外澄清时，应尽快先向用户发送一条简短回执，例如“收到，我先检查现有任务并继续处理”或“收到，我正在安排助手处理”，然后再继续做 task 路由和后台调度。\n     这个快速回执不等于最终结果；它只是为了让用户立即知道系统已接单。\n  4. 如果不是直接回复，再判断它与历史 task 的关系：\n     - append_to_running_task：这是同一工作，且已有 task 正在运行。\n     - continue_existing_task：这是同一工作，但已有 task 当前未运行，应恢复同一个 task_id。\n     - fork_new_task：和历史工作相关，但应开一个新的 task_id，例如新的 deliverable、不同 agent_system、不同实验分支、风险隔离。\n     - brand_new_task：与现有工作无关，应开全新 task。\n  5. 做出 task 决策后，必须把触发这次决策的 message_id 绑定到对应 task_id：\n     - 新建 task：用 cheapclaw_start_task 的 source_message_ids。\n     - 追加已有 task：用 cheapclaw_add_task_message 的 source_message_ids，或用 cheapclaw_update_panel 补充绑定。\n     - 直接回复无 task：也应在面板中更新 last_reply_summary，并清理 pending_events，避免同一条消息反复触发。\n  6. 如果同一 conversation 中有多个历史 task，必须先调用 cheapclaw_list_conversation_tasks，并结合：\n     - social_history 中的最近用户消息\n     - panel 中的完整 message_task_bindings\n     - task 的最近 final_output / thinking / status\n     来判断该继续哪个旧 task_id。\n     `recommended_task_id` 只是启发式提示，不是强制结论。最终选择必须由你基于历史对话和任务状态自行判断。\n     只有在有明确证据表明用户是在要求一个新 deliverable、一个新实验分支、一个不同 agent_system，或者旧 task 明显不适合承接时，才允许新建 task。\n  7. 处理完成后要更新面板：清掉已处理的 dirty / pending_events，必要时写 last_reply_summary、task 状态、message_task_bindings。\n  </核心决策流程>\n\n  <连续任务强规则>\n  对同一 deliverable 的修改、补充、重试、参数调整，默认都属于继续已有 task，而不是新建 task。\n  当旧 task 当前未运行，但你希望在“同一个 task_id / 同一个工作目录 / 同一段历史记忆”上继续做新的后台执行时，优先使用 cheapclaw_start_task，并显式传入这个旧 task_id。cheapclaw_start_task 不会再自动生成 task_id；如果确实要开新任务，必须先调用 cheapclaw_generate_task_id。\n  cheapclaw_add_task_message 主要用于：\n  - 目标 task 仍在运行中，需要即时插入新的需求\n  - 或者你明确想先把消息追加进当前任务上下文，再配合 resume/fresh 继续\n  下面这些表达，若 conversation 中已有相关 task，默认先判断该 task 是否仍在运行：\n  - “改成生成前 20 个”\n  - “把刚才那个脚本默认值改一下”\n  - “继续刚才那个任务”\n  - “再加一个导出 csv”\n  - “刚才那个结果不对，重试一下”\n  规则：\n  - 若旧 task 正在运行：优先 cheapclaw_add_task_message\n  - 若旧 task 已结束/已停止，但仍然是同一工作：优先 cheapclaw_start_task(task_id=旧task_id)\n  - 若确实是全新工作：先 cheapclaw_generate_task_id，再 cheapclaw_start_task(task_id=新task_id)\n  - 只有当用户明确要求新的独立交付物、不同方向的工作、或需要保留旧结果作为并行分支时，才新建新的 task_id\n  如果最新用户消息是在某个 task 完成后紧接着提出的增量修改，默认继续这个最近完成的 task_id。\n  </连续任务强规则>\n\n  <任务派发原则>\n  - 只有当确实需要后台工作时才启动 worker。\n  - 派工后要立即给用户发送回执，不等待 worker 完成。\n  - 如果任务正在进行而用户又提出补充需求，优先追加到同一 task，而不是重复开新任务。\n  - 如果用户明确改变目标、交付物、方法或系统，应考虑 fork 新 task。\n  - 如果 watchdog 只是“安静但可能还活着”，先查看状态、日志、history，再决定是否 fresh 或 reset。\n  - reset_task 是高风险操作，只在证据充分、当前 task 无法安全恢复时使用。\n  </任务派发原则>\n\n  <工具使用原则>\n  你优先使用 CheapClaw 专用工具：\n  - cheapclaw_read_panel\n  - cheapclaw_read_social_history\n  - cheapclaw_get_task_status\n  - cheapclaw_start_task\n  - cheapclaw_add_task_message\n  - cheapclaw_send_message\n  - cheapclaw_update_panel\n  - cheapclaw_schedule_plan / cheapclaw_cancel_plan\n  - cheapclaw_reset_task\n  - cheapclaw_list_agent_systems\n  - cheapclaw_list_global_skills / cheapclaw_reveal_skills\n  只有在需要看日志尾部或补充核验文件内容时，才使用 file_read / task_share_context_path / grep。\n  不要假设任务输入里已经附带了完整 panel 路径、message_history_path、share_context_path、log_path。需要这些时，主动调用 CheapClaw 工具查询。\n  如果当前新消息不足以判断其和旧任务的关系，先用 cheapclaw_read_social_history 扩展读取历史；如果你已经知道关键词或 task_id，也可以直接对 social_history.jsonl / latest_context.md / panel.json 使用 grep。\n  启动 worker 时不要臆造 agent_name。默认对 `CheapClawWorkerGeneral` 只使用 `worker_agent`。\n  如果你想使用别的 agent_name，必须先通过 `cheapclaw_list_agent_systems` 确认该 agent_system 的 `agent_names` 中确实存在该名字。\n  你绝对不能启动 `CheapClawSupervisor` 或 `supervisor_agent` 作为后台任务。主调度 agent 不能调用本身，否则会造成递归调度和状态污染。\n  </工具使用原则>\n\n  <计划与watchdog>\n  当 trigger_reason 或 pending_events 中出现 plan_tick / watchdog_tick / task_completed 时：\n  - 先查看对应 task 的最新状态和最近输出\n  - 决定是否需要给用户发送状态更新\n  - 决定是否需要继续派生任务、追加消息、fresh 或 reset\n  - 不要把“很久没更新 thinking”直接等同于卡死；先结合 log_path、last_action_at、最近历史消息综合判断\n  如果需要系统化排查 watchdog 观测，你可以加载 cheapclaw-watchdog skill。\n  </计划与watchdog>\n\n  <输出要求>\n  你本轮结束前必须用 final_output 给出简洁调度摘要：\n  - 处理了哪些 conversations\n  - 哪些消息被直接回复\n  - 哪些 message_id 被绑定到了哪些 task_id\n  - 启动/恢复/追加/重置了哪些 tasks\n  - 设置或取消了哪些计划\n  不要在 final_output 中粘贴大段日志或文件内容。\n  </输出要求>\n"
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawSupervisor/level_0_tools.yaml",
    "content": "tools:\n  # ==================== 文件操作工具 ====================\n  \n  file_read:\n    level: 0\n    type: tool_call_agent\n    name: \"file_read\"\n    description: \"读取指定文本文件的内容。路径参数必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。可以读取单个或多个文件，也可以指定起始和结束行。默认返回带行号的 JSON 格式。警告：不要读取二进制文件（如 pdf、docx、图片等）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"文件相对路径数组，基于当前 workspace/task 根目录解析。单个文件传 ['file.txt']，多个文件传 ['file1.txt', 'file2.txt']。不要传绝对路径；只允许读取文本文件，不要读取二进制文件。\"\n        start_line:\n          type: \"integer\"\n          description: \"读取起始行号（从1开始），可选。多文件模式下应用于所有文件。\"\n        end_line:\n          type: \"integer\"\n          description: \"读取结束行号（包含），可选。多文件模式下应用于所有文件。\"\n        encoding:\n          type: \"string\"\n          description: \"文件编码，可选。不指定时自动检测。\"\n        show_line_numbers:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号。true 返回 JSON 格式（含行号），false 返回纯文本。默认 true。\"\n      required: [\"path\"]\n\n  file_write:\n    level: 0\n    type: tool_call_agent\n    name: \"file_write\"\n    description: \"向指定文本文件写入内容。path 必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。如果文件不存在会自动创建；如果存在可以选择覆盖或追加，也支持替换指定行。注意：禁止写入 reference.bib 文件，请使用专门的参考文献管理工具（reference_add/reference_delete）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"文件的相对路径，例如 'src/main.py'，相对于当前 workspace/task 根目录解析。不要传绝对路径。写入前建议使用目录列表工具检查是否有同名文件，避免覆盖他人文件。禁止路径为 'reference.bib'。\"\n        content:\n          type: \"string\"\n          description: \"要写入的文本内容。\"\n        mode:\n          type: \"string\"\n          enum: [\"write\", \"append\"]\n          default: \"write\"\n          description: \"写入模式。'write' 覆盖整个文件，'append' 追加到文件末尾。\"\n        start_line:\n          type: \"integer\"\n          description: \"行替换模式 - 起始行号（从1开始），可选。\"\n        end_line:\n          type: \"integer\"\n          description: \"行替换模式 - 结束行号，可选。\"\n      required: [\"path\", \"content\"]\n  \n  dir_list:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_list\"\n    description: \"列出指定目录的内容。path 必须是相对于当前 workspace/task 根目录的相对路径；不传时默认列出任务根目录。可以递归列出所有子目录和文件（自动排除 code_env 目录）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          default: \".\"\n          description: \"要列出的目录相对路径，相对于当前 workspace/task 根目录解析。不指定时列出任务根目录。\"\n        recursive:\n          type: \"boolean\"\n          default: false\n          description: \"是否递归列出子目录，默认 false。\"\n      required: []\n\n  dir_create:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_create\"\n    description: \"创建新目录。path 必须是相对于当前 workspace/task 根目录的相对路径。如果父目录不存在会自动创建。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要创建的目录相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  file_move:\n    level: 0\n    type: tool_call_agent\n    name: \"file_move\"\n    description: \"移动或复制文件/目录。source 和 destination 都应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source:\n          # type: \"string\"\n          # description: \"源文件或目录的相对路径。\"\n          # path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"源文件或目录的相对路径组，相对于当前 workspace/task 根目录解析。可以单个或多个。\"\n        destination:\n          type: \"string\"\n          description: \"目标相对路径，相对于当前 workspace/task 根目录解析。\"\n        copy:\n          type: \"boolean\"\n          default: false\n          description: \"是否复制（保留原文件），默认 false（移动）。\"\n      required: [\"source\", \"destination\"]\n\n  file_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"file_delete\"\n    description: \"删除指定的文件或目录。path 应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要删除的文件或目录的相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  # ==================== 网络工具 ====================\n\n  web_search:\n    level: 0\n    type: tool_call_agent\n    name: \"web_search\"\n    description: \"使用 DuckDuckGo 进行网络搜索。结果会保存为 Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或问题。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件），请保存在 temp/web_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  google_scholar_search:\n    level: 0\n    type: tool_call_agent\n    name: \"google_scholar_search\"\n    description: \"在 Google Scholar 上搜索学术论文。支持年份筛选和分页。搜索结果保存为 Markdown 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或主题。\"\n        year_low:\n          type: \"integer\"\n          description: \"筛选论文的起始年份，可选。\"\n        year_high:\n          type: \"integer\"\n          description: \"筛选论文的结束年份，可选。\"\n        pages:\n          type: \"integer\"\n          default: 1\n          description: \"爬取的搜索结果页数，每页约10篇论文。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件)。请保存在 temp/scholar_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  arxiv_search:\n    level: 0\n    type: tool_call_agent\n    name: \"arxiv_search\"\n    description: \"搜索 arXiv 预印本论文库。返回论文标题、作者、摘要、PDF 下载地址等信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词，例如 'transformer neural network'。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        sort_by:\n          type: \"string\"\n          enum: [\"relevance\", \"lastUpdatedDate\", \"submittedDate\"]\n          default: \"relevance\"\n          description: \"排序方式：relevance（相关性）、lastUpdatedDate（更新时间）、submittedDate（提交时间）。\"\n        sort_order:\n          type: \"string\"\n          enum: [\"descending\", \"ascending\"]\n          default: \"descending\"\n          description: \"排序顺序：descending（降序）、ascending（升序）。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件）。请保存在 temp/arxiv_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  crawl_page:\n    level: 0\n    type: tool_call_agent\n    name: \"crawl_page\"\n    description: \"爬取指定 URL 的网页内容，转换为 Markdown 格式。使用 crawl4ai 智能提取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要爬取的网页完整 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存 Markdown 文件的相对路径，必选。不指定则直接返回内容。请保存在 temp/crawl_page目录中。\"\n        download_images:\n          type: \"boolean\"\n          default: false\n          description: \"是否下载图片，默认 false（移除图片）。\"\n      required: [\"url\",\"save_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 参考文献管理工具 ====================\n\n  reference_list:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_list\"\n    description: \"列出 reference.bib 文件中的所有参考文献（显示原文）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: []\n\n  reference_add:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_add\"\n    description: \"向 reference.bib 添加参考文献。如果引用键已存在则覆盖原有内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        entries:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考文献字符串数组，每个元素是一条完整的bib条目。例如：['@article{key1,...}', '@book{key2,...}']\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"entries\"]\n\n  reference_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_delete\"\n    description: \"从 reference.bib 删除指定的参考文献。\"\n    parameters:\n      type: \"object\"\n      properties:\n        keys:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"要删除的引用键（如 'sun2023blockchain'）或引用键数组。\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"keys\"]\n\n  # ==================== 文档处理工具 ====================\n\n  parse_document:\n    level: 0\n    type: tool_call_agent\n    name: \"parse_document\"\n    description: \"解析二进制文档为纯文本文件，不提供总结，分析服务。支持 PDF、Word、Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要解析的文档相对路径。\"\n        save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径。请保存在 temp/parse_document目录中。\"\n      required: [\"path\",\"save_path\"]\n\n  vision_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"vision_tool\"\n    description: \"使用LLM Vision模型分析图片内容。可以识别图片中的内容、描述场景、回答问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_path:\n          type: \"string\"\n          description: \"图片文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这是什么？'或'请描述图片中的内容'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"必选，保存结果的相对路径,保存为纯文本文件 md或者 txt。请保存在 temp/answer_figuers目录中。\"\n        # model:\n        #   type: \"string\"\n        #   description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"image_path\",\"save_path\"]\n\n  image_read:\n    level: 0\n    type: tool_call_agent\n    name: \"image_read\"\n    description: \"读取并分析图片内容（支持同时读取多张）。如果主模型支持多模态，图片会直接嵌入到对话中由主模型分析；否则会调用 Vision LLM 进行分析并返回文字描述。适用于查看实验结果图表、分析截图、理解图片内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径数组（相对于任务目录）。读取单张图片传单元素数组，如 [\\\"result.png\\\"]。支持 jpg/jpeg/png/gif/webp/bmp 格式。\"\n        query:\n          type: \"string\"\n          description: \"关于图片的问题或分析要求，例如'这些图表显示了什么趋势？'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"可选，保存分析结果的相对路径（仅在 text-only 模式下有效）。\"\n      required: [\"image_paths\"]\n\n  create_image:\n    level: 0\n    type: tool_call_agent\n    name: \"create_image\"\n    description: \"根据提示词生成图片，或基于参考图进行图片编辑/融合/风格迁移。支持最多 14 张参考图（Gemini 3 Pro）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        prompt:\n          type: \"string\"\n          description: \"图片的描述提示词或编辑指令。纯生成时描述要生成的图片；有参考图时描述如何处理参考图（如'融合这两张图'、'将第一张图转为梵高风格'）。\"\n        image_path:\n          type: \"string\"\n          description: \"生成图片保存的相对路径（例如 'temp/generated_image.png'）。\"\n        reference_images:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考图片相对路径列表，可选。用于图片编辑、风格迁移、多图融合等。不提供则为纯文本生成图片。\"\n        size:\n          type: \"string\"\n          default: \"1024x1024\"\n          description: \"生成图片尺寸，默认 '1024x1024'。支持 '1792x1024'（16:9）等。\"\n        n:\n          type: \"integer\"\n          default: 1\n          description: \"生成图片数量，默认 1。\"\n      required: [\"prompt\", \"image_path\"]\n\n  audio_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"audio_tool\"\n    description: \"使用LLM Audio模型分析音频内容。可以识别音频中的内容、描述场景、回答问题等。支持 mp3、wav、m4a 等格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        audio_path:\n          type: \"string\"\n          description: \"音频文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这段音频讲了什么？'或'请描述音频内容'。不指定则默认描述音频内容。\"\n        model:\n          type: \"string\"\n          description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"audio_path\"]\n\n  paper_analyze_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"paper_analyze_tool\"\n    description: \"解析论文文档并使用LLM分析论文内容。可以总结论文、回答关于论文的问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        paper_path:\n          type: \"string\"\n          description: \"论文文件的相对路径（相对于任务目录），支持PDF、Word等格式。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这篇论文的主要贡献是什么？'不指定则默认总结论文内容。\"\n        parse_save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径，可选。\"\n      required: [\"paper_path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从指定 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 文档处理工具 ====================\n\n  # parse_document:\n  #   level: 0\n  #   type: tool_call_agent\n  #   name: \"parse_document\"\n  #   description: \"解析文档文件并提取文本内容。支持 PDF、Word、Markdown 格式。使用 pdfplumber 高质量提取 PDF（包含表格）。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       path:\n  #         type: \"string\"\n  #         description: \"要解析的文档相对路径。\"\n  #       save_path:\n  #         type: \"string\"\n  #         description: \"保存解析结果的相对路径，可选。不指定则直接返回内容。\"\n  #     required: [\"path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  images_to_ppt:\n    level: 0\n    type: tool_call_agent\n    name: \"images_to_ppt\"\n    description: \"将多张图片转换为 PowerPoint 演示文稿，每张图片占一页。PPT 尺寸自动根据第一张图片的宽高比设置，所有图片居中显示并保持比例。适合将多张图表、截图等快速制作成演示文稿。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径列表，例如 ['chart1.png', 'chart2.png']。也可以是单个字符串。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PPT 文件的相对路径，例如 'presentation.pptx'。\"\n      required: [\"image_paths\", \"output_path\"]\n\n  # ==================== 浏览器操作工具 ====================\n\n  browser_launch:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_launch\"\n    description: \"启动浏览器会话。默认打开有界面的浏览器窗口（非无头模式），创建第一个标签页 page_0。返回 browser_id 用于后续操作。会自动创建 temp/browser/{browser_id}/ 目录保存截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        headless:\n          type: \"boolean\"\n          default: false\n          description: \"是否无头模式（不显示浏览器窗口），默认 false（显示窗口）。\"\n        width:\n          type: \"integer\"\n          default: 1280\n          description: \"浏览器窗口宽度（像素），默认 1280。\"\n        height:\n          type: \"integer\"\n          default: 800\n          description: \"浏览器窗口高度（像素），默认 800。\"\n      required: []\n\n  browser_close:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close\"\n    description: \"关闭浏览器会话。会关闭所有标签页并清理资源。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID（由 browser_launch 返回）。\"\n      required: [\"browser_id\"]\n\n  browser_navigate:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_navigate\"\n    description: \"在当前活跃标签页导航到指定 URL。导航后自动截图并保存页面内容到 temp/browser/{browser_id}/current.png 和 page_content.md。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        url:\n          type: \"string\"\n          description: \"目标 URL，例如 'https://www.example.com'。\"\n        wait_until:\n          type: \"string\"\n          enum: [\"load\", \"domcontentloaded\", \"networkidle\"]\n          default: \"load\"\n          description: \"等待条件：load（页面加载完成）、domcontentloaded（DOM加载完成）、networkidle（网络空闲）。默认 load。\"\n      required: [\"browser_id\", \"url\"]\n\n  browser_snapshot:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_snapshot\"\n    description: \"获取当前活跃标签页的快照。更新截图和页面文本内容。返回页面标题、URL、截图路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        include_html:\n          type: \"boolean\"\n          default: false\n          description: \"是否包含 HTML 源码，默认 false。如果为 true，会保存到 page_source.html。\"\n      required: [\"browser_id\"]\n\n  browser_execute_js:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_execute_js\"\n    description: \"在当前活跃标签页执行 JavaScript 代码。这是最强大的浏览器操作工具，可以实现任意页面操作（点击、输入、滚动、提取数据等）。执行后自动截图。注意：JavaScript 代码必须是函数表达式，如 '() => { return document.title; }'。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        script:\n          type: \"string\"\n          description: \"要执行的 JavaScript 代码。必须是函数表达式，如 '() => { ... }'。示例：'() => document.querySelector(\\\"#btn\\\").click()' 或 '() => { return Array.from(document.querySelectorAll(\\\".item\\\")).map(el => el.textContent); }'。\"\n        save_result:\n          type: \"boolean\"\n          default: false\n          description: \"是否将执行结果保存到 js_result.json 文件，默认 false。\"\n      required: [\"browser_id\", \"script\"]\n\n  browser_new_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_new_page\"\n    description: \"在当前浏览器会话中新建一个标签页。新标签页会自动成为活跃页面。返回新的 page_id（如 page_1, page_2）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_switch_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_switch_page\"\n    description: \"切换到指定的标签页，使其成为活跃页面。切换后会自动更新截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要切换到的页面ID，例如 'page_0', 'page_1'。可通过 browser_list_pages 查看所有页面。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_close_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close_page\"\n    description: \"关闭指定的标签页。如果关闭的是活跃页面，会自动切换到第一个页面。不能关闭唯一的标签页（至少保留一个）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要关闭的页面ID，例如 'page_1'。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_list_pages:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_list_pages\"\n    description: \"列出当前浏览器会话的所有标签页。显示每个页面的 page_id、标题、URL、是否为活跃页面。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_click:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_click\"\n    description: \"点击当前页面的指定元素。使用 CSS 选择器定位元素。点击后自动截图。如果元素难以点击，建议使用 browser_execute_js 执行 JavaScript 点击。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器，例如 '#submit-btn', '.button', 'button[type=\\\"submit\\\"]'。\"\n        timeout:\n          type: \"integer\"\n          default: 5000\n          description: \"等待元素出现的超时时间（毫秒），默认 5000。\"\n      required: [\"browser_id\", \"selector\"]\n\n  browser_type:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_type\"\n    description: \"在指定的输入框输入文本。使用 CSS 选择器定位输入框。输入后自动截图。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"输入框的 CSS 选择器，例如 '#username', 'input[name=\\\"email\\\"]'。\"\n        text:\n          type: \"string\"\n          description: \"要输入的文本内容。\"\n        clear_first:\n          type: \"boolean\"\n          default: true\n          description: \"是否先清空输入框，默认 true。\"\n      required: [\"browser_id\", \"selector\", \"text\"]\n\n  browser_wait:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_wait\"\n    description: \"等待指定条件满足。可以等待元素出现、页面导航完成或指定时间。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        wait_type:\n          type: \"string\"\n          enum: [\"selector\", \"navigation\", \"timeout\"]\n          description: \"等待类型：selector（等待元素出现）、navigation（等待导航完成）、timeout（等待指定时间）。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器（wait_type='selector' 时必需）。\"\n        timeout:\n          type: \"integer\"\n          default: 30000\n          description: \"超时时间（毫秒），默认 30000。\"\n        milliseconds:\n          type: \"integer\"\n          description: \"等待时长（毫秒，wait_type='timeout' 时必需）。\"\n      required: [\"browser_id\", \"wait_type\"]\n\n  browser_mouse_move:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_move\"\n    description: \"移动鼠标到指定坐标位置。支持人类化移动（贝塞尔曲线轨迹）模拟真实用户行为，避免人机验证检测。适用于需要精确控制鼠标位置的场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。设为 false 则直接瞬移到目标位置。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_mouse_click_coords:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_click_coords\"\n    description: \"在指定坐标位置点击鼠标。支持左键/右键/中键、单击/双击、人类化点击（随机延迟和轨迹）。适用于动态元素、Canvas/SVG 区域、无法用选择器定位的元素。特别适合处理滑块验证码等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"点击的 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"点击的 y 坐标（像素）。\"\n        button:\n          type: \"string\"\n          enum: [\"left\", \"right\", \"middle\"]\n          default: \"left\"\n          description: \"鼠标按钮：left（左键）、right（右键）、middle（中键），默认 left。\"\n        click_count:\n          type: \"integer\"\n          default: 1\n          description: \"点击次数，1为单击，2为双击，默认 1。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化点击（贝塞尔曲线移动+随机延迟），默认 true。推荐在需要绕过人机验证时启用。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_drag_and_drop:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_drag_and_drop\"\n    description: \"执行鼠标拖拽操作，从起点拖动到终点。支持人类化拖拽（贝塞尔曲线轨迹+随机延迟）模拟真实用户行为。主要用于：1) 滑块验证码（重要！）2) 拖拽排序 3) 地图平移/缩放 4) 拖拽文件上传 5) 任何需要拖拽的交互。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        from_x:\n          type: \"number\"\n          description: \"起始 x 坐标（像素）。\"\n        from_y:\n          type: \"number\"\n          description: \"起始 y 坐标（像素）。\"\n        to_x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        to_y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化拖拽（贝塞尔曲线轨迹+随机延迟），默认 true。强烈推荐在处理验证码时启用。\"\n      required: [\"browser_id\", \"from_x\", \"from_y\", \"to_x\", \"to_y\"]\n\n  browser_hover:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_hover\"\n    description: \"鼠标悬停在元素或坐标上，停留指定时长。支持人类化移动。用于触发悬停菜单、查看 tooltip、触发延迟加载内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"要悬停的元素 CSS 选择器（selector 和坐标二选一）。\"\n        x:\n          type: \"number\"\n          description: \"悬停的 x 坐标（selector 和坐标二选一）。\"\n        y:\n          type: \"number\"\n          description: \"悬停的 y 坐标（selector 和坐标二选一）。\"\n        duration_ms:\n          type: \"integer\"\n          default: 1000\n          description: \"悬停持续时间（毫秒），默认 1000。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。\"\n      required: [\"browser_id\"]\n\n  browser_scroll:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_scroll\"\n    description: \"使用鼠标滚轮滚动页面或指定元素。支持平滑滚动模拟真实用户行为。可以滚动整个页面，也可以滚动指定元素（如滚动容器、iframe 等）。用于查看页面更多内容、触发懒加载、滚动到特定位置等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        delta_y:\n          type: \"integer\"\n          description: \"垂直滚动距离（像素）。正数向下滚动，负数向上滚动。例如：500 向下滚动500像素，-300 向上滚动300像素。\"\n        delta_x:\n          type: \"integer\"\n          default: 0\n          description: \"水平滚动距离（像素），可选，默认 0。正数向右滚动，负数向左滚动。\"\n        selector:\n          type: \"string\"\n          description: \"要滚动的元素 CSS 选择器，可选。不指定则滚动整个页面。指定后会先移动鼠标到该元素，然后滚动该元素。\"\n        smooth:\n          type: \"boolean\"\n          default: true\n          description: \"是否平滑滚动（分多次小步滚动），默认 true。平滑滚动更像真实用户，但稍慢。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否先使用人类化移动鼠标到元素（仅在指定 selector 时有效），默认 true。\"\n      required: [\"browser_id\", \"delta_y\"]\n\n  # ==================== 代码执行工具 ====================\n\n  execute_command:\n    level: 0\n    type: tool_call_agent\n    name: \"execute_command\"\n    description: \"执行命令行命令。可选后台执行并将输出重定向到文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        command:\n          type: \"string\"\n          description: \"要执行的 shell 命令，例如 'ls -la'、'python script.py'、'pip install -r requirements.txt'。\"\n        working_dir:\n          type: \"string\"\n          default: \".\"\n          description: \"命令执行的工作目录相对路径，默认为任务根目录。\"\n        timeout:\n          type: \"integer\"\n          default: 30\n          description: \"命令执行超时时间（秒），默认 30。\"\n        background:\n          type: \"boolean\"\n          default: false\n          description: \"是否后台执行（不阻塞），默认 false。后台执行时必须指定 output_file。\"\n        output_file:\n          type: \"string\"\n          description: \"输出重定向到文件的相对路径。后台执行时必需，非后台执行时可选。\"\n      required: [\"command\"]\n\n  grep:\n    level: 0\n    type: tool_call_agent\n    name: \"grep\"\n    description: \"在文件中搜索匹配的文本模式（跨平台纯Python实现，支持正则表达式）。可以搜索指定目录或文件，支持递归搜索和文件类型过滤。\"\n    parameters:\n      type: \"object\"\n      properties:\n        pattern:\n          type: \"string\"\n          description: \"要搜索的正则表达式模式，例如 'def.*function' 或 'TODO'。\"\n        search_path:\n          type: \"string\"\n          default: \".\"\n          description: \"搜索路径相对路径，默认为当前工作区根目录。\"\n        file_pattern:\n          type: \"string\"\n          default: \"*\"\n          description: \"文件名匹配模式（支持通配符），如 '*.py'、'*.txt'、'*.md' 等。默认匹配所有文件。\"\n        recursive:\n          type: \"boolean\"\n          default: true\n          description: \"是否递归搜索子目录，默认 true。\"\n        case_sensitive:\n          type: \"boolean\"\n          default: true\n          description: \"是否大小写敏感，默认 true。\"\n        show_line_number:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号，默认 true。\"\n        max_results:\n          type: \"integer\"\n          default: 100\n          description: \"最大结果数量，默认 100。\"\n        context_lines:\n          type: \"integer\"\n          default: 0\n          description: \"显示匹配行前后的上下文行数，默认 0（不显示上下文）。\"\n      required: [\"pattern\"]\n\n  # ==================== Skill 工具 ====================\n\n  load_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"load_skill\"\n    description: \"将指定的 Agent Skill 从全局技能库部署到当前 workspace 的 .skills/ 目录，并把对应 SKILL.md 注入当前上下文。部署后可通过 execute_command 运行技能包含的脚本。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要部署的 skill 名称，对应 <available_skills> 中列出的 name。\"\n      required: [\"skill_name\"]\n\n  offload_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"offload_skill\"\n    description: \"从当前上下文中卸载某个已加载 skill 的 SKILL.md 内容，但不删除磁盘上的 .skills 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要从当前上下文中卸载的 skill 名称。\"\n      required: [\"skill_name\"]\n\n  fresh:\n    level: 0\n    type: tool_call_agent\n    name: \"fresh\"\n    description: \"在安全点刷新运行时配置、工具注册、skills 与提示词缓存。默认刷新当前 task；若指定 task_id，则刷新对应 task。这里的 task_id 应为绝对路径。仅当你刚创建/安装了新工具或新 skills 时才使用。\"\n    parameters:\n      type: \"object\"\n      properties:\n        reason:\n          type: \"string\"\n          description: \"触发 fresh 的原因说明，例如“刚安装了新工具”或“刚安装了新 skill”。\"\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时 fresh 当前任务；指定后会 fresh 对应任务，若该任务未在运行则会重载配置并后台 resume。\"\n\n  add_message:\n    level: 0\n    type: tool_call_agent\n    name: \"add_message\"\n    description: \"向指定 task 的 current.instructions 追加一条新消息。若目标 task 正在运行，它会在下一轮看到这条消息；若未运行，可选择后台 resume。task_id 应为绝对路径；省略时默认当前 task。适合对同一任务做需求补充或变更。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n        message:\n          type: \"string\"\n          description: \"要追加给该 task 的消息内容。\"\n        source:\n          type: \"string\"\n          description: \"消息来源标记，例如 agent / user / system。默认 agent。\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n          description: \"当目标 task 当前未运行时，是否在追加消息后后台 resume。默认 false。\"\n      required: [\"message\"]\n\n  start_background_task:\n    level: 0\n    type: tool_call_agent\n    name: \"start_background_task\"\n    description: \"后台启动一个新的 task 进程。适合把独立子任务交给另一个 workspace/task 在后台异步运行。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"必需。新任务的 task_id，建议使用绝对路径作为 workspace。\"\n        user_input:\n          type: \"string\"\n          description: \"必需。新任务的需求描述。\"\n        agent_system:\n          type: \"string\"\n          description: \"可选。Agent system，默认 OpenCowork。\"\n        agent_name:\n          type: \"string\"\n          description: \"可选。启动的 agent 名称，默认 alpha_agent。\"\n        force_new:\n          type: \"boolean\"\n          default: false\n          description: \"是否强制清空该 task 的旧状态后再启动。\"\n        direct_tools:\n          type: \"boolean\"\n          default: true\n          description: \"是否启用 direct-tools。默认 true。\"\n        config:\n          type: \"object\"\n          description: \"可选。类似 SDK 的运行配置。当前支持 llm_config_path、user_data_root、agent_library_dir/library_dir、skills_dir、tools_dir、action_window_steps、thinking_interval、fresh_enabled、fresh_interval_sec、mcp_servers、auto_mode、force_new、direct_tools。\"\n      required: [\"task_id\", \"user_input\"]\n\n  task_share_context_path:\n    level: 0\n    type: tool_call_agent\n    name: \"task_share_context_path\"\n    description: \"返回指定 task 的 share_context 和 stack 文件路径，不直接返回内容。task_id 应为绝对路径；拿到路径后，如有需要请再自行读取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n      required: []\n\n  list_task_ids:\n    level: 0\n    type: tool_call_agent\n    name: \"list_task_ids\"\n    description: \"列出当前已知的 task_id 列表，来源于 share_context 持久化记录。可选只返回当前运行中的 task。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_running:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回当前运行中的 task。默认 false。\"\n      required: []\n\n  # ==================== 框架必需工具 ====================\n\n  final_output:\n    level: 0\n    type: tool_call_agent\n    name: \"final_output\"\n    description: \"智能体输出最终结果的工具。当智能体完成任务或需要终止执行时调用此工具。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        status:\n          type: \"string\"\n          enum: [\"success\", \"error\"]\n          description: \"任务执行状态：'success' 表示成功完成，'error' 表示执行失败。\"\n        output:\n          type: \"string\"\n          description: \"成功或失败的说明。如果输出包含文件，必须提供文件的相对路径和描述（不要重复文件中已有的内容），并包含 judge agent 的反馈。\"\n        error_information:\n          type: \"string\"\n          description: \"错误信息，仅在 status 为 'error' 时必需。\"\n      required: [\"task_id\", \"status\", \"output\"]\n  cheapclaw_read_panel:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_read_panel\"\n    description: \"读取 CheapClaw 的完整消息面板或指定 conversation 的完整面板数据。默认输入不会附带完整 linked_tasks 和完整 bindings；当你需要完整 panel、完整 message_task_bindings、context_summary_path、路径字段、或 service_state 细节时，使用它。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_dirty:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回 dirty=true 的 conversations。\"\n        channel:\n          type: \"string\"\n          description: \"渠道名，例如 telegram / feishu / whatsapp。\"\n        conversation_id:\n          type: \"string\"\n          description: \"会话稳定 ID。\"\n      required: []\n\n  cheapclaw_update_panel:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_update_panel\"\n    description: \"CheapClaw 面板的兜底修正工具。大多数消息写入、task 启动/完成、message_id 绑定、dirty 清理应由系统自动完成；只有当你需要补写 last_reply_summary、手动修正绑定关系、追加特殊 pending_event，或纠正异常状态时才使用它。该工具只返回是否成功和执行了哪些操作，不返回整块 panel。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n          description: \"渠道名。\"\n        conversation_id:\n          type: \"string\"\n          description: \"会话 ID。\"\n        set_dirty:\n          type: \"boolean\"\n          description: \"是否标记该会话为 dirty。\"\n        clear_dirty:\n          type: \"boolean\"\n          description: \"是否清除该会话的 dirty 和 pending_events。\"\n        conversation_patch:\n          type: \"object\"\n          description: \"要直接 merge 到 conversation 上的字段。\"\n        task_id:\n          type: \"string\"\n          description: \"目标 task_id，必须是绝对路径。\"\n        task_patch:\n          type: \"object\"\n          description: \"要 merge 到 linked task 上的字段。\"\n        bind_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。需要绑定到 task_id 的 message_id 列表。用于把具体用户消息明确关联到某个 task。\"\n        binding_note:\n          type: \"string\"\n          description: \"可选。绑定说明，例如“继续昨天的报告任务”或“这是一个新分支 deliverable”。\"\n        binding_type:\n          type: \"string\"\n          description: \"可选。绑定类型，例如 task / direct_reply / forked_task。默认 task。\"\n        append_pending_event:\n          type: \"object\"\n          description: \"要追加到 pending_events 的事件对象。\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_read_social_history:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_read_social_history\"\n    description: \"读取某个渠道会话的社交历史消息。默认只取最近有限条，但你可以通过 limit、message_id 范围或时间范围做分层检索。群聊建议优先读取最近和 bot 相关的消息；如果最近 10 条不足以判断，再扩大到最近 20 条、50 条或指定时间段。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        limit:\n          type: \"integer\"\n          default: 30\n        only_mentions_to_bot:\n          type: \"boolean\"\n          default: false\n        include_bot_replies:\n          type: \"boolean\"\n          default: true\n        from_message_id:\n          type: \"string\"\n        to_message_id:\n          type: \"string\"\n        before_timestamp:\n          type: \"string\"\n        after_timestamp:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_send_message:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_send_message\"\n    description: \"向 CheapClaw 主服务写入一个待发送消息，由主服务异步发送到对应社交平台。若还需要发送本地文件，优先使用 cheapclaw_send_file；此工具也可附带 attachments，但更适合文本回执。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        message:\n          type: \"string\"\n        attachments:\n          type: \"array\"\n          items:\n            type: \"object\"\n          description: \"附件元数据列表，可选。\"\n      required: [\"channel\", \"conversation_id\", \"message\"]\n\n  cheapclaw_send_file:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_send_file\"\n    description: \"向指定社交渠道异步发送一个本地文件。适用于将任务产出的脚本、文档、图片等文件直接发回用户。local_path 必须是当前机器上真实存在的文件绝对路径。若交付结果本质上是一个文件，优先发文件，不要把整段文件内容直接塞进文本消息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n          description: \"渠道名，例如 telegram / feishu / whatsapp。\"\n        conversation_id:\n          type: \"string\"\n          description: \"目标会话 ID。\"\n        local_path:\n          type: \"string\"\n          description: \"要发送的本地文件绝对路径。\"\n        filename:\n          type: \"string\"\n          description: \"可选。对外显示的文件名；不传则使用 local_path 的文件名。\"\n        mime_type:\n          type: \"string\"\n          description: \"可选。文件 MIME 类型；不传则自动猜测。\"\n        kind:\n          type: \"string\"\n          description: \"可选。auto / document / image / video / audio。默认 auto。\"\n        caption:\n          type: \"string\"\n          description: \"可选。文件说明文字。\"\n        message:\n          type: \"string\"\n          description: \"可选。随文件一起发送的额外文本消息。\"\n      required: [\"channel\", \"conversation_id\", \"local_path\"]\n\n  cheapclaw_start_task:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_start_task\"\n    description: \"为指定 conversation 后台启动一个 worker 进程，并自动把它绑定到 CheapClaw 面板。它既可以用于新 task_id，也可以用于旧 task_id，但 task_id 必须显式提供。若要创建全新任务，应先调用 cheapclaw_generate_task_id 生成新的绝对路径 task_id；若要继续同一工作，应直接复用旧 task_id。若传入已经存在的 task_id 且 force_new=false，新的后台执行会继续使用这个 task_id 对应的 workspace、history、share_context 和记忆。对于“同一工作但旧 worker 已结束”的情况，优先使用它并传旧 task_id。只有在明确是全新工作、并行分支或不同 deliverable 时，才应生成新的 task_id。禁止用它启动 CheapClawSupervisor 本身。默认在 CheapClawWorkerGeneral 中使用 worker_agent。只有在 cheapclaw_list_agent_systems 已确认目标 agent_name 存在时才应显式传 agent_name。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        conversation_type:\n          type: \"string\"\n          default: \"group\"\n        display_name:\n          type: \"string\"\n        task_name:\n          type: \"string\"\n        task_id:\n          type: \"string\"\n          description: \"必需。必须是绝对路径。创建新任务前应先调用 cheapclaw_generate_task_id；若传入一个已有 task_id，则会在同一个 task 身份下继续运行，复用该 task 的历史记忆和工作目录。\"\n        user_input:\n          type: \"string\"\n        agent_system:\n          type: \"string\"\n          description: \"目标 agent_system。不能使用 CheapClawSupervisor；主 agent 不允许调用本身。\"\n        agent_name:\n          type: \"string\"\n          description: \"可选。默认不传，CheapClawWorkerGeneral 会自动使用 worker_agent。不要臆造 agent_name。只有在 cheapclaw_list_agent_systems 返回的 agent_names 中确认存在时才传。\"\n        force_new:\n          type: \"boolean\"\n          default: false\n        require_mention:\n          type: \"boolean\"\n          default: true\n        exposed_skills:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。额外追加给该 task 的 skills 名称列表。系统会始终保留默认开放的 skills（当前为 docx、pptx、xlsx、find-skills），这里传入的是在默认集合基础上的增量追加，重复项会自动去重。\"\n        source_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。触发本次启动的用户 message_id 列表。主 agent 应传入，用于把这些用户消息绑定到新 task。\"\n      required: [\"channel\", \"conversation_id\", \"task_name\", \"task_id\", \"user_input\"]\n\n  cheapclaw_add_task_message:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_add_task_message\"\n    description: \"给已有 task_id 追加同一任务语义下的新消息，并自动附加当前时区时间。task_id 必须是绝对路径。它主要用于目标 task 正在运行时的即时需求插入，让运行中的 agent 在后续轮次吸收新要求；也可用于先追加消息再配合 resume/fresh。若旧 task 已经停止，但你只是想在同一个 task_id 下重新起一个后台执行，通常更适合用 cheapclaw_start_task(task_id=旧task_id)。在决定是否追加前，应结合 panel 历史对话、message_task_bindings、最近 final_output 先确认这是不是同一个 deliverable。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        message:\n          type: \"string\"\n        source:\n          type: \"string\"\n          default: \"agent\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n          description: \"目标 task 未运行时，是否在追加消息后尝试恢复。适合你明确要沿用当前 current 指令上下文继续。\"\n        agent_system:\n          type: \"string\"\n        channel:\n          type: \"string\"\n          description: \"可选。若提供，会把 source_message_ids 绑定到这个 conversation 下的 task。\"\n        conversation_id:\n          type: \"string\"\n          description: \"可选。若提供，会把 source_message_ids 绑定到这个 conversation 下的 task。\"\n        source_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。触发这次追加消息的用户 message_id 列表。主 agent 应传入，用于把这些消息绑定到已有 task。\"\n      required: [\"task_id\", \"message\"]\n\n  cheapclaw_get_task_status:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_get_task_status\"\n    description: \"读取指定 task_id 的聚合状态，包括 running、share_context_path、stack_path、last_thinking、last_final_output、log_path 等。任务输入里默认不会附带这些路径与明细；当你需要核验某个 task 的详细状态或文件位置时，用它。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n      required: [\"task_id\"]\n\n  cheapclaw_list_agent_systems:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_agent_systems\"\n    description: \"列出当前 user_data_root 下可用的 agent_system 配置，并返回每个 system 中实际存在的 agent_names。启动任务前应用它确认 agent_name；对 CheapClawWorkerGeneral，默认使用 worker_agent。\"\n    parameters:\n      type: \"object\"\n      properties: {}\n      required: []\n\n  cheapclaw_schedule_plan:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_schedule_plan\"\n    description: \"创建 CheapClaw 计划任务。支持 main_agent 或 task 范围。除了 interval_sec 和 once_at，还支持 daily/weekly 按固定时刻触发，例如每天 08:00 或每周一/三/五 08:00。\"\n    parameters:\n      type: \"object\"\n      properties:\n        name:\n          type: \"string\"\n        scope:\n          type: \"string\"\n          enum: [\"main_agent\", \"task\"]\n        task_id:\n          type: \"string\"\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        interval_sec:\n          type: \"integer\"\n        once_at:\n          type: \"string\"\n        schedule_type:\n          type: \"string\"\n          enum: [\"interval\", \"once\", \"daily\", \"weekly\"]\n        time_of_day:\n          type: \"string\"\n          description: \"用于 daily/weekly，格式 HH:MM，例如 08:00。\"\n        days_of_week:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"用于 weekly，取值如 mon/tue/wed/thu/fri/sat/sun。\"\n        message:\n          type: \"string\"\n        enabled:\n          type: \"boolean\"\n          default: true\n      required: [\"name\", \"scope\"]\n\n  cheapclaw_cancel_plan:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_cancel_plan\"\n    description: \"取消已有的计划任务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        plan_id:\n          type: \"string\"\n      required: [\"plan_id\"]\n\n  cheapclaw_reset_task:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_reset_task\"\n    description: \"重置 task 状态，可选保留 history，并可尝试终止当前 task 的后台进程。task_id 必须是绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        preserve_history:\n          type: \"boolean\"\n          default: true\n        kill_background_processes:\n          type: \"boolean\"\n          default: true\n        reason:\n          type: \"string\"\n      required: [\"task_id\"]\n\n  cheapclaw_generate_task_id:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_generate_task_id\"\n    description: \"按 CheapClaw 规则生成新的绝对路径 task_id。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        task_name:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\", \"task_name\"]\n\n  cheapclaw_list_conversation_tasks:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_conversation_tasks\"\n    description: \"列出某个 conversation 当前已经关联的 tasks，并返回 latest_bound_task_id、running_task_ids、recent_task_ids，以及基于绑定和最近活动生成的 recommended_task_id / recommended_action。注意：recommended_* 只是启发式提示，不是强制结论。主 agent 必须结合 panel 历史、社交消息历史、最近 final_output 和用户最新表达，自行决定是续用旧 task_id 还是新建 task。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_list_global_skills:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_global_skills\"\n    description: \"查看当前全局 skills 主库中的全部可用技能。\"\n    parameters:\n      type: \"object\"\n      properties: {}\n      required: []\n\n  cheapclaw_reveal_skills:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_reveal_skills\"\n    description: \"将指定 skills 追加到某个 task 的可见 skills 白名单中。它不会修改全局 skills 主库；load_skill 仍然从全局主库安装技能。可选执行 fresh 让运行中的任务重新看到这些 skills。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        skill_names:\n          type: \"array\"\n          items:\n            type: \"string\"\n        run_fresh:\n          type: \"boolean\"\n          default: false\n      required: [\"task_id\", \"skill_names\"]\n"
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawSupervisor/level_3_agents.yaml",
    "content": "tools:\n  supervisor_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - cheapclaw_read_panel\n      - cheapclaw_update_panel\n      - cheapclaw_read_social_history\n      - cheapclaw_send_message\n      - cheapclaw_send_file\n      - cheapclaw_start_task\n      - cheapclaw_add_task_message\n      - cheapclaw_get_task_status\n      - cheapclaw_list_agent_systems\n      - cheapclaw_schedule_plan\n      - cheapclaw_cancel_plan\n      - cheapclaw_reset_task\n      - cheapclaw_generate_task_id\n      - cheapclaw_list_conversation_tasks\n      - cheapclaw_list_global_skills\n      - cheapclaw_reveal_skills\n      - file_read\n      - task_share_context_path\n      - load_skill\n      - offload_skill\n      - fresh\n      - final_output\n      - execute_command\n    max_turns: 80\n    execution_model: openai/google/gemini-3-flash-preview\n    thinking_model: openai/google/gemini-3-flash-preview\n    compressor_model: openai/google/gemini-3-flash-preview\n    image_generation_model: openai/google/gemini-3-flash-preview\n    read_figure_model: openai/google/gemini-3-flash-preview\n    max_tokens: 0\n    action_window_steps: 20\n    thinking_interval: 20\n    prompts:\n      agent_responsibility: |\n        你是 CheapClaw 的总调度智能体。你负责会话消息判断、历史 task 路由、message_id 到 task_id 绑定、worker 派发、watchdog 处理和用户回执。你可以使用execute_command查看电脑的目录结构，安排 task_id。\n      agent_workflow: |\n        对每个 dirty conversation，先判断直接回复还是需要任务；如果是任务型消息，应先尽快发一条简短回执；然后必须先调用 cheapclaw_list_conversation_tasks，再结合 panel 和 social history 自己判断该继续哪个旧 task。若旧 task 正在运行，优先 cheapclaw_add_task_message；若旧 task 已停止但仍是同一工作，优先 cheapclaw_start_task(task_id=旧task_id)；只有明确是新 deliverable 或并行分支时才新建 task_id。随后必须把相关 message_id 绑定到对应 task_id，并更新面板。\n    name: \"supervisor_agent\"\n    description: \"CheapClaw 主调度智能体\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        task_input:\n          type: \"string\"\n      required: [\"task_id\", \"task_input\"]\n"
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawWorkerGeneral/general_prompts.yaml",
    "content": "system_prompt_xml: |\n  <系统角色>\n  你是 CheapClawWorkerGeneral 系统中的后台 worker。你负责完成被分派给当前 task_id 的具体工作。\n  </系统角色>\n\n  <工作空间与路径>\n  你明确处在当前 task_id 对应的工作空间中。大多数文件类工具都应传相对路径；task_id 参数则必须是绝对路径。\n  你需要继承并利用同一 task_id 下积累的历史信息、share_context、history 和文件空间，而不是把每次补充消息都当成全新任务。\n  </工作空间与路径>\n\n  <连续任务语义>\n  当前 task 可能已经绑定多条用户消息，这些消息共同定义同一工作的连续需求变化。\n  你必须把最新用户消息与历史工作结果一起理解：\n  - 如果新消息是增量修改，就在现有成果上继续推进。\n  - 如果新消息修正了目标，要基于最新目标调整计划，但不要无故丢掉已有有效产出。\n  - 只有当当前 task 明显不适合承接该目标时，才在 final_output 中说明应由 supervisor 分叉新 task。\n  </连续任务语义>\n\n  <技能与扩展>\n  当前 task 只能看到被允许的 overlay skills。\n  如果你判断现有 skills 不够，可以：\n  1. 使用 cheapclaw_list_global_skills 查看主技能库\n  2. 使用 cheapclaw_reveal_skills 把需要的 skill 暴露给当前 task\n  3. 再 fresh 当前 task 继续工作\n  不要假设某个 skill 已经可见，先检查再揭开。\n  </技能与扩展>\n\n  <执行原则>\n  - 尽量复用当前 task 目录中的已有材料和中间结果。\n  - 长时间命令必须后台运行并写日志，不要把当前进程挂死。\n  - 需要外部命令时优先可恢复、可观察、可复用的方式。\n  - 如果你判断任务当前无法完成，应在 final_output 中明确说明阻塞点和建议，而不是无意义循环。\n  </执行原则>\n\n  <输出要求>\n  任务完成时必须使用 final_output。\n  output 中应说明：\n  - 完成了什么\n  - 最终文件路径\n  - 关键中间文件路径\n  - 若未完成，阻塞原因是什么\n  不要把大段文件内容直接粘贴进 output。\n  </输出要求>\n"
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawWorkerGeneral/level_0_tools.yaml",
    "content": "tools:\n  # ==================== 文件操作工具 ====================\n  \n  file_read:\n    level: 0\n    type: tool_call_agent\n    name: \"file_read\"\n    description: \"读取指定文本文件的内容。路径参数必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。可以读取单个或多个文件，也可以指定起始和结束行。默认返回带行号的 JSON 格式。警告：不要读取二进制文件（如 pdf、docx、图片等）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"文件相对路径数组，基于当前 workspace/task 根目录解析。单个文件传 ['file.txt']，多个文件传 ['file1.txt', 'file2.txt']。不要传绝对路径；只允许读取文本文件，不要读取二进制文件。\"\n        start_line:\n          type: \"integer\"\n          description: \"读取起始行号（从1开始），可选。多文件模式下应用于所有文件。\"\n        end_line:\n          type: \"integer\"\n          description: \"读取结束行号（包含），可选。多文件模式下应用于所有文件。\"\n        encoding:\n          type: \"string\"\n          description: \"文件编码，可选。不指定时自动检测。\"\n        show_line_numbers:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号。true 返回 JSON 格式（含行号），false 返回纯文本。默认 true。\"\n      required: [\"path\"]\n\n  file_write:\n    level: 0\n    type: tool_call_agent\n    name: \"file_write\"\n    description: \"向指定文本文件写入内容。path 必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。如果文件不存在会自动创建；如果存在可以选择覆盖或追加，也支持替换指定行。注意：禁止写入 reference.bib 文件，请使用专门的参考文献管理工具（reference_add/reference_delete）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"文件的相对路径，例如 'src/main.py'，相对于当前 workspace/task 根目录解析。不要传绝对路径。写入前建议使用目录列表工具检查是否有同名文件，避免覆盖他人文件。禁止路径为 'reference.bib'。\"\n        content:\n          type: \"string\"\n          description: \"要写入的文本内容。\"\n        mode:\n          type: \"string\"\n          enum: [\"write\", \"append\"]\n          default: \"write\"\n          description: \"写入模式。'write' 覆盖整个文件，'append' 追加到文件末尾。\"\n        start_line:\n          type: \"integer\"\n          description: \"行替换模式 - 起始行号（从1开始），可选。\"\n        end_line:\n          type: \"integer\"\n          description: \"行替换模式 - 结束行号，可选。\"\n      required: [\"path\", \"content\"]\n  \n  dir_list:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_list\"\n    description: \"列出指定目录的内容。path 必须是相对于当前 workspace/task 根目录的相对路径；不传时默认列出任务根目录。可以递归列出所有子目录和文件（自动排除 code_env 目录）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          default: \".\"\n          description: \"要列出的目录相对路径，相对于当前 workspace/task 根目录解析。不指定时列出任务根目录。\"\n        recursive:\n          type: \"boolean\"\n          default: false\n          description: \"是否递归列出子目录，默认 false。\"\n      required: []\n\n  dir_create:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_create\"\n    description: \"创建新目录。path 必须是相对于当前 workspace/task 根目录的相对路径。如果父目录不存在会自动创建。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要创建的目录相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  file_move:\n    level: 0\n    type: tool_call_agent\n    name: \"file_move\"\n    description: \"移动或复制文件/目录。source 和 destination 都应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source:\n          # type: \"string\"\n          # description: \"源文件或目录的相对路径。\"\n          # path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"源文件或目录的相对路径组，相对于当前 workspace/task 根目录解析。可以单个或多个。\"\n        destination:\n          type: \"string\"\n          description: \"目标相对路径，相对于当前 workspace/task 根目录解析。\"\n        copy:\n          type: \"boolean\"\n          default: false\n          description: \"是否复制（保留原文件），默认 false（移动）。\"\n      required: [\"source\", \"destination\"]\n\n  file_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"file_delete\"\n    description: \"删除指定的文件或目录。path 应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要删除的文件或目录的相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  # ==================== 网络工具 ====================\n\n  web_search:\n    level: 0\n    type: tool_call_agent\n    name: \"web_search\"\n    description: \"使用 DuckDuckGo 进行网络搜索。结果会保存为 Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或问题。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件），请保存在 temp/web_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  google_scholar_search:\n    level: 0\n    type: tool_call_agent\n    name: \"google_scholar_search\"\n    description: \"在 Google Scholar 上搜索学术论文。支持年份筛选和分页。搜索结果保存为 Markdown 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或主题。\"\n        year_low:\n          type: \"integer\"\n          description: \"筛选论文的起始年份，可选。\"\n        year_high:\n          type: \"integer\"\n          description: \"筛选论文的结束年份，可选。\"\n        pages:\n          type: \"integer\"\n          default: 1\n          description: \"爬取的搜索结果页数，每页约10篇论文。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件)。请保存在 temp/scholar_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  arxiv_search:\n    level: 0\n    type: tool_call_agent\n    name: \"arxiv_search\"\n    description: \"搜索 arXiv 预印本论文库。返回论文标题、作者、摘要、PDF 下载地址等信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词，例如 'transformer neural network'。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        sort_by:\n          type: \"string\"\n          enum: [\"relevance\", \"lastUpdatedDate\", \"submittedDate\"]\n          default: \"relevance\"\n          description: \"排序方式：relevance（相关性）、lastUpdatedDate（更新时间）、submittedDate（提交时间）。\"\n        sort_order:\n          type: \"string\"\n          enum: [\"descending\", \"ascending\"]\n          default: \"descending\"\n          description: \"排序顺序：descending（降序）、ascending（升序）。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件）。请保存在 temp/arxiv_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  crawl_page:\n    level: 0\n    type: tool_call_agent\n    name: \"crawl_page\"\n    description: \"爬取指定 URL 的网页内容，转换为 Markdown 格式。使用 crawl4ai 智能提取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要爬取的网页完整 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存 Markdown 文件的相对路径，必选。不指定则直接返回内容。请保存在 temp/crawl_page目录中。\"\n        download_images:\n          type: \"boolean\"\n          default: false\n          description: \"是否下载图片，默认 false（移除图片）。\"\n      required: [\"url\",\"save_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 参考文献管理工具 ====================\n\n  reference_list:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_list\"\n    description: \"列出 reference.bib 文件中的所有参考文献（显示原文）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: []\n\n  reference_add:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_add\"\n    description: \"向 reference.bib 添加参考文献。如果引用键已存在则覆盖原有内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        entries:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考文献字符串数组，每个元素是一条完整的bib条目。例如：['@article{key1,...}', '@book{key2,...}']\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"entries\"]\n\n  reference_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_delete\"\n    description: \"从 reference.bib 删除指定的参考文献。\"\n    parameters:\n      type: \"object\"\n      properties:\n        keys:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"要删除的引用键（如 'sun2023blockchain'）或引用键数组。\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"keys\"]\n\n  # ==================== 文档处理工具 ====================\n\n  parse_document:\n    level: 0\n    type: tool_call_agent\n    name: \"parse_document\"\n    description: \"解析二进制文档为纯文本文件，不提供总结，分析服务。支持 PDF、Word、Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要解析的文档相对路径。\"\n        save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径。请保存在 temp/parse_document目录中。\"\n      required: [\"path\",\"save_path\"]\n\n  vision_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"vision_tool\"\n    description: \"使用LLM Vision模型分析图片内容。可以识别图片中的内容、描述场景、回答问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_path:\n          type: \"string\"\n          description: \"图片文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这是什么？'或'请描述图片中的内容'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"必选，保存结果的相对路径,保存为纯文本文件 md或者 txt。请保存在 temp/answer_figuers目录中。\"\n        # model:\n        #   type: \"string\"\n        #   description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"image_path\",\"save_path\"]\n\n  image_read:\n    level: 0\n    type: tool_call_agent\n    name: \"image_read\"\n    description: \"读取并分析图片内容（支持同时读取多张）。如果主模型支持多模态，图片会直接嵌入到对话中由主模型分析；否则会调用 Vision LLM 进行分析并返回文字描述。适用于查看实验结果图表、分析截图、理解图片内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径数组（相对于任务目录）。读取单张图片传单元素数组，如 [\\\"result.png\\\"]。支持 jpg/jpeg/png/gif/webp/bmp 格式。\"\n        query:\n          type: \"string\"\n          description: \"关于图片的问题或分析要求，例如'这些图表显示了什么趋势？'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"可选，保存分析结果的相对路径（仅在 text-only 模式下有效）。\"\n      required: [\"image_paths\"]\n\n  create_image:\n    level: 0\n    type: tool_call_agent\n    name: \"create_image\"\n    description: \"根据提示词生成图片，或基于参考图进行图片编辑/融合/风格迁移。支持最多 14 张参考图（Gemini 3 Pro）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        prompt:\n          type: \"string\"\n          description: \"图片的描述提示词或编辑指令。纯生成时描述要生成的图片；有参考图时描述如何处理参考图（如'融合这两张图'、'将第一张图转为梵高风格'）。\"\n        image_path:\n          type: \"string\"\n          description: \"生成图片保存的相对路径（例如 'temp/generated_image.png'）。\"\n        reference_images:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考图片相对路径列表，可选。用于图片编辑、风格迁移、多图融合等。不提供则为纯文本生成图片。\"\n        size:\n          type: \"string\"\n          default: \"1024x1024\"\n          description: \"生成图片尺寸，默认 '1024x1024'。支持 '1792x1024'（16:9）等。\"\n        n:\n          type: \"integer\"\n          default: 1\n          description: \"生成图片数量，默认 1。\"\n      required: [\"prompt\", \"image_path\"]\n\n  audio_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"audio_tool\"\n    description: \"使用LLM Audio模型分析音频内容。可以识别音频中的内容、描述场景、回答问题等。支持 mp3、wav、m4a 等格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        audio_path:\n          type: \"string\"\n          description: \"音频文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这段音频讲了什么？'或'请描述音频内容'。不指定则默认描述音频内容。\"\n        model:\n          type: \"string\"\n          description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"audio_path\"]\n\n  paper_analyze_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"paper_analyze_tool\"\n    description: \"解析论文文档并使用LLM分析论文内容。可以总结论文、回答关于论文的问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        paper_path:\n          type: \"string\"\n          description: \"论文文件的相对路径（相对于任务目录），支持PDF、Word等格式。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这篇论文的主要贡献是什么？'不指定则默认总结论文内容。\"\n        parse_save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径，可选。\"\n      required: [\"paper_path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从指定 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 文档处理工具 ====================\n\n  # parse_document:\n  #   level: 0\n  #   type: tool_call_agent\n  #   name: \"parse_document\"\n  #   description: \"解析文档文件并提取文本内容。支持 PDF、Word、Markdown 格式。使用 pdfplumber 高质量提取 PDF（包含表格）。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       path:\n  #         type: \"string\"\n  #         description: \"要解析的文档相对路径。\"\n  #       save_path:\n  #         type: \"string\"\n  #         description: \"保存解析结果的相对路径，可选。不指定则直接返回内容。\"\n  #     required: [\"path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  images_to_ppt:\n    level: 0\n    type: tool_call_agent\n    name: \"images_to_ppt\"\n    description: \"将多张图片转换为 PowerPoint 演示文稿，每张图片占一页。PPT 尺寸自动根据第一张图片的宽高比设置，所有图片居中显示并保持比例。适合将多张图表、截图等快速制作成演示文稿。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径列表，例如 ['chart1.png', 'chart2.png']。也可以是单个字符串。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PPT 文件的相对路径，例如 'presentation.pptx'。\"\n      required: [\"image_paths\", \"output_path\"]\n\n  # ==================== 浏览器操作工具 ====================\n\n  browser_launch:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_launch\"\n    description: \"启动浏览器会话。默认打开有界面的浏览器窗口（非无头模式），创建第一个标签页 page_0。返回 browser_id 用于后续操作。会自动创建 temp/browser/{browser_id}/ 目录保存截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        headless:\n          type: \"boolean\"\n          default: false\n          description: \"是否无头模式（不显示浏览器窗口），默认 false（显示窗口）。\"\n        width:\n          type: \"integer\"\n          default: 1280\n          description: \"浏览器窗口宽度（像素），默认 1280。\"\n        height:\n          type: \"integer\"\n          default: 800\n          description: \"浏览器窗口高度（像素），默认 800。\"\n      required: []\n\n  browser_close:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close\"\n    description: \"关闭浏览器会话。会关闭所有标签页并清理资源。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID（由 browser_launch 返回）。\"\n      required: [\"browser_id\"]\n\n  browser_navigate:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_navigate\"\n    description: \"在当前活跃标签页导航到指定 URL。导航后自动截图并保存页面内容到 temp/browser/{browser_id}/current.png 和 page_content.md。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        url:\n          type: \"string\"\n          description: \"目标 URL，例如 'https://www.example.com'。\"\n        wait_until:\n          type: \"string\"\n          enum: [\"load\", \"domcontentloaded\", \"networkidle\"]\n          default: \"load\"\n          description: \"等待条件：load（页面加载完成）、domcontentloaded（DOM加载完成）、networkidle（网络空闲）。默认 load。\"\n      required: [\"browser_id\", \"url\"]\n\n  browser_snapshot:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_snapshot\"\n    description: \"获取当前活跃标签页的快照。更新截图和页面文本内容。返回页面标题、URL、截图路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        include_html:\n          type: \"boolean\"\n          default: false\n          description: \"是否包含 HTML 源码，默认 false。如果为 true，会保存到 page_source.html。\"\n      required: [\"browser_id\"]\n\n  browser_execute_js:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_execute_js\"\n    description: \"在当前活跃标签页执行 JavaScript 代码。这是最强大的浏览器操作工具，可以实现任意页面操作（点击、输入、滚动、提取数据等）。执行后自动截图。注意：JavaScript 代码必须是函数表达式，如 '() => { return document.title; }'。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        script:\n          type: \"string\"\n          description: \"要执行的 JavaScript 代码。必须是函数表达式，如 '() => { ... }'。示例：'() => document.querySelector(\\\"#btn\\\").click()' 或 '() => { return Array.from(document.querySelectorAll(\\\".item\\\")).map(el => el.textContent); }'。\"\n        save_result:\n          type: \"boolean\"\n          default: false\n          description: \"是否将执行结果保存到 js_result.json 文件，默认 false。\"\n      required: [\"browser_id\", \"script\"]\n\n  browser_new_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_new_page\"\n    description: \"在当前浏览器会话中新建一个标签页。新标签页会自动成为活跃页面。返回新的 page_id（如 page_1, page_2）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_switch_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_switch_page\"\n    description: \"切换到指定的标签页，使其成为活跃页面。切换后会自动更新截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要切换到的页面ID，例如 'page_0', 'page_1'。可通过 browser_list_pages 查看所有页面。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_close_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close_page\"\n    description: \"关闭指定的标签页。如果关闭的是活跃页面，会自动切换到第一个页面。不能关闭唯一的标签页（至少保留一个）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要关闭的页面ID，例如 'page_1'。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_list_pages:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_list_pages\"\n    description: \"列出当前浏览器会话的所有标签页。显示每个页面的 page_id、标题、URL、是否为活跃页面。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_click:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_click\"\n    description: \"点击当前页面的指定元素。使用 CSS 选择器定位元素。点击后自动截图。如果元素难以点击，建议使用 browser_execute_js 执行 JavaScript 点击。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器，例如 '#submit-btn', '.button', 'button[type=\\\"submit\\\"]'。\"\n        timeout:\n          type: \"integer\"\n          default: 5000\n          description: \"等待元素出现的超时时间（毫秒），默认 5000。\"\n      required: [\"browser_id\", \"selector\"]\n\n  browser_type:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_type\"\n    description: \"在指定的输入框输入文本。使用 CSS 选择器定位输入框。输入后自动截图。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"输入框的 CSS 选择器，例如 '#username', 'input[name=\\\"email\\\"]'。\"\n        text:\n          type: \"string\"\n          description: \"要输入的文本内容。\"\n        clear_first:\n          type: \"boolean\"\n          default: true\n          description: \"是否先清空输入框，默认 true。\"\n      required: [\"browser_id\", \"selector\", \"text\"]\n\n  browser_wait:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_wait\"\n    description: \"等待指定条件满足。可以等待元素出现、页面导航完成或指定时间。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        wait_type:\n          type: \"string\"\n          enum: [\"selector\", \"navigation\", \"timeout\"]\n          description: \"等待类型：selector（等待元素出现）、navigation（等待导航完成）、timeout（等待指定时间）。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器（wait_type='selector' 时必需）。\"\n        timeout:\n          type: \"integer\"\n          default: 30000\n          description: \"超时时间（毫秒），默认 30000。\"\n        milliseconds:\n          type: \"integer\"\n          description: \"等待时长（毫秒，wait_type='timeout' 时必需）。\"\n      required: [\"browser_id\", \"wait_type\"]\n\n  browser_mouse_move:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_move\"\n    description: \"移动鼠标到指定坐标位置。支持人类化移动（贝塞尔曲线轨迹）模拟真实用户行为，避免人机验证检测。适用于需要精确控制鼠标位置的场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。设为 false 则直接瞬移到目标位置。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_mouse_click_coords:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_click_coords\"\n    description: \"在指定坐标位置点击鼠标。支持左键/右键/中键、单击/双击、人类化点击（随机延迟和轨迹）。适用于动态元素、Canvas/SVG 区域、无法用选择器定位的元素。特别适合处理滑块验证码等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"点击的 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"点击的 y 坐标（像素）。\"\n        button:\n          type: \"string\"\n          enum: [\"left\", \"right\", \"middle\"]\n          default: \"left\"\n          description: \"鼠标按钮：left（左键）、right（右键）、middle（中键），默认 left。\"\n        click_count:\n          type: \"integer\"\n          default: 1\n          description: \"点击次数，1为单击，2为双击，默认 1。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化点击（贝塞尔曲线移动+随机延迟），默认 true。推荐在需要绕过人机验证时启用。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_drag_and_drop:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_drag_and_drop\"\n    description: \"执行鼠标拖拽操作，从起点拖动到终点。支持人类化拖拽（贝塞尔曲线轨迹+随机延迟）模拟真实用户行为。主要用于：1) 滑块验证码（重要！）2) 拖拽排序 3) 地图平移/缩放 4) 拖拽文件上传 5) 任何需要拖拽的交互。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        from_x:\n          type: \"number\"\n          description: \"起始 x 坐标（像素）。\"\n        from_y:\n          type: \"number\"\n          description: \"起始 y 坐标（像素）。\"\n        to_x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        to_y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化拖拽（贝塞尔曲线轨迹+随机延迟），默认 true。强烈推荐在处理验证码时启用。\"\n      required: [\"browser_id\", \"from_x\", \"from_y\", \"to_x\", \"to_y\"]\n\n  browser_hover:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_hover\"\n    description: \"鼠标悬停在元素或坐标上，停留指定时长。支持人类化移动。用于触发悬停菜单、查看 tooltip、触发延迟加载内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"要悬停的元素 CSS 选择器（selector 和坐标二选一）。\"\n        x:\n          type: \"number\"\n          description: \"悬停的 x 坐标（selector 和坐标二选一）。\"\n        y:\n          type: \"number\"\n          description: \"悬停的 y 坐标（selector 和坐标二选一）。\"\n        duration_ms:\n          type: \"integer\"\n          default: 1000\n          description: \"悬停持续时间（毫秒），默认 1000。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。\"\n      required: [\"browser_id\"]\n\n  browser_scroll:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_scroll\"\n    description: \"使用鼠标滚轮滚动页面或指定元素。支持平滑滚动模拟真实用户行为。可以滚动整个页面，也可以滚动指定元素（如滚动容器、iframe 等）。用于查看页面更多内容、触发懒加载、滚动到特定位置等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        delta_y:\n          type: \"integer\"\n          description: \"垂直滚动距离（像素）。正数向下滚动，负数向上滚动。例如：500 向下滚动500像素，-300 向上滚动300像素。\"\n        delta_x:\n          type: \"integer\"\n          default: 0\n          description: \"水平滚动距离（像素），可选，默认 0。正数向右滚动，负数向左滚动。\"\n        selector:\n          type: \"string\"\n          description: \"要滚动的元素 CSS 选择器，可选。不指定则滚动整个页面。指定后会先移动鼠标到该元素，然后滚动该元素。\"\n        smooth:\n          type: \"boolean\"\n          default: true\n          description: \"是否平滑滚动（分多次小步滚动），默认 true。平滑滚动更像真实用户，但稍慢。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否先使用人类化移动鼠标到元素（仅在指定 selector 时有效），默认 true。\"\n      required: [\"browser_id\", \"delta_y\"]\n\n  # ==================== 代码执行工具 ====================\n\n  execute_command:\n    level: 0\n    type: tool_call_agent\n    name: \"execute_command\"\n    description: \"执行命令行命令。可选后台执行并将输出重定向到文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        command:\n          type: \"string\"\n          description: \"要执行的 shell 命令，例如 'ls -la'、'python script.py'、'pip install -r requirements.txt'。\"\n        working_dir:\n          type: \"string\"\n          default: \".\"\n          description: \"命令执行的工作目录相对路径，默认为任务根目录。\"\n        timeout:\n          type: \"integer\"\n          default: 30\n          description: \"命令执行超时时间（秒），默认 30。\"\n        background:\n          type: \"boolean\"\n          default: false\n          description: \"是否后台执行（不阻塞），默认 false。后台执行时必须指定 output_file。\"\n        output_file:\n          type: \"string\"\n          description: \"输出重定向到文件的相对路径。后台执行时必需，非后台执行时可选。\"\n      required: [\"command\"]\n\n  grep:\n    level: 0\n    type: tool_call_agent\n    name: \"grep\"\n    description: \"在文件中搜索匹配的文本模式（跨平台纯Python实现，支持正则表达式）。可以搜索指定目录或文件，支持递归搜索和文件类型过滤。\"\n    parameters:\n      type: \"object\"\n      properties:\n        pattern:\n          type: \"string\"\n          description: \"要搜索的正则表达式模式，例如 'def.*function' 或 'TODO'。\"\n        search_path:\n          type: \"string\"\n          default: \".\"\n          description: \"搜索路径相对路径，默认为当前工作区根目录。\"\n        file_pattern:\n          type: \"string\"\n          default: \"*\"\n          description: \"文件名匹配模式（支持通配符），如 '*.py'、'*.txt'、'*.md' 等。默认匹配所有文件。\"\n        recursive:\n          type: \"boolean\"\n          default: true\n          description: \"是否递归搜索子目录，默认 true。\"\n        case_sensitive:\n          type: \"boolean\"\n          default: true\n          description: \"是否大小写敏感，默认 true。\"\n        show_line_number:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号，默认 true。\"\n        max_results:\n          type: \"integer\"\n          default: 100\n          description: \"最大结果数量，默认 100。\"\n        context_lines:\n          type: \"integer\"\n          default: 0\n          description: \"显示匹配行前后的上下文行数，默认 0（不显示上下文）。\"\n      required: [\"pattern\"]\n\n  # ==================== Skill 工具 ====================\n\n  load_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"load_skill\"\n    description: \"将指定的 Agent Skill 从全局技能库部署到当前 workspace 的 .skills/ 目录，并把对应 SKILL.md 注入当前上下文。部署后可通过 execute_command 运行技能包含的脚本。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要部署的 skill 名称，对应 <available_skills> 中列出的 name。\"\n      required: [\"skill_name\"]\n\n  offload_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"offload_skill\"\n    description: \"从当前上下文中卸载某个已加载 skill 的 SKILL.md 内容，但不删除磁盘上的 .skills 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要从当前上下文中卸载的 skill 名称。\"\n      required: [\"skill_name\"]\n\n  fresh:\n    level: 0\n    type: tool_call_agent\n    name: \"fresh\"\n    description: \"在安全点刷新运行时配置、工具注册、skills 与提示词缓存。默认刷新当前 task；若指定 task_id，则刷新对应 task。这里的 task_id 应为绝对路径。仅当你刚创建/安装了新工具或新 skills 时才使用。\"\n    parameters:\n      type: \"object\"\n      properties:\n        reason:\n          type: \"string\"\n          description: \"触发 fresh 的原因说明，例如“刚安装了新工具”或“刚安装了新 skill”。\"\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时 fresh 当前任务；指定后会 fresh 对应任务，若该任务未在运行则会重载配置并后台 resume。\"\n\n  add_message:\n    level: 0\n    type: tool_call_agent\n    name: \"add_message\"\n    description: \"向指定 task 的 current.instructions 追加一条新消息。若目标 task 正在运行，它会在下一轮看到这条消息；若未运行，可选择后台 resume。task_id 应为绝对路径；省略时默认当前 task。适合对同一任务做需求补充或变更。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n        message:\n          type: \"string\"\n          description: \"要追加给该 task 的消息内容。\"\n        source:\n          type: \"string\"\n          description: \"消息来源标记，例如 agent / user / system。默认 agent。\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n          description: \"当目标 task 当前未运行时，是否在追加消息后后台 resume。默认 false。\"\n      required: [\"message\"]\n\n  start_background_task:\n    level: 0\n    type: tool_call_agent\n    name: \"start_background_task\"\n    description: \"后台启动一个新的 task 进程。适合把独立子任务交给另一个 workspace/task 在后台异步运行。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"必需。新任务的 task_id，建议使用绝对路径作为 workspace。\"\n        user_input:\n          type: \"string\"\n          description: \"必需。新任务的需求描述。\"\n        agent_system:\n          type: \"string\"\n          description: \"可选。Agent system，默认 OpenCowork。\"\n        agent_name:\n          type: \"string\"\n          description: \"可选。启动的 agent 名称，默认 alpha_agent。\"\n        force_new:\n          type: \"boolean\"\n          default: false\n          description: \"是否强制清空该 task 的旧状态后再启动。\"\n        direct_tools:\n          type: \"boolean\"\n          default: true\n          description: \"是否启用 direct-tools。默认 true。\"\n        config:\n          type: \"object\"\n          description: \"可选。类似 SDK 的运行配置。当前支持 llm_config_path、user_data_root、agent_library_dir/library_dir、skills_dir、tools_dir、action_window_steps、thinking_interval、fresh_enabled、fresh_interval_sec、mcp_servers、auto_mode、force_new、direct_tools。\"\n      required: [\"task_id\", \"user_input\"]\n\n  task_share_context_path:\n    level: 0\n    type: tool_call_agent\n    name: \"task_share_context_path\"\n    description: \"返回指定 task 的 share_context 和 stack 文件路径，不直接返回内容。task_id 应为绝对路径；拿到路径后，如有需要请再自行读取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n      required: []\n\n  list_task_ids:\n    level: 0\n    type: tool_call_agent\n    name: \"list_task_ids\"\n    description: \"列出当前已知的 task_id 列表，来源于 share_context 持久化记录。可选只返回当前运行中的 task。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_running:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回当前运行中的 task。默认 false。\"\n      required: []\n\n  # ==================== 框架必需工具 ====================\n\n  final_output:\n    level: 0\n    type: tool_call_agent\n    name: \"final_output\"\n    description: \"智能体输出最终结果的工具。当智能体完成任务或需要终止执行时调用此工具。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        status:\n          type: \"string\"\n          enum: [\"success\", \"error\"]\n          description: \"任务执行状态：'success' 表示成功完成，'error' 表示执行失败。\"\n        output:\n          type: \"string\"\n          description: \"成功或失败的说明。如果输出包含文件，必须提供文件的相对路径和描述（不要重复文件中已有的内容），并包含 judge agent 的反馈。\"\n        error_information:\n          type: \"string\"\n          description: \"错误信息，仅在 status 为 'error' 时必需。\"\n      required: [\"task_id\", \"status\", \"output\"]\n  cheapclaw_read_panel:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_read_panel\"\n    description: \"读取 CheapClaw 消息面板。可只读取 dirty 会话，或读取指定 channel / conversation_id 的会话。当你需要完整 message_task_bindings、context_summary_path 或完整 linked_tasks 时使用。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_dirty:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回 dirty=true 的 conversations。\"\n        channel:\n          type: \"string\"\n          description: \"渠道名，例如 telegram / feishu / whatsapp。\"\n        conversation_id:\n          type: \"string\"\n          description: \"会话稳定 ID。\"\n      required: []\n\n  cheapclaw_update_panel:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_update_panel\"\n    description: \"CheapClaw 面板的兜底修正工具。大多数消息写入、task 启动/完成、message_id 绑定、dirty 清理应由系统自动完成；只有当你需要补写 last_reply_summary、手动修正绑定关系、追加特殊 pending_event，或纠正异常状态时才使用它。该工具只返回是否成功和执行了哪些操作，不返回整块 panel。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n          description: \"渠道名。\"\n        conversation_id:\n          type: \"string\"\n          description: \"会话 ID。\"\n        set_dirty:\n          type: \"boolean\"\n          description: \"是否标记该会话为 dirty。\"\n        clear_dirty:\n          type: \"boolean\"\n          description: \"是否清除该会话的 dirty 和 pending_events。\"\n        conversation_patch:\n          type: \"object\"\n          description: \"要直接 merge 到 conversation 上的字段。\"\n        task_id:\n          type: \"string\"\n          description: \"目标 task_id，必须是绝对路径。\"\n        task_patch:\n          type: \"object\"\n          description: \"要 merge 到 linked task 上的字段。\"\n        bind_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。需要绑定到 task_id 的 message_id 列表。用于把具体用户消息明确关联到某个 task。\"\n        binding_note:\n          type: \"string\"\n          description: \"可选。绑定说明，例如“继续昨天的报告任务”或“这是一个新分支 deliverable”。\"\n        binding_type:\n          type: \"string\"\n          description: \"可选。绑定类型，例如 task / direct_reply / forked_task。默认 task。\"\n        append_pending_event:\n          type: \"object\"\n          description: \"要追加到 pending_events 的事件对象。\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_read_social_history:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_read_social_history\"\n    description: \"读取某个渠道会话的社交历史消息。默认只取最近有限条，但可通过 limit、message_id 范围或时间范围做分层检索。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        limit:\n          type: \"integer\"\n          default: 30\n        only_mentions_to_bot:\n          type: \"boolean\"\n          default: false\n        include_bot_replies:\n          type: \"boolean\"\n          default: true\n        from_message_id:\n          type: \"string\"\n        to_message_id:\n          type: \"string\"\n        before_timestamp:\n          type: \"string\"\n        after_timestamp:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_send_message:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_send_message\"\n    description: \"向 CheapClaw 主服务写入一个待发送消息，由主服务异步发送到对应社交平台。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        message:\n          type: \"string\"\n        attachments:\n          type: \"array\"\n          items:\n            type: \"object\"\n          description: \"附件元数据列表，可选。\"\n      required: [\"channel\", \"conversation_id\", \"message\"]\n\n  cheapclaw_start_task:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_start_task\"\n    description: \"为指定 conversation 后台启动新的 worker task，并自动把它绑定到 CheapClaw 面板。task_id 必须显式提供。创建新任务前应先调用 cheapclaw_generate_task_id；继续同一工作时应直接复用旧 task_id。可指定 agent_system、agent_name、task_id 和允许暴露的 skills。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        conversation_type:\n          type: \"string\"\n          default: \"group\"\n        display_name:\n          type: \"string\"\n        task_name:\n          type: \"string\"\n        task_id:\n          type: \"string\"\n          description: \"必需。必须是绝对路径。创建新任务前应先调用 cheapclaw_generate_task_id；继续同一工作时应直接复用旧 task_id。\"\n        user_input:\n          type: \"string\"\n        agent_system:\n          type: \"string\"\n        agent_name:\n          type: \"string\"\n        force_new:\n          type: \"boolean\"\n          default: false\n        require_mention:\n          type: \"boolean\"\n          default: true\n        exposed_skills:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。额外追加给该 task 的 skills 名称列表。系统会始终保留默认开放的 skills（当前为 docx、pptx、xlsx、find-skills），这里传入的是在默认集合基础上的增量追加，重复项会自动去重。\"\n        source_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。触发本次启动的用户 message_id 列表。主 agent 应传入，用于把这些用户消息绑定到新 task。\"\n      required: [\"channel\", \"conversation_id\", \"task_name\", \"task_id\", \"user_input\"]\n\n  cheapclaw_add_task_message:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_add_task_message\"\n    description: \"给已有 task_id 追加同一任务语义下的新消息，并自动附加当前时区时间。task_id 必须是绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        message:\n          type: \"string\"\n        source:\n          type: \"string\"\n          default: \"agent\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n        agent_system:\n          type: \"string\"\n        channel:\n          type: \"string\"\n          description: \"可选。若提供，会把 source_message_ids 绑定到这个 conversation 下的 task。\"\n        conversation_id:\n          type: \"string\"\n          description: \"可选。若提供，会把 source_message_ids 绑定到这个 conversation 下的 task。\"\n        source_message_ids:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"可选。触发这次追加消息的用户 message_id 列表。主 agent 应传入，用于把这些消息绑定到已有 task。\"\n      required: [\"task_id\", \"message\"]\n\n  cheapclaw_get_task_status:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_get_task_status\"\n    description: \"读取指定 task_id 的聚合状态，包括 running、share_context_path、stack_path、last_thinking、last_final_output、log_path 等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n      required: [\"task_id\"]\n\n  cheapclaw_list_agent_systems:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_agent_systems\"\n    description: \"列出当前 user_data_root 下可用的 agent_system 配置。\"\n    parameters:\n      type: \"object\"\n      properties: {}\n      required: []\n\n  cheapclaw_schedule_plan:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_schedule_plan\"\n    description: \"创建 CheapClaw 计划任务。支持 main_agent 或 task 范围。除了 interval_sec 和 once_at，还支持 daily/weekly 按固定时刻触发。\"\n    parameters:\n      type: \"object\"\n      properties:\n        name:\n          type: \"string\"\n        scope:\n          type: \"string\"\n          enum: [\"main_agent\", \"task\"]\n        task_id:\n          type: \"string\"\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        interval_sec:\n          type: \"integer\"\n        once_at:\n          type: \"string\"\n        schedule_type:\n          type: \"string\"\n          enum: [\"interval\", \"once\", \"daily\", \"weekly\"]\n        time_of_day:\n          type: \"string\"\n          description: \"用于 daily/weekly，格式 HH:MM，例如 08:00。\"\n        days_of_week:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"用于 weekly，取值如 mon/tue/wed/thu/fri/sat/sun。\"\n        message:\n          type: \"string\"\n        enabled:\n          type: \"boolean\"\n          default: true\n      required: [\"name\", \"scope\"]\n\n  cheapclaw_cancel_plan:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_cancel_plan\"\n    description: \"取消已有的计划任务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        plan_id:\n          type: \"string\"\n      required: [\"plan_id\"]\n\n  cheapclaw_reset_task:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_reset_task\"\n    description: \"重置 task 状态，可选保留 history，并可尝试终止当前 task 的后台进程。task_id 必须是绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        preserve_history:\n          type: \"boolean\"\n          default: true\n        kill_background_processes:\n          type: \"boolean\"\n          default: true\n        reason:\n          type: \"string\"\n      required: [\"task_id\"]\n\n  cheapclaw_generate_task_id:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_generate_task_id\"\n    description: \"按 CheapClaw 规则生成新的绝对路径 task_id。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n        task_name:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\", \"task_name\"]\n\n  cheapclaw_list_conversation_tasks:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_conversation_tasks\"\n    description: \"列出某个 conversation 当前已经关联的全部 tasks。若要决定继续哪个旧 task，应先读最近历史对话，再结合这里的完整 task 列表和状态判断。\"\n    parameters:\n      type: \"object\"\n      properties:\n        channel:\n          type: \"string\"\n        conversation_id:\n          type: \"string\"\n      required: [\"channel\", \"conversation_id\"]\n\n  cheapclaw_list_global_skills:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_list_global_skills\"\n    description: \"查看当前全局 skills 主库中的全部可用技能。\"\n    parameters:\n      type: \"object\"\n      properties: {}\n      required: []\n\n  cheapclaw_reveal_skills:\n    level: 0\n    type: tool_call_agent\n    name: \"cheapclaw_reveal_skills\"\n    description: \"将指定 skills 追加到某个 task 的可见 skills 白名单中。它不会修改全局 skills 主库；load_skill 仍然从全局主库安装技能。可选执行 fresh 让运行中的任务重新看到这些 skills。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        skill_names:\n          type: \"array\"\n          items:\n            type: \"string\"\n        run_fresh:\n          type: \"boolean\"\n          default: false\n      required: [\"task_id\", \"skill_names\"]\n"
  },
  {
    "path": "apps/cheapclaw/assets/agent_library/CheapClawWorkerGeneral/level_3_agents.yaml",
    "content": "tools:\n  worker_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - execute_command\n      - grep\n      - load_skill\n      - offload_skill\n      - fresh\n      - cheapclaw_reveal_skills\n      - file_read\n      - file_write\n      - file_move\n      - file_delete\n      - dir_list\n      - dir_create\n      - final_output\n      - image_read\n      - parse_document\n      - web_search\n      - google_scholar_search\n      - arxiv_search\n      - crawl_page\n      - file_download\n      - reference_list\n      - reference_add\n      - reference_delete\n    max_turns: 100\n    execution_model: openai/google/gemini-3-flash-preview\n    thinking_model: openai/google/gemini-3-flash-preview\n    compressor_model: openai/google/gemini-3-flash-preview\n    image_generation_model: openai/google/gemini-3-flash-preview\n    read_figure_model: openai/google/gemini-3-flash-preview\n    max_tokens: 0\n    action_window_steps: 20\n    thinking_interval: 20\n    prompts:\n      agent_responsibility: |\n        你是 CheapClaw 的后台 worker，负责完成具体任务产出。\n      agent_workflow: |\n        阅读当前任务、已有历史和文件空间后执行工作。默认你只能看到当前 task 被开放的 skills。若确实需要更多 skills，可基于已知 skill 名称调用 cheapclaw_reveal_skills 为当前 task 增加可见技能，再 fresh 当前任务继续。\n    name: \"worker_agent\"\n    description: \"CheapClaw 通用后台 worker\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n        task_input:\n          type: \"string\"\n      required: [\"task_id\", \"task_input\"]\n"
  },
  {
    "path": "apps/cheapclaw/assets/config/app_config.example.json",
    "content": "{\n  \"runtime\": {\n    \"action_window_steps\": 20,\n    \"thinking_interval\": 20,\n    \"fresh_enabled\": false,\n    \"fresh_interval_sec\": 0\n  },\n  \"env\": {\n    \"command_mode\": \"direct\",\n    \"seed_builtin_resources\": false\n  },\n  \"cheapclaw\": {\n    \"watchdog_interval_sec\": 10800,\n    \"default_exposed_skills\": [\n      \"docx\",\n      \"pptx\",\n      \"xlsx\",\n      \"find-skills\"\n    ],\n    \"default_mcp_servers\": [],\n    \"feishu_mode\": \"long_connection\",\n    \"service_log_file\": \"cheapclaw_service.log\"\n  }\n}\n"
  },
  {
    "path": "apps/cheapclaw/assets/config/channels.example.json",
    "content": "{\n  \"telegram\": {\n    \"enabled\": false,\n    \"bot_token\": \"\",\n    \"allowed_chats\": []\n  },\n  \"feishu\": {\n    \"enabled\": false,\n    \"mode\": \"long_connection\",\n    \"app_id\": \"\",\n    \"app_secret\": \"\",\n    \"verify_token\": \"\",\n    \"encrypt_key\": \"\"\n  },\n  \"whatsapp\": {\n    \"enabled\": false,\n    \"access_token\": \"\",\n    \"phone_number_id\": \"\",\n    \"verify_token\": \"\",\n    \"api_version\": \"v21.0\"\n  }\n}\n"
  },
  {
    "path": "apps/cheapclaw/assets/config/llm_config_example.yaml",
    "content": "# CheapClaw 默认 llm 配置样例。当前示例统一使用 Gemini 3 Flash。\ntemperature: 0\nmax_tokens: 0\nmax_context_window: 500000\nbase_url: https://openrouter.ai/api/v1\napi_key:\ntimeout: 300\nstream_timeout: 30\nfirst_chunk_timeout: 30\n\ntool_choice:\n  execution: required\n  thinking: required\n  compressor: required\n  image_generation: required\n  read_figure: required\n\nmodels:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n    tool_choice: required\n  - name: openai/moonshotai/kimi-k2.5\n    tool_choice: auto\n  - name: openai/qwen/qwen3.5-27b\n    tool_choice: auto\n\nfigure_models:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n    tool_choice: required\n  - name: openai/moonshotai/kimi-k2.5\n    tool_choice: auto\n  - name: openai/qwen/qwen3.5-27b\n    tool_choice: auto\n\ncompressor_models:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n    tool_choice: required\n  - name: openai/moonshotai/kimi-k2.5\n    tool_choice: auto\n  - name: openai/qwen/qwen3.5-27b\n    tool_choice: auto\n\nread_figure_models:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n    tool_choice: required\n  - name: openai/moonshotai/kimi-k2.5\n    tool_choice: auto\n  - name: openai/qwen/qwen3.5-27b\n    tool_choice: auto\n\nthinking_models:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n    tool_choice: required\n  - name: openai/moonshotai/kimi-k2.5\n    tool_choice: auto\n  - name: openai/qwen/qwen3.5-27b\n    tool_choice: auto\n\nmultimodal: true\ncompressor_multimodal: true\n"
  },
  {
    "path": "apps/cheapclaw/cheapclaw_hooks.py",
    "content": "#!/usr/bin/env python3\n\"\"\"CheapClaw runtime hooks for background worker tool events.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict\n\nCURRENT_DIR = Path(__file__).resolve().parent\nif str(CURRENT_DIR) not in sys.path:\n    sys.path.insert(0, str(CURRENT_DIR))\n\ntry:\n    from .tool_runtime_helpers import emit_task_event, now_iso\nexcept ImportError:\n    from tool_runtime_helpers import emit_task_event, now_iso\n\n\ndef on_tool_event(payload: Dict[str, Any]) -> None:\n    if not isinstance(payload, dict):\n        return\n    if payload.get(\"when\") != \"after\":\n        return\n    if payload.get(\"tool_name\") != \"final_output\":\n        return\n    if int(payload.get(\"agent_level\") or 0) != 0:\n        return\n\n    task_id = str(payload.get(\"task_id\") or \"\").strip()\n    if not task_id:\n        return\n    if Path(task_id).name == \"supervisor_task\":\n        return\n\n    result = payload.get(\"result\") or {}\n    if not isinstance(result, dict):\n        result = {}\n\n    emit_task_event({\n        \"event_type\": \"task_final_output\",\n        \"task_id\": task_id,\n        \"agent_id\": str(payload.get(\"agent_id\") or \"\"),\n        \"agent_name\": str(payload.get(\"agent_name\") or \"\"),\n        \"status\": str(result.get(\"status\") or \"\"),\n        \"output\": str(result.get(\"output\") or \"\"),\n        \"error_information\": str(result.get(\"error_information\") or \"\"),\n        \"observed_at\": now_iso(),\n        \"pid\": os.getpid(),\n    })\n"
  },
  {
    "path": "apps/cheapclaw/cheapclaw_service.py",
    "content": "#!/usr/bin/env python3\n\"\"\"Standalone CheapClaw application built on top of the public InfiAgent SDK.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport hashlib\nimport hmac\nimport json\nimport mimetypes\nimport os\nimport shutil\nimport sys\nimport tempfile\nimport threading\nimport time\nimport uuid\nimport traceback\nfrom contextlib import contextmanager\nfrom dataclasses import dataclass\nfrom datetime import datetime, timedelta\nfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServer\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, Iterable, List, Optional, Tuple\nfrom urllib.parse import parse_qs, urlparse\n\nimport requests\n\nfrom infiagent import InfiAgent, infiagent\n\nCURRENT_DIR = Path(__file__).resolve().parent\nif str(CURRENT_DIR) not in sys.path:\n    sys.path.insert(0, str(CURRENT_DIR))\n\ntry:\n    from .tool_runtime_helpers import (\n        ack_outbox_event,\n        ack_task_event,\n        append_history,\n        bind_messages_to_task,\n        compute_next_scheduled_run,\n        ensure_conversation,\n        generate_task_id,\n        get_channels_root,\n        list_global_skills,\n        list_outbox_events,\n        list_task_events,\n        load_plans,\n        now_iso,\n        parse_iso,\n        queue_outbound_message,\n        refresh_conversation_context_file,\n        save_plans,\n        set_task_visible_skills,\n        _short_text,\n        slugify,\n        update_conversation_task,\n    )\nexcept ImportError:\n    from tool_runtime_helpers import (\n        ack_outbox_event,\n        ack_task_event,\n        append_history,\n        bind_messages_to_task,\n        compute_next_scheduled_run,\n        ensure_conversation,\n        generate_task_id,\n        get_channels_root,\n        list_global_skills,\n        list_outbox_events,\n        list_task_events,\n        load_plans,\n        now_iso,\n        parse_iso,\n        queue_outbound_message,\n        refresh_conversation_context_file,\n        save_plans,\n        set_task_visible_skills,\n        _short_text,\n        slugify,\n        update_conversation_task,\n    )\n\ntry:\n    import fcntl\nexcept ImportError:  # pragma: no cover\n    fcntl = None\n\n\nAPP_ROOT = Path(__file__).resolve().parent\nASSET_ROOT = APP_ROOT / \"assets\"\nASSET_AGENT_LIBRARY_ROOT = ASSET_ROOT / \"agent_library\"\nASSET_CONFIG_ROOT = ASSET_ROOT / \"config\"\nASSET_APP_CONFIG_EXAMPLE_PATH = ASSET_CONFIG_ROOT / \"app_config.example.json\"\nASSET_CHANNELS_EXAMPLE_PATH = ASSET_CONFIG_ROOT / \"channels.example.json\"\nAPP_TOOLS_ROOT = APP_ROOT / \"tools_library\"\nAPP_SKILLS_ROOT = APP_ROOT / \"skills\"\nAPP_WEB_ROOT = APP_ROOT / \"web\"\nSERVICE_LOG_PATH: Optional[Path] = None\nACTIVE_SERVICE: Optional[\"CheapClawService\"] = None\nFINAL_OUTPUT_HOOK_CALLBACK = f\"{(APP_ROOT / 'cheapclaw_hooks.py').resolve()}:on_tool_event\"\n\n\ndef _tail_text(path: Path, max_chars: int = 4000) -> str:\n    try:\n        text = path.read_text(encoding=\"utf-8\", errors=\"ignore\")\n    except Exception:\n        return \"\"\n    if len(text) <= max_chars:\n        return text\n    return text[-max_chars:]\n\n\ndef _atomic_write_text(path: Path, content: str) -> None:\n    path.parent.mkdir(parents=True, exist_ok=True)\n    fd, tmp_name = tempfile.mkstemp(prefix=path.name + \".\", dir=str(path.parent))\n    try:\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as tmp_file:\n            tmp_file.write(content)\n        os.replace(tmp_name, path)\n    finally:\n        if os.path.exists(tmp_name):\n            os.unlink(tmp_name)\n\n\ndef _log(message: str) -> None:\n    line = f\"[CheapClaw {datetime.now().astimezone().isoformat(timespec='seconds')}] {message}\"\n    print(line, flush=True)\n    global SERVICE_LOG_PATH\n    if SERVICE_LOG_PATH is not None:\n        try:\n            SERVICE_LOG_PATH.parent.mkdir(parents=True, exist_ok=True)\n            with open(SERVICE_LOG_PATH, \"a\", encoding=\"utf-8\") as fh:\n                fh.write(line + \"\\n\")\n        except Exception:\n            pass\n\n\ndef _load_json(path: Path, default: Any) -> Any:\n    try:\n        return json.loads(path.read_text(encoding=\"utf-8\"))\n    except Exception:\n        return default\n\n\ndef _load_cheapclaw_app_config_example() -> Dict[str, Any]:\n    fallback = {\n        \"runtime\": {\n            \"action_window_steps\": 20,\n            \"thinking_interval\": 20,\n            \"fresh_enabled\": False,\n            \"fresh_interval_sec\": 0,\n        },\n        \"env\": {\n            \"command_mode\": \"direct\",\n            \"seed_builtin_resources\": False,\n        },\n        \"cheapclaw\": {\n            \"watchdog_interval_sec\": 10800,\n            \"default_exposed_skills\": [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"],\n            \"default_mcp_servers\": [],\n            \"feishu_mode\": \"long_connection\",\n            \"service_log_file\": \"cheapclaw_service.log\",\n        },\n    }\n    return _load_json(ASSET_APP_CONFIG_EXAMPLE_PATH, fallback)\n\n\ndef _extract_cheapclaw_settings(payload: Dict[str, Any]) -> Dict[str, Any]:\n    payload = payload if isinstance(payload, dict) else {}\n    example_payload = _load_cheapclaw_app_config_example()\n    example_cheapclaw = example_payload.get(\"cheapclaw\", {}) if isinstance(example_payload.get(\"cheapclaw\"), dict) else {}\n    cheapclaw = payload.get(\"cheapclaw\", {}) if isinstance(payload.get(\"cheapclaw\"), dict) else {}\n    default_skills = cheapclaw.get(\"default_exposed_skills\", example_cheapclaw.get(\"default_exposed_skills\", [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"]))\n    if not isinstance(default_skills, list):\n        default_skills = list(example_cheapclaw.get(\"default_exposed_skills\", [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"]))\n    default_mcp_servers = cheapclaw.get(\"default_mcp_servers\", example_cheapclaw.get(\"default_mcp_servers\", []))\n    if not isinstance(default_mcp_servers, list):\n        default_mcp_servers = list(example_cheapclaw.get(\"default_mcp_servers\", []))\n    return {\n        \"watchdog_interval_sec\": max(60, int(cheapclaw.get(\"watchdog_interval_sec\", example_cheapclaw.get(\"watchdog_interval_sec\", 10800)) or example_cheapclaw.get(\"watchdog_interval_sec\", 10800))),\n        \"default_exposed_skills\": [str(item).strip() for item in default_skills if str(item).strip()],\n        \"default_mcp_servers\": [item for item in default_mcp_servers if isinstance(item, dict)],\n        \"feishu_mode\": str(cheapclaw.get(\"feishu_mode\", example_cheapclaw.get(\"feishu_mode\", \"long_connection\")) or example_cheapclaw.get(\"feishu_mode\", \"long_connection\")).strip(),\n        \"service_log_file\": str(cheapclaw.get(\"service_log_file\", example_cheapclaw.get(\"service_log_file\", \"cheapclaw_service.log\")) or example_cheapclaw.get(\"service_log_file\", \"cheapclaw_service.log\")).strip(),\n    }\n\n\n@dataclass(frozen=True)\nclass CheapClawPaths:\n    user_data_root: Path\n    cheapclaw_root: Path\n    panel_dir: Path\n    panel_path: Path\n    panel_lock_path: Path\n    panel_backups_dir: Path\n    plans_path: Path\n    config_dir: Path\n    app_config_path: Path\n    app_config_example_path: Path\n    channels_config_path: Path\n    channels_example_path: Path\n    channels_root: Path\n    outbox_dir: Path\n    tasks_root: Path\n    task_skills_root: Path\n    supervisor_task_id: Path\n    runtime_dir: Path\n    runtime_state_path: Path\n\n    @classmethod\n    def from_user_data_root(cls, user_data_root: str | Path, app_name: str = \"cheapclaw\") -> \"CheapClawPaths\":\n        root = Path(user_data_root).expanduser().resolve()\n        cheapclaw_root = root / app_name\n        panel_dir = cheapclaw_root / \"panel\"\n        runtime_dir = cheapclaw_root / \"runtime\"\n        config_dir = cheapclaw_root / \"config\"\n        return cls(\n            user_data_root=root,\n            cheapclaw_root=cheapclaw_root,\n            panel_dir=panel_dir,\n            panel_path=panel_dir / \"panel.json\",\n            panel_lock_path=panel_dir / \"panel.lock\",\n            panel_backups_dir=panel_dir / \"backups\",\n            plans_path=cheapclaw_root / \"plans.json\",\n            config_dir=config_dir,\n            app_config_path=config_dir / \"app_config.json\",\n            app_config_example_path=config_dir / \"app_config.example.json\",\n            channels_config_path=config_dir / \"channels.json\",\n            channels_example_path=config_dir / \"channels.example.json\",\n            channels_root=cheapclaw_root / \"channels\",\n            outbox_dir=cheapclaw_root / \"outbox\",\n            tasks_root=cheapclaw_root / \"tasks\",\n            task_skills_root=cheapclaw_root / \"task_skills\",\n            supervisor_task_id=cheapclaw_root / \"supervisor_task\",\n            runtime_dir=runtime_dir,\n            runtime_state_path=runtime_dir / \"state.json\",\n        )\n\n\nclass CheapClawPanelStore:\n    def __init__(self, paths: CheapClawPaths, history_preview_limit: int = 50):\n        self.paths = paths\n        self.history_preview_limit = max(1, int(history_preview_limit))\n        self._thread_lock = threading.RLock()\n        self.ensure_layout()\n\n    def ensure_layout(self) -> None:\n        for path in [\n            self.paths.cheapclaw_root,\n            self.paths.panel_dir,\n            self.paths.panel_backups_dir,\n            self.paths.config_dir,\n            self.paths.runtime_dir,\n            self.paths.channels_root,\n            self.paths.outbox_dir,\n            self.paths.tasks_root,\n            self.paths.task_skills_root,\n        ]:\n            path.mkdir(parents=True, exist_ok=True)\n        if not self.paths.panel_path.exists():\n            _atomic_write_text(\n                self.paths.panel_path,\n                json.dumps(\n                    {\n                        \"version\": 1,\n                        \"channels\": {},\n                        \"service_state\": {\n                            \"main_agent_task_id\": str(self.paths.supervisor_task_id),\n                            \"main_agent_running\": False,\n                            \"main_agent_run_id\": \"\",\n                            \"main_agent_last_started_at\": \"\",\n                            \"main_agent_last_finished_at\": \"\",\n                            \"main_agent_dirty\": False,\n                            \"watchdog_last_run_at\": \"\",\n                            \"last_backup_path\": \"\",\n                        },\n                    },\n                    ensure_ascii=False,\n                    indent=2,\n                ),\n            )\n        if not self.paths.plans_path.exists():\n            _atomic_write_text(self.paths.plans_path, json.dumps({\"version\": 1, \"plans\": []}, ensure_ascii=False, indent=2))\n        if not self.paths.runtime_state_path.exists():\n            _atomic_write_text(self.paths.runtime_state_path, json.dumps({\"webhook_server\": {}, \"telegram_offsets\": {}}, ensure_ascii=False, indent=2))\n\n    @contextmanager\n    def _file_lock(self):\n        self.paths.panel_dir.mkdir(parents=True, exist_ok=True)\n        with self._thread_lock:\n            with open(self.paths.panel_lock_path, \"a+\", encoding=\"utf-8\") as lock_file:\n                if fcntl is not None:\n                    fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)\n                try:\n                    yield\n                finally:\n                    if fcntl is not None:\n                        fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)\n\n    def load_panel(self) -> Dict[str, Any]:\n        return self._normalize_panel(_load_json(self.paths.panel_path, {\"version\": 1, \"channels\": {}, \"service_state\": {}}))\n\n    def save_panel(self, panel: Dict[str, Any], *, backup: bool = True) -> Dict[str, Any]:\n        normalized = self._normalize_panel(panel)\n        with self._file_lock():\n            self._write_panel_locked(normalized, backup=backup)\n        return normalized\n\n    def mutate(self, updater: Callable[[Dict[str, Any]], Dict[str, Any] | None]) -> Dict[str, Any]:\n        with self._file_lock():\n            current = self.load_panel()\n            updated = updater(current)\n            panel = current if updated is None else updated\n            normalized = self._normalize_panel(panel)\n            self._write_panel_locked(normalized, backup=True)\n            return normalized\n\n    def _write_panel_locked(self, panel: Dict[str, Any], *, backup: bool) -> None:\n        if backup and self.paths.panel_path.exists():\n            backup_path = self.paths.panel_backups_dir / f\"panel_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}.json\"\n            backup_path.write_text(self.paths.panel_path.read_text(encoding=\"utf-8\"), encoding=\"utf-8\")\n            panel.setdefault(\"service_state\", {})[\"last_backup_path\"] = str(backup_path)\n        _atomic_write_text(self.paths.panel_path, json.dumps(panel, ensure_ascii=False, indent=2))\n\n    def _normalize_panel(self, panel: Dict[str, Any]) -> Dict[str, Any]:\n        if not isinstance(panel, dict):\n            panel = {}\n        panel.setdefault(\"version\", 1)\n        panel.setdefault(\"channels\", {})\n        panel.setdefault(\"service_state\", {})\n        defaults = {\n            \"main_agent_task_id\": str(self.paths.supervisor_task_id),\n            \"main_agent_running\": False,\n            \"main_agent_run_id\": \"\",\n            \"main_agent_last_started_at\": \"\",\n            \"main_agent_last_finished_at\": \"\",\n            \"main_agent_dirty\": False,\n            \"watchdog_last_run_at\": \"\",\n            \"last_backup_path\": \"\",\n        }\n        for key, value in defaults.items():\n            panel[\"service_state\"].setdefault(key, value)\n        for channel, payload in list(panel[\"channels\"].items()):\n            if not isinstance(payload, dict):\n                panel[\"channels\"][channel] = {\"conversations\": {}}\n                payload = panel[\"channels\"][channel]\n            payload.setdefault(\"conversations\", {})\n            for conversation_id, conversation in list(payload[\"conversations\"].items()):\n                payload[\"conversations\"][conversation_id] = self._normalize_conversation(channel, conversation_id, conversation)\n        return panel\n\n    def _normalize_conversation(self, channel: str, conversation_id: str, conversation: Dict[str, Any]) -> Dict[str, Any]:\n        if not isinstance(conversation, dict):\n            conversation = {}\n        defaults = {\n            \"channel\": channel,\n            \"conversation_id\": conversation_id,\n            \"conversation_type\": \"group\",\n            \"display_name\": conversation_id,\n            \"trigger_policy\": {\"require_mention\": True},\n            \"message_history_path\": str(get_channels_root() / slugify(channel) / slugify(conversation_id) / \"social_history.jsonl\"),\n            \"context_summary_path\": str(get_channels_root() / slugify(channel) / slugify(conversation_id) / \"latest_context.md\"),\n            \"messages\": [],\n            \"linked_tasks\": [],\n            \"pending_events\": [],\n            \"dirty\": False,\n            \"last_snapshot_path\": \"\",\n            \"updated_at\": \"\",\n            \"running_task_count\": 0,\n            \"has_stale_running_tasks\": False,\n            \"latest_user_message_at\": \"\",\n            \"latest_bot_message_at\": \"\",\n            \"unread_event_count\": 0,\n            \"last_reply_summary\": \"\",\n            \"conversation_tags\": [],\n            \"message_task_bindings\": [],\n        }\n        for key, value in defaults.items():\n            conversation.setdefault(key, value)\n        normalized_tasks = []\n        for item in conversation.get(\"linked_tasks\", []):\n            if not isinstance(item, dict):\n                continue\n            task_id = str(item.get(\"task_id\") or \"\").strip()\n            if not task_id:\n                continue\n            task_defaults = {\n                \"task_id\": task_id,\n                \"created_at\": \"\",\n                \"agent_system\": \"\",\n                \"agent_name\": \"\",\n                \"status\": \"unknown\",\n                \"share_context_path\": \"\",\n                \"stack_path\": \"\",\n                \"log_path\": \"\",\n                \"skills_dir\": \"\",\n                \"default_exposed_skills\": [],\n                \"mcp_servers\": [],\n                \"last_thinking\": \"\",\n                \"last_thinking_at\": \"\",\n                \"last_final_output\": \"\",\n                \"last_final_output_at\": \"\",\n                \"last_action_at\": \"\",\n                \"last_log_at\": \"\",\n                \"fresh_retry_count\": 0,\n                \"last_watchdog_note\": \"\",\n                \"pid_alive\": None,\n                \"watchdog_observation\": \"\",\n                \"watchdog_suspected_state\": \"\",\n            }\n            task_defaults.update(item)\n            normalized_tasks.append(task_defaults)\n        conversation[\"linked_tasks\"] = normalized_tasks\n        conversation[\"running_task_count\"] = sum(1 for item in normalized_tasks if item.get(\"status\") == \"running\")\n        conversation[\"unread_event_count\"] = len(conversation.get(\"pending_events\", []))\n        return conversation\n\n    def dirty_conversations(self) -> List[Dict[str, Any]]:\n        panel = self.load_panel()\n        items = []\n        for channel_payload in panel.get(\"channels\", {}).values():\n            for conv in channel_payload.get(\"conversations\", {}).values():\n                if conv.get(\"dirty\"):\n                    items.append(conv)\n        return items\n\n    def record_social_message(self, **kwargs) -> Dict[str, Any]:\n        timestamp = kwargs.get(\"timestamp\") or now_iso()\n        channel = str(kwargs.get(\"channel\") or \"\").strip()\n        conversation_id = str(kwargs.get(\"conversation_id\") or \"\").strip()\n        message_text = str(kwargs.get(\"message_text\") or \"\").strip()\n        attachments = kwargs.get(\"attachments\") or []\n        if not channel or not conversation_id or (not message_text and not attachments):\n            raise ValueError(\"channel, conversation_id and message_text/attachments are required\")\n\n        def _update(panel: Dict[str, Any]) -> Dict[str, Any]:\n            conv = ensure_conversation(\n                panel,\n                channel=channel,\n                conversation_id=conversation_id,\n                conversation_type=str(kwargs.get(\"conversation_type\") or \"group\"),\n                display_name=kwargs.get(\"display_name\") or conversation_id,\n                require_mention=bool(kwargs.get(\"require_mention\", True)),\n            )\n            event = {\n                \"message_id\": str(kwargs.get(\"message_id\") or \"\").strip(),\n                \"timestamp\": timestamp,\n                \"sender_id\": str(kwargs.get(\"sender_id\") or \"\").strip(),\n                \"sender_name\": str(kwargs.get(\"sender_name\") or \"\").strip(),\n                \"text\": message_text,\n                \"attachments\": attachments,\n                \"is_mention_to_bot\": bool(kwargs.get(\"is_mention_to_bot\", False)),\n                \"direction\": \"inbound\",\n            }\n            history_path = Path(conv[\"message_history_path\"])\n            history_path.parent.mkdir(parents=True, exist_ok=True)\n            with open(history_path, \"a\", encoding=\"utf-8\") as fh:\n                fh.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n            conv.setdefault(\"messages\", []).append(event)\n            del conv[\"messages\"][:-self.history_preview_limit]\n            conv.setdefault(\"pending_events\", []).append({\"type\": \"social_message\", \"timestamp\": timestamp, \"message_id\": event[\"message_id\"]})\n            if kwargs.get(\"mark_dirty\", True):\n                conv[\"dirty\"] = True\n                panel[\"service_state\"][\"main_agent_dirty\"] = True\n            conv[\"updated_at\"] = timestamp\n            conv[\"latest_user_message_at\"] = timestamp\n            conv[\"unread_event_count\"] = len(conv[\"pending_events\"])\n            return panel\n        panel = self.mutate(_update)\n        refresh_conversation_context_file(channel, conversation_id, panel)\n        return panel\n\n    def set_main_agent_state(self, *, running: bool, run_id: str = \"\", mark_dirty: Optional[bool] = None) -> Dict[str, Any]:\n        def _update(panel: Dict[str, Any]) -> Dict[str, Any]:\n            state = panel[\"service_state\"]\n            state[\"main_agent_running\"] = bool(running)\n            if run_id:\n                state[\"main_agent_run_id\"] = run_id\n            if running:\n                state[\"main_agent_last_started_at\"] = now_iso()\n            else:\n                state[\"main_agent_last_finished_at\"] = now_iso()\n            if mark_dirty is not None:\n                state[\"main_agent_dirty\"] = bool(mark_dirty)\n            return panel\n        return self.mutate(_update)\n\n    def mark_watchdog_tick(self) -> Dict[str, Any]:\n        def _update(panel: Dict[str, Any]) -> Dict[str, Any]:\n            panel[\"service_state\"][\"watchdog_last_run_at\"] = now_iso()\n            return panel\n        return self.mutate(_update)\n\n\nclass ChannelAdapter:\n    name = \"base\"\n\n    def __init__(self, config: Dict[str, Any], service: \"CheapClawService\"):\n        self.config = config\n        self.service = service\n\n    def poll_events(self) -> List[Dict[str, Any]]:\n        return []\n\n    def send_message(self, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None) -> Tuple[bool, str]:\n        raise NotImplementedError\n\n    @staticmethod\n    def _normalize_attachments(attachments: Optional[List[Dict[str, Any]]]) -> List[Dict[str, Any]]:\n        items = []\n        for item in attachments or []:\n            if not isinstance(item, dict):\n                continue\n            local_path = str(item.get(\"local_path\") or item.get(\"path\") or \"\").strip()\n            if not local_path:\n                continue\n            path = Path(local_path).expanduser().resolve()\n            if not path.exists() or not path.is_file():\n                continue\n            guessed_mime = mimetypes.guess_type(str(path))[0] or \"application/octet-stream\"\n            items.append({\n                \"path\": path,\n                \"filename\": str(item.get(\"filename\") or path.name),\n                \"mime_type\": str(item.get(\"mime_type\") or guessed_mime),\n                \"kind\": str(item.get(\"kind\") or \"auto\").strip().lower() or \"auto\",\n                \"caption\": str(item.get(\"caption\") or \"\").strip(),\n            })\n        return items\n\n    def handle_webhook_get(self, path: str, query: Dict[str, List[str]], headers: Dict[str, str]) -> Tuple[int, Dict[str, str], bytes]:\n        return 404, {\"Content-Type\": \"text/plain; charset=utf-8\"}, b\"not found\"\n\n    def handle_webhook_post(self, path: str, body: bytes, headers: Dict[str, str]) -> Tuple[int, Dict[str, str], bytes]:\n        return 404, {\"Content-Type\": \"text/plain; charset=utf-8\"}, b\"not found\"\n\n\ndef _ensure_cheapclaw_app_config(paths: CheapClawPaths) -> Dict[str, Any]:\n    paths.config_dir.mkdir(parents=True, exist_ok=True)\n    example_payload = _load_cheapclaw_app_config_example()\n    _atomic_write_text(paths.app_config_example_path, json.dumps(example_payload, ensure_ascii=False, indent=2))\n    if not paths.app_config_path.exists():\n        _atomic_write_text(paths.app_config_path, json.dumps(example_payload, ensure_ascii=False, indent=2))\n    payload = _load_json(paths.app_config_path, example_payload)\n    if not isinstance(payload, dict):\n        payload = {}\n    runtime_cfg = payload.setdefault(\"runtime\", {})\n    if not isinstance(runtime_cfg, dict):\n        runtime_cfg = {}\n        payload[\"runtime\"] = runtime_cfg\n    runtime_cfg.setdefault(\"action_window_steps\", example_payload[\"runtime\"][\"action_window_steps\"])\n    runtime_cfg.setdefault(\"thinking_interval\", example_payload[\"runtime\"][\"thinking_interval\"])\n    runtime_cfg.setdefault(\"fresh_enabled\", example_payload[\"runtime\"][\"fresh_enabled\"])\n    runtime_cfg.setdefault(\"fresh_interval_sec\", example_payload[\"runtime\"][\"fresh_interval_sec\"])\n    if int(runtime_cfg.get(\"action_window_steps\", 20) or 20) == 20 and int(runtime_cfg.get(\"thinking_interval\", 20) or 20) == 10:\n        runtime_cfg[\"thinking_interval\"] = 20\n    env_cfg = payload.setdefault(\"env\", {})\n    if not isinstance(env_cfg, dict):\n        env_cfg = {}\n        payload[\"env\"] = env_cfg\n    env_cfg[\"seed_builtin_resources\"] = False\n    env_cfg.setdefault(\"command_mode\", example_payload[\"env\"][\"command_mode\"])\n    cheapclaw_cfg = payload.setdefault(\"cheapclaw\", {})\n    if not isinstance(cheapclaw_cfg, dict):\n        cheapclaw_cfg = {}\n        payload[\"cheapclaw\"] = cheapclaw_cfg\n    for key, value in example_payload[\"cheapclaw\"].items():\n        cheapclaw_cfg.setdefault(key, value)\n    default_skills = cheapclaw_cfg.get(\"default_exposed_skills\", [])\n    if not isinstance(default_skills, list):\n        default_skills = list(example_payload[\"cheapclaw\"].get(\"default_exposed_skills\", []))\n    for skill_name in example_payload[\"cheapclaw\"].get(\"default_exposed_skills\", []):\n        if skill_name not in default_skills:\n            default_skills.append(skill_name)\n    cheapclaw_cfg[\"default_exposed_skills\"] = default_skills\n    if not isinstance(cheapclaw_cfg.get(\"default_mcp_servers\"), list):\n        cheapclaw_cfg[\"default_mcp_servers\"] = list(example_payload[\"cheapclaw\"].get(\"default_mcp_servers\", []))\n    _atomic_write_text(paths.app_config_path, json.dumps(payload, ensure_ascii=False, indent=2))\n    return payload\n\n\ndef _sync_root_app_config_from_cheapclaw(user_data_root: Path, cheapclaw_cfg: Dict[str, Any]) -> None:\n    root_path = Path(user_data_root).expanduser().resolve() / \"config\" / \"app_config.json\"\n    root_path.parent.mkdir(parents=True, exist_ok=True)\n    payload = _load_json(root_path, {})\n    if not isinstance(payload, dict):\n        payload = {}\n    runtime_cfg = cheapclaw_cfg.get(\"runtime\", {}) if isinstance(cheapclaw_cfg, dict) else {}\n    env_cfg = payload.setdefault(\"env\", {})\n    env_cfg[\"seed_builtin_resources\"] = False\n    env_cfg.setdefault(\"command_mode\", \"direct\")\n    runtime = payload.setdefault(\"runtime\", {})\n    if isinstance(runtime_cfg, dict):\n        for key in (\"action_window_steps\", \"thinking_interval\", \"fresh_enabled\", \"fresh_interval_sec\"):\n            if key in runtime_cfg:\n                runtime[key] = runtime_cfg[key]\n    payload.pop(\"cheapclaw\", None)\n    root_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n\n\nclass TelegramAdapter(ChannelAdapter):\n    name = \"telegram\"\n\n    def __init__(self, config: Dict[str, Any], service: \"CheapClawService\"):\n        super().__init__(config, service)\n        self.bot_token = str(config.get(\"bot_token\") or \"\").strip()\n        self.allowed_chats = {str(item) for item in config.get(\"allowed_chats\", [])}\n        self._api_root = f\"https://api.telegram.org/bot{self.bot_token}\" if self.bot_token else \"\"\n        self._state = self.service.load_runtime_state()\n        self._me_cache = self._state.get(\"telegram_bot_me\") or {}\n\n    def _request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:\n        if not self._api_root:\n            return {}\n        response = requests.request(method, self._api_root + endpoint, timeout=30, **kwargs)\n        response.raise_for_status()\n        data = response.json()\n        return data if isinstance(data, dict) else {}\n\n    def _get_me(self) -> Dict[str, Any]:\n        if self._me_cache:\n            return self._me_cache\n        data = self._request(\"GET\", \"/getMe\")\n        self._me_cache = data.get(\"result\", {}) if data.get(\"ok\") else {}\n        state = self.service.load_runtime_state()\n        state[\"telegram_bot_me\"] = self._me_cache\n        self.service.save_runtime_state(state)\n        return self._me_cache\n\n    def _message_mentions_bot(self, message: Dict[str, Any], text: str, is_group: bool) -> bool:\n        if not is_group:\n            return True\n        me = self._get_me() or {}\n        bot_username = str(me.get(\"username\") or \"\").strip()\n        bot_id = str(me.get(\"id\") or \"\").strip()\n        if bot_username and f\"@{bot_username}\".lower() in text.lower():\n            return True\n\n        for entity in (message.get(\"entities\") or []) + (message.get(\"caption_entities\") or []):\n            if not isinstance(entity, dict):\n                continue\n            entity_type = str(entity.get(\"type\") or \"\")\n            if entity_type == \"mention\" and bot_username:\n                offset = int(entity.get(\"offset\") or 0)\n                length = int(entity.get(\"length\") or 0)\n                if text[offset:offset + length].lower() == f\"@{bot_username}\".lower():\n                    return True\n            if entity_type == \"text_mention\":\n                user = entity.get(\"user\") or {}\n                if bot_id and str(user.get(\"id\") or \"\") == bot_id:\n                    return True\n\n        reply_to = message.get(\"reply_to_message\") or {}\n        reply_from = reply_to.get(\"from\") or {}\n        if bot_id and str(reply_from.get(\"id\") or \"\") == bot_id:\n            return True\n        if reply_from.get(\"is_bot\") and bot_username and str(reply_from.get(\"username\") or \"\").lower() == bot_username.lower():\n            return True\n        return False\n\n    def poll_events(self) -> List[Dict[str, Any]]:\n        if not self.bot_token:\n            return []\n        state = self.service.load_runtime_state()\n        offsets = state.setdefault(\"telegram_offsets\", {})\n        offset = int(offsets.get(\"default\", 0) or 0)\n        data = self._request(\"GET\", \"/getUpdates\", params={\"timeout\": 1, \"offset\": offset + 1})\n        items = []\n        for result in data.get(\"result\", []):\n            update_id = int(result.get(\"update_id\") or 0)\n            message = (\n                result.get(\"message\")\n                or result.get(\"edited_message\")\n                or result.get(\"channel_post\")\n                or result.get(\"edited_channel_post\")\n                or result.get(\"business_message\")\n                or result.get(\"edited_business_message\")\n                or {}\n            )\n            chat = message.get(\"chat\") or {}\n            chat_id = str(chat.get(\"id\") or \"\").strip()\n            if not chat_id:\n                continue\n            if self.allowed_chats and chat_id not in self.allowed_chats:\n                continue\n            text = str(message.get(\"text\") or message.get(\"caption\") or \"\").strip()\n            is_group = chat.get(\"type\") in {\"group\", \"supergroup\"}\n            mention = self._message_mentions_bot(message, text, is_group)\n            if is_group and not mention:\n                offsets[\"default\"] = update_id\n                continue\n            from_user = message.get(\"from\") or message.get(\"sender_chat\") or {}\n            sender_name = \" \".join(\n                part for part in [\n                    str(from_user.get(\"first_name\") or \"\").strip(),\n                    str(from_user.get(\"last_name\") or \"\").strip(),\n                ] if part\n            ).strip()\n            if not sender_name:\n                sender_name = str(from_user.get(\"title\") or from_user.get(\"username\") or \"\")\n            items.append({\n                \"event_id\": f\"telegram_{update_id}\",\n                \"channel\": \"telegram\",\n                \"conversation_id\": chat_id,\n                \"conversation_type\": \"group\" if is_group else \"person\",\n                \"display_name\": str(chat.get(\"title\") or chat.get(\"username\") or chat_id),\n                \"sender_id\": str(from_user.get(\"id\") or \"\"),\n                \"sender_name\": sender_name,\n                \"message_id\": str(message.get(\"message_id\") or \"\"),\n                \"message_text\": text,\n                \"attachments\": [],\n                \"timestamp\": datetime.fromtimestamp(int(message.get(\"date\") or time.time())).astimezone().isoformat(timespec=\"seconds\"),\n                \"is_mention_to_bot\": mention,\n                \"require_mention\": is_group,\n            })\n            offsets[\"default\"] = update_id\n        self.service.save_runtime_state(state)\n        return items\n\n    def send_message(self, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None) -> Tuple[bool, str]:\n        if not self.bot_token:\n            return False, \"telegram bot_token is missing\"\n        last_remote_id = \"\"\n        normalized = self._normalize_attachments(attachments)\n        if message:\n            payload = {\"chat_id\": conversation_id, \"text\": message}\n            try:\n                data = self._request(\"POST\", \"/sendMessage\", json=payload)\n            except Exception as exc:\n                return False, str(exc)\n            if not data.get(\"ok\"):\n                return False, json.dumps(data, ensure_ascii=False)\n            last_remote_id = str((data.get(\"result\") or {}).get(\"message_id\") or \"\")\n        for item in normalized:\n            mime_type = item[\"mime_type\"]\n            method = \"/sendPhoto\" if mime_type.startswith(\"image/\") else \"/sendDocument\"\n            field = \"photo\" if method == \"/sendPhoto\" else \"document\"\n            data_payload = {\"chat_id\": conversation_id}\n            caption = item[\"caption\"] or (message if not last_remote_id else \"\")\n            if caption:\n                data_payload[\"caption\"] = caption\n            with open(item[\"path\"], \"rb\") as fh:\n                files = {field: (item[\"filename\"], fh, mime_type)}\n                try:\n                    data = self._request(\"POST\", method, data=data_payload, files=files)\n                except Exception as exc:\n                    return False, str(exc)\n            if not data.get(\"ok\"):\n                return False, json.dumps(data, ensure_ascii=False)\n            last_remote_id = str((data.get(\"result\") or {}).get(\"message_id\") or \"\")\n        if not message and not normalized:\n            return False, \"telegram message or attachments are required\"\n        return True, last_remote_id\n\n\nclass FeishuAdapter(ChannelAdapter):\n    name = \"feishu\"\n\n    def __init__(self, config: Dict[str, Any], service: \"CheapClawService\"):\n        super().__init__(config, service)\n        self.app_id = str(config.get(\"app_id\") or \"\").strip()\n        self.app_secret = str(config.get(\"app_secret\") or \"\").strip()\n        self.verify_token = str(config.get(\"verify_token\") or \"\").strip()\n        self.encrypt_key = str(config.get(\"encrypt_key\") or \"\").strip()\n        self.mode = str(config.get(\"mode\") or \"long_connection\").strip() or \"long_connection\"\n        self.api_root = \"https://open.feishu.cn/open-apis\"\n        self._queue_lock = threading.Lock()\n        self._queued_events: List[Dict[str, Any]] = []\n        self._long_conn_thread: Optional[threading.Thread] = None\n        self._long_conn_started = False\n        if self.mode == \"long_connection\":\n            self._start_long_connection()\n\n    def _enqueue_event(self, payload: Dict[str, Any]) -> None:\n        with self._queue_lock:\n            self._queued_events.append(payload)\n\n    def _normalize_message_event(self, header: Dict[str, Any], event: Dict[str, Any]) -> Optional[Dict[str, Any]]:\n        message = event.get(\"message\") or {}\n        sender = event.get(\"sender\") or {}\n        if header.get(\"event_type\") != \"im.message.receive_v1\":\n            return None\n        text = \"\"\n        content_raw = message.get(\"content\")\n        if isinstance(content_raw, str):\n            try:\n                content = json.loads(content_raw)\n            except Exception:\n                content = {}\n            text = str(content.get(\"text\") or \"\").strip()\n        chat_type = str(message.get(\"chat_type\") or \"\")\n        chat_id = str(message.get(\"chat_id\") or \"\").strip()\n        if not chat_id:\n            return None\n        mention = (chat_type != \"group\") or (\"<at\" in text)\n        return {\n            \"event_id\": f\"feishu_{message.get('message_id')}\",\n            \"channel\": \"feishu\",\n            \"conversation_id\": chat_id,\n            \"conversation_type\": \"group\" if chat_type == \"group\" else \"person\",\n            \"display_name\": chat_id,\n            \"sender_id\": str((sender.get(\"sender_id\") or {}).get(\"open_id\") or \"\"),\n            \"sender_name\": str((sender.get(\"sender_id\") or {}).get(\"user_id\") or \"\"),\n            \"message_id\": str(message.get(\"message_id\") or \"\"),\n            \"message_text\": text,\n            \"attachments\": [],\n            \"timestamp\": now_iso(),\n            \"is_mention_to_bot\": mention,\n            \"require_mention\": chat_type == \"group\",\n        }\n\n    def _start_long_connection(self) -> None:\n        if self._long_conn_started:\n            return\n        self._long_conn_started = True\n        if not self.app_id or not self.app_secret:\n            _log(\"Feishu long connection skipped: missing app_id/app_secret\")\n            return\n\n        def _runner() -> None:\n            try:\n                import lark_oapi as lark\n\n                def _handle_message(data) -> None:\n                    try:\n                        payload = json.loads(lark.JSON.marshal(data) or \"{}\")\n                        normalized = self._normalize_message_event(payload.get(\"header\") or {}, payload.get(\"event\") or {})\n                        if normalized:\n                            self._enqueue_event(normalized)\n                    except Exception as exc:\n                        _log(f\"Feishu long connection event parse failed: {exc}\")\n\n                event_handler = lark.EventDispatcherHandler.builder(\n                    self.encrypt_key,\n                    self.verify_token,\n                ).register_p2_im_message_receive_v1(_handle_message).build()\n\n                client = lark.ws.Client(\n                    self.app_id,\n                    self.app_secret,\n                    event_handler=event_handler,\n                    log_level=lark.LogLevel.INFO,\n                )\n                _log(\"Feishu long connection started\")\n                client.start()\n            except Exception as exc:\n                _log(f\"Feishu long connection stopped: {exc}\")\n\n        self._long_conn_thread = threading.Thread(target=_runner, daemon=True, name=\"cheapclaw-feishu-long-conn\")\n        self._long_conn_thread.start()\n\n    def poll_events(self) -> List[Dict[str, Any]]:\n        if self.mode != \"long_connection\":\n            return []\n        with self._queue_lock:\n            items = list(self._queued_events)\n            self._queued_events.clear()\n            return items\n\n    def _tenant_access_token(self) -> str:\n        state = self.service.load_runtime_state()\n        cached = state.get(\"feishu_token\") or {}\n        expire_at = parse_iso(cached.get(\"expire_at\", \"\"))\n        if cached.get(\"token\") and expire_at and expire_at > datetime.now().astimezone() + timedelta(seconds=60):\n            return str(cached[\"token\"])\n        if not self.app_id or not self.app_secret:\n            return \"\"\n        response = requests.post(\n            f\"{self.api_root}/auth/v3/tenant_access_token/internal\",\n            json={\"app_id\": self.app_id, \"app_secret\": self.app_secret},\n            timeout=30,\n        )\n        response.raise_for_status()\n        data = response.json()\n        token = str(data.get(\"tenant_access_token\") or \"\")\n        expire_at = datetime.now().astimezone() + timedelta(seconds=int(data.get(\"expire\", 0) or 0))\n        state[\"feishu_token\"] = {\"token\": token, \"expire_at\": expire_at.isoformat(timespec=\"seconds\")}\n        self.service.save_runtime_state(state)\n        return token\n\n    def handle_webhook_post(self, path: str, body: bytes, headers: Dict[str, str]) -> Tuple[int, Dict[str, str], bytes]:\n        try:\n            payload = json.loads(body.decode(\"utf-8\"))\n        except Exception:\n            return 400, {\"Content-Type\": \"application/json\"}, b'{\"error\":\"invalid json\"}'\n\n        challenge = payload.get(\"challenge\")\n        if challenge:\n            return 200, {\"Content-Type\": \"application/json\"}, json.dumps({\"challenge\": challenge}).encode(\"utf-8\")\n\n        normalized = self._normalize_message_event(payload.get(\"header\") or {}, payload.get(\"event\") or {})\n        if normalized:\n            self.service.ingest_event(normalized)\n        return 200, {\"Content-Type\": \"application/json\"}, b'{\"ok\":true}'\n\n    def send_message(self, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None) -> Tuple[bool, str]:\n        token = self._tenant_access_token()\n        if not token:\n            return False, \"feishu app_id/app_secret are missing\"\n        last_remote_id = \"\"\n        normalized = self._normalize_attachments(attachments)\n        if message:\n            response = requests.post(\n                f\"{self.api_root}/im/v1/messages\",\n                params={\"receive_id_type\": \"chat_id\"},\n                headers={\"Authorization\": f\"Bearer {token}\", \"Content-Type\": \"application/json; charset=utf-8\"},\n                json={\"receive_id\": conversation_id, \"msg_type\": \"text\", \"content\": json.dumps({\"text\": message}, ensure_ascii=False)},\n                timeout=30,\n            )\n            if response.status_code >= 300:\n                return False, response.text\n            data = response.json()\n            last_remote_id = str(((data.get(\"data\") or {}).get(\"message_id\")) or \"\")\n        for item in normalized:\n            mime_type = item[\"mime_type\"]\n            is_image = mime_type.startswith(\"image/\")\n            upload_url = f\"{self.api_root}/im/v1/images\" if is_image else f\"{self.api_root}/im/v1/files\"\n            with open(item[\"path\"], \"rb\") as fh:\n                files = {\"image\" if is_image else \"file\": (item[\"filename\"], fh, mime_type)}\n                data_payload = {\"image_type\": \"message\"} if is_image else {\"file_type\": \"stream\", \"file_name\": item[\"filename\"]}\n                upload_resp = requests.post(\n                    upload_url,\n                    headers={\"Authorization\": f\"Bearer {token}\"},\n                    data=data_payload,\n                    files=files,\n                    timeout=60,\n                )\n            if upload_resp.status_code >= 300:\n                return False, upload_resp.text\n            upload_data = upload_resp.json()\n            key_name = \"image_key\" if is_image else \"file_key\"\n            media_key = str(((upload_data.get(\"data\") or {}).get(key_name)) or \"\")\n            if not media_key:\n                return False, json.dumps(upload_data, ensure_ascii=False)\n            msg_type = \"image\" if is_image else \"file\"\n            content = {key_name: media_key}\n            send_resp = requests.post(\n                f\"{self.api_root}/im/v1/messages\",\n                params={\"receive_id_type\": \"chat_id\"},\n                headers={\"Authorization\": f\"Bearer {token}\", \"Content-Type\": \"application/json; charset=utf-8\"},\n                json={\"receive_id\": conversation_id, \"msg_type\": msg_type, \"content\": json.dumps(content, ensure_ascii=False)},\n                timeout=30,\n            )\n            if send_resp.status_code >= 300:\n                return False, send_resp.text\n            data = send_resp.json()\n            last_remote_id = str(((data.get(\"data\") or {}).get(\"message_id\")) or \"\")\n        if not message and not normalized:\n            return False, \"feishu message or attachments are required\"\n        return True, last_remote_id\n\n\nclass WhatsAppCloudAdapter(ChannelAdapter):\n    name = \"whatsapp\"\n\n    def __init__(self, config: Dict[str, Any], service: \"CheapClawService\"):\n        super().__init__(config, service)\n        self.access_token = str(config.get(\"access_token\") or \"\").strip()\n        self.phone_number_id = str(config.get(\"phone_number_id\") or \"\").strip()\n        self.verify_token = str(config.get(\"verify_token\") or \"\").strip()\n        self.api_version = str(config.get(\"api_version\") or \"v21.0\").strip()\n        self.api_root = f\"https://graph.facebook.com/{self.api_version}\"\n\n    def handle_webhook_get(self, path: str, query: Dict[str, List[str]], headers: Dict[str, str]) -> Tuple[int, Dict[str, str], bytes]:\n        mode = (query.get(\"hub.mode\") or [\"\"])[0]\n        token = (query.get(\"hub.verify_token\") or [\"\"])[0]\n        challenge = (query.get(\"hub.challenge\") or [\"\"])[0]\n        if mode == \"subscribe\" and token and token == self.verify_token:\n            return 200, {\"Content-Type\": \"text/plain; charset=utf-8\"}, challenge.encode(\"utf-8\")\n        return 403, {\"Content-Type\": \"text/plain; charset=utf-8\"}, b\"forbidden\"\n\n    def handle_webhook_post(self, path: str, body: bytes, headers: Dict[str, str]) -> Tuple[int, Dict[str, str], bytes]:\n        try:\n            payload = json.loads(body.decode(\"utf-8\"))\n        except Exception:\n            return 400, {\"Content-Type\": \"application/json\"}, b'{\"error\":\"invalid json\"}'\n        for entry in payload.get(\"entry\", []):\n            for change in entry.get(\"changes\", []):\n                value = change.get(\"value\", {})\n                contacts = value.get(\"contacts\") or []\n                contact_name = str((contacts[0].get(\"profile\") or {}).get(\"name\") or \"\") if contacts else \"\"\n                for message in value.get(\"messages\", []) or []:\n                    text = str(((message.get(\"text\") or {}).get(\"body\")) or \"\").strip()\n                    from_id = str(message.get(\"from\") or \"\").strip()\n                    self.service.ingest_event({\n                        \"event_id\": f\"whatsapp_{message.get('id')}\",\n                        \"channel\": \"whatsapp\",\n                        \"conversation_id\": from_id,\n                        \"conversation_type\": \"person\",\n                        \"display_name\": contact_name or from_id,\n                        \"sender_id\": from_id,\n                        \"sender_name\": contact_name,\n                        \"message_id\": str(message.get(\"id\") or \"\"),\n                        \"message_text\": text,\n                        \"attachments\": [],\n                        \"timestamp\": now_iso(),\n                        \"is_mention_to_bot\": True,\n                        \"require_mention\": False,\n                    })\n        return 200, {\"Content-Type\": \"application/json\"}, b'{\"ok\":true}'\n\n    def send_message(self, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None) -> Tuple[bool, str]:\n        if not self.access_token or not self.phone_number_id:\n            return False, \"whatsapp access_token or phone_number_id is missing\"\n        last_remote_id = \"\"\n        normalized = self._normalize_attachments(attachments)\n        if message:\n            response = requests.post(\n                f\"{self.api_root}/{self.phone_number_id}/messages\",\n                headers={\"Authorization\": f\"Bearer {self.access_token}\", \"Content-Type\": \"application/json\"},\n                json={\"messaging_product\": \"whatsapp\", \"to\": conversation_id, \"type\": \"text\", \"text\": {\"body\": message}},\n                timeout=30,\n            )\n            if response.status_code >= 300:\n                return False, response.text\n            data = response.json()\n            if data.get(\"messages\"):\n                last_remote_id = str((data.get(\"messages\") or [{}])[0].get(\"id\") or \"\")\n        for item in normalized:\n            mime_type = item[\"mime_type\"]\n            media_type = \"image\" if mime_type.startswith(\"image/\") else \"document\"\n            with open(item[\"path\"], \"rb\") as fh:\n                files = {\"file\": (item[\"filename\"], fh, mime_type)}\n                upload_resp = requests.post(\n                    f\"{self.api_root}/{self.phone_number_id}/media\",\n                    headers={\"Authorization\": f\"Bearer {self.access_token}\"},\n                    data={\"messaging_product\": \"whatsapp\", \"type\": mime_type},\n                    files=files,\n                    timeout=60,\n                )\n            if upload_resp.status_code >= 300:\n                return False, upload_resp.text\n            upload_data = upload_resp.json()\n            media_id = str(upload_data.get(\"id\") or \"\")\n            if not media_id:\n                return False, json.dumps(upload_data, ensure_ascii=False)\n            payload = {\n                \"messaging_product\": \"whatsapp\",\n                \"to\": conversation_id,\n                \"type\": media_type,\n                media_type: {\"id\": media_id},\n            }\n            if media_type == \"document\":\n                payload[media_type][\"filename\"] = item[\"filename\"]\n            caption = item[\"caption\"] or (message if not last_remote_id else \"\")\n            if caption:\n                payload[media_type][\"caption\"] = caption\n            send_resp = requests.post(\n                f\"{self.api_root}/{self.phone_number_id}/messages\",\n                headers={\"Authorization\": f\"Bearer {self.access_token}\", \"Content-Type\": \"application/json\"},\n                json=payload,\n                timeout=30,\n            )\n            if send_resp.status_code >= 300:\n                return False, send_resp.text\n            data = send_resp.json()\n            if data.get(\"messages\"):\n                last_remote_id = str((data.get(\"messages\") or [{}])[0].get(\"id\") or \"\")\n        if not message and not normalized:\n            return False, \"whatsapp message or attachments are required\"\n        return True, last_remote_id\n\n\nclass CheapClawService:\n    def __init__(\n        self,\n        *,\n        user_data_root: str,\n        llm_config_path: Optional[str] = None,\n        default_agent_system: str = \"CheapClawWorkerGeneral\",\n        default_agent_name: str = \"worker_agent\",\n        supervisor_agent_system: str = \"CheapClawSupervisor\",\n        supervisor_agent_name: str = \"supervisor_agent\",\n        tools_dir: Optional[str] = None,\n        skills_dir: Optional[str] = None,\n        history_preview_limit: int = 50,\n        watchdog_interval_sec: Optional[int] = None,\n    ):\n        global ACTIVE_SERVICE\n        resolved_user_root = Path(user_data_root).expanduser().resolve()\n        self.paths = CheapClawPaths.from_user_data_root(resolved_user_root)\n        cheapclaw_cfg = _ensure_cheapclaw_app_config(self.paths)\n        _sync_root_app_config_from_cheapclaw(resolved_user_root, cheapclaw_cfg)\n        cheapclaw_settings = _extract_cheapclaw_settings(cheapclaw_cfg)\n        runtime_cfg = cheapclaw_cfg.get(\"runtime\", {}) if isinstance(cheapclaw_cfg, dict) else {}\n        asset_tools_dir = str((Path(tools_dir).expanduser().resolve()) if tools_dir else APP_TOOLS_ROOT.resolve())\n        self.sdk: InfiAgent = infiagent(\n            user_data_root=str(resolved_user_root),\n            llm_config_path=llm_config_path,\n            default_agent_system=default_agent_system,\n            default_agent_name=default_agent_name,\n            tools_dir=asset_tools_dir,\n            skills_dir=skills_dir,\n            action_window_steps=runtime_cfg.get(\"action_window_steps\"),\n            thinking_interval=runtime_cfg.get(\"thinking_interval\"),\n            fresh_enabled=runtime_cfg.get(\"fresh_enabled\"),\n            fresh_interval_sec=runtime_cfg.get(\"fresh_interval_sec\"),\n            seed_builtin_resources=False,\n        )\n        runtime = self.sdk.describe_runtime()\n        self.runtime = runtime\n        global SERVICE_LOG_PATH\n        SERVICE_LOG_PATH = Path(runtime[\"logs_dir\"]) / cheapclaw_settings[\"service_log_file\"]\n        self.panel_store = CheapClawPanelStore(self.paths, history_preview_limit=history_preview_limit)\n        self.default_agent_system = default_agent_system\n        self.default_agent_name = default_agent_name\n        self.supervisor_agent_system = supervisor_agent_system\n        self.supervisor_agent_name = supervisor_agent_name\n        self.app_tools_dir = asset_tools_dir\n        self.default_exposed_skills = cheapclaw_settings[\"default_exposed_skills\"]\n        self.default_mcp_servers = cheapclaw_settings[\"default_mcp_servers\"]\n        self.asset_agent_library_root = ASSET_AGENT_LIBRARY_ROOT.resolve()\n        self.asset_channels_example_path = ASSET_CHANNELS_EXAMPLE_PATH.resolve()\n        self.app_skills_root = APP_SKILLS_ROOT.resolve()\n        self._supervisor_lock = threading.Lock()\n        self.watchdog_interval_sec = max(60, int(watchdog_interval_sec or cheapclaw_settings[\"watchdog_interval_sec\"]))\n        self.adapters: Dict[str, ChannelAdapter] = {}\n        self.bootstrap_assets(force=False)\n        self.reload_adapters()\n        ACTIVE_SERVICE = self\n        _log(\n            f\"service initialized: user_data_root={runtime['user_data_root']} \"\n            f\"watchdog_interval_sec={self.watchdog_interval_sec}\"\n        )\n\n    @contextmanager\n    def _runtime_scope(self):\n        with self.sdk._runtime_scope():\n            yield\n\n    def bootstrap_assets(self, force: bool = False) -> Dict[str, Any]:\n        runtime = self.sdk.describe_runtime()\n        user_root = Path(runtime[\"user_data_root\"])\n        cheapclaw_cfg = _ensure_cheapclaw_app_config(self.paths)\n        _sync_root_app_config_from_cheapclaw(user_root, cheapclaw_cfg)\n        agent_root = Path(runtime[\"agent_library_dir\"])\n        skills_root = Path(runtime[\"skills_dir\"])\n        agent_root.mkdir(parents=True, exist_ok=True)\n        skills_root.mkdir(parents=True, exist_ok=True)\n        allowed_systems = {item.name for item in self.asset_agent_library_root.iterdir() if item.is_dir()}\n        if not runtime.get(\"seed_builtin_resources\", True):\n            for entry in list(agent_root.iterdir()):\n                if not entry.is_dir():\n                    continue\n                if entry.name in allowed_systems:\n                    continue\n                try:\n                    shutil.rmtree(entry)\n                except FileNotFoundError:\n                    pass\n\n        installed_systems = []\n        for system_dir in sorted(self.asset_agent_library_root.iterdir(), key=lambda item: item.name.lower()):\n            if not system_dir.is_dir():\n                continue\n            target = agent_root / system_dir.name\n            if force and target.exists():\n                shutil.rmtree(target)\n            shutil.copytree(system_dir, target, dirs_exist_ok=True)\n            installed_systems.append(str(target))\n\n        for skill_dir in sorted(self.app_skills_root.iterdir(), key=lambda item: item.name.lower()) if self.app_skills_root.exists() else []:\n            if not skill_dir.is_dir():\n                continue\n            target = skills_root / skill_dir.name\n            if force and target.exists():\n                shutil.rmtree(target)\n            shutil.copytree(skill_dir, target, dirs_exist_ok=True)\n\n        if force or not self.paths.channels_example_path.exists():\n            shutil.copyfile(self.asset_channels_example_path, self.paths.channels_example_path)\n        if not self.paths.channels_config_path.exists():\n            shutil.copyfile(self.asset_channels_example_path, self.paths.channels_config_path)\n\n        return {\n            \"status\": \"success\",\n            \"tools_dir\": self.app_tools_dir,\n            \"installed_agent_systems\": installed_systems,\n            \"supervisor_agent_system\": self.supervisor_agent_system,\n            \"worker_agent_system\": self.default_agent_system,\n            \"app_config_path\": str(self.paths.app_config_path),\n            \"app_config_example_path\": str(self.paths.app_config_example_path),\n            \"channels_config_path\": str(self.paths.channels_config_path),\n            \"channels_example_path\": str(self.paths.channels_example_path),\n            \"skills_root\": str(skills_root),\n        }\n\n    def describe_runtime(self) -> Dict[str, Any]:\n        return self.sdk.describe_runtime()\n\n    def list_agent_systems(self) -> Dict[str, Any]:\n        return self.sdk.list_agent_systems()\n\n    def list_global_skills(self) -> Dict[str, Any]:\n        return {\"status\": \"success\", \"skills_root\": self.runtime[\"skills_dir\"], \"skills\": list_global_skills(self.runtime[\"skills_dir\"])}\n\n    def _find_task_entry(self, task_id: str) -> Tuple[Optional[Dict[str, Any]], Optional[Dict[str, Any]]]:\n        target_task_id = str(Path(task_id).expanduser().resolve())\n        panel = self.panel_store.load_panel()\n        for channel_payload in panel.get(\"channels\", {}).values():\n            for conv in channel_payload.get(\"conversations\", {}).values():\n                for item in conv.get(\"linked_tasks\", []):\n                    if str(item.get(\"task_id\") or \"\") == target_task_id:\n                        return conv, item\n        return None, None\n\n    def get_task_preferences(self, *, task_id: str) -> Dict[str, Any]:\n        _, item = self._find_task_entry(task_id)\n        if item is None:\n            return {\n                \"status\": \"success\",\n                \"task_id\": str(Path(task_id).expanduser().resolve()),\n                \"default_exposed_skills\": list(self.default_exposed_skills),\n                \"mcp_servers\": list(self.default_mcp_servers),\n            }\n        return {\n            \"status\": \"success\",\n            \"task_id\": str(Path(task_id).expanduser().resolve()),\n            \"default_exposed_skills\": list(item.get(\"default_exposed_skills\") or self.default_exposed_skills),\n            \"mcp_servers\": list(item.get(\"mcp_servers\") or self.default_mcp_servers),\n        }\n\n    def update_task_preferences(\n        self,\n        *,\n        task_id: str,\n        default_exposed_skills: Optional[Iterable[str]] = None,\n        mcp_servers: Optional[List[Dict[str, Any]]] = None,\n    ) -> Dict[str, Any]:\n        with self._runtime_scope():\n            resolved_task_id = str(Path(task_id).expanduser().resolve())\n            conv, item = self._find_task_entry(resolved_task_id)\n            if conv is None or item is None:\n                return {\"status\": \"error\", \"error\": f\"task_id not found in panel: {resolved_task_id}\"}\n\n            task_patch: Dict[str, Any] = {\"updated_at\": now_iso()}\n            if default_exposed_skills is not None:\n                selected_skills = [str(name).strip() for name in default_exposed_skills if str(name).strip()]\n                set_task_visible_skills(resolved_task_id, selected_skills)\n                task_patch[\"default_exposed_skills\"] = selected_skills\n                task_patch[\"skills_dir\"] = \"\"\n            if mcp_servers is not None:\n                task_patch[\"mcp_servers\"] = [entry for entry in mcp_servers if isinstance(entry, dict)]\n\n            panel = update_conversation_task(\n                str(conv.get(\"channel\") or \"\"),\n                str(conv.get(\"conversation_id\") or \"\"),\n                resolved_task_id,\n                task_patch,\n                mark_dirty=False,\n            )\n            updated_item = next(\n                (linked for linked in panel.get(\"channels\", {}).get(str(conv.get(\"channel\") or \"\"), {}).get(\"conversations\", {}).get(str(conv.get(\"conversation_id\") or \"\"), {}).get(\"linked_tasks\", []) if linked.get(\"task_id\") == resolved_task_id),\n                {},\n            )\n            return {\n                \"status\": \"success\",\n                \"task_id\": resolved_task_id,\n                \"default_exposed_skills\": list(updated_item.get(\"default_exposed_skills\") or self.default_exposed_skills),\n                \"mcp_servers\": list(updated_item.get(\"mcp_servers\") or self.default_mcp_servers),\n                \"skills_dir\": str(updated_item.get(\"skills_dir\") or \"\"),\n            }\n\n    def load_runtime_state(self) -> Dict[str, Any]:\n        self.paths.runtime_state_path.parent.mkdir(parents=True, exist_ok=True)\n        return _load_json(self.paths.runtime_state_path, {\"webhook_server\": {}, \"telegram_offsets\": {}})\n\n    def save_runtime_state(self, payload: Dict[str, Any]) -> Dict[str, Any]:\n        _atomic_write_text(self.paths.runtime_state_path, json.dumps(payload, ensure_ascii=False, indent=2))\n        return payload\n\n    def load_channel_config(self) -> Dict[str, Any]:\n        return _load_json(self.paths.channels_config_path, _load_json(self.paths.channels_example_path, {}))\n\n    def reload_adapters(self) -> Dict[str, ChannelAdapter]:\n        config = self.load_channel_config()\n        adapters: Dict[str, ChannelAdapter] = {}\n        if config.get(\"telegram\", {}).get(\"enabled\"):\n            adapters[\"telegram\"] = TelegramAdapter(config.get(\"telegram\", {}), self)\n        if config.get(\"feishu\", {}).get(\"enabled\"):\n            adapters[\"feishu\"] = FeishuAdapter(config.get(\"feishu\", {}), self)\n        if config.get(\"whatsapp\", {}).get(\"enabled\"):\n            adapters[\"whatsapp\"] = WhatsAppCloudAdapter(config.get(\"whatsapp\", {}), self)\n        self.adapters = adapters\n        return adapters\n\n    def ingest_event(self, event: Dict[str, Any]) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return self.panel_store.record_social_message(**event)\n\n    def build_task_id(self, *, channel: str, conversation_id: str, task_name: str) -> str:\n        with self._runtime_scope():\n            return generate_task_id(channel, conversation_id, task_name)\n\n    def build_task_skills_overlay(self, *, task_id: str, exposed_skills: Optional[Iterable[str]] = None) -> Dict[str, Any]:\n        with self._runtime_scope():\n            payload = set_task_visible_skills(task_id, exposed_skills or [])\n        return {\"status\": \"success\", **payload}\n\n    def record_social_message(self, **kwargs) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return self.panel_store.record_social_message(**kwargs)\n\n    def start_task(self, **kwargs) -> Dict[str, Any]:\n        with self._runtime_scope():\n            channel = str(kwargs.get(\"channel\") or \"\").strip()\n            conversation_id = str(kwargs.get(\"conversation_id\") or \"\").strip()\n            task_name = str(kwargs.get(\"task_name\") or \"\").strip()\n            user_input = str(kwargs.get(\"user_input\") or \"\").strip()\n            if not channel or not conversation_id or not task_name or not user_input:\n                return {\"status\": \"error\", \"error\": \"channel, conversation_id, task_name and user_input are required\"}\n            resolved_task_id = str(Path(kwargs.get(\"task_id\") or self.build_task_id(channel=channel, conversation_id=conversation_id, task_name=task_name)).expanduser().resolve())\n            requested_agent_system = str(kwargs.get(\"agent_system\") or self.default_agent_system).strip() or self.default_agent_system\n            requested_agent_name = str(kwargs.get(\"agent_name\") or \"\").strip()\n            if requested_agent_system == self.supervisor_agent_system:\n                return {\"status\": \"error\", \"error\": f\"禁止使用 {self.supervisor_agent_system} 启动后台任务，主 agent 不能调用本身。\"}\n            systems_payload = self.sdk.list_agent_systems()\n            systems = {\n                str(item.get(\"name\") or \"\"): item\n                for item in systems_payload.get(\"agent_systems\", [])\n                if isinstance(item, dict)\n            }\n            system_info = systems.get(requested_agent_system, {})\n            available_agent_names = [str(name).strip() for name in system_info.get(\"agent_names\", []) if str(name).strip()]\n            if requested_agent_system == \"CheapClawWorkerGeneral\":\n                selected_agent_name = \"worker_agent\"\n            elif requested_agent_name and requested_agent_name in available_agent_names:\n                selected_agent_name = requested_agent_name\n            elif available_agent_names:\n                selected_agent_name = available_agent_names[0]\n            else:\n                selected_agent_name = requested_agent_name or self.default_agent_name\n            merged_config = dict(kwargs.get(\"config\") or {})\n            merged_config.setdefault(\"tools_dir\", self.app_tools_dir)\n            exposed_skills = kwargs.get(\"exposed_skills\")\n            task_preferences = self.get_task_preferences(task_id=resolved_task_id)\n            if exposed_skills is None:\n                exposed_skills = list(task_preferences.get(\"default_exposed_skills\") or self.default_exposed_skills)\n            else:\n                merged_visible = []\n                for item in list(task_preferences.get(\"default_exposed_skills\") or self.default_exposed_skills) + list(exposed_skills or []):\n                    name = str(item).strip()\n                    if name and name not in merged_visible:\n                        merged_visible.append(name)\n                exposed_skills = merged_visible\n            if \"mcp_servers\" not in merged_config:\n                merged_config[\"mcp_servers\"] = list(task_preferences.get(\"mcp_servers\") or self.default_mcp_servers)\n            if exposed_skills is not None:\n                merged_config[\"visible_skills\"] = list(exposed_skills)\n            existing_hooks = list(merged_config.get(\"tool_hooks\") or [])\n            if not any(str(item.get(\"callback\") or \"\") == FINAL_OUTPUT_HOOK_CALLBACK for item in existing_hooks if isinstance(item, dict)):\n                existing_hooks.append({\n                    \"name\": \"cheapclaw-final-output\",\n                    \"callback\": FINAL_OUTPUT_HOOK_CALLBACK,\n                    \"when\": \"after\",\n                    \"tool_names\": [\"final_output\"],\n                    \"include_arguments\": False,\n                    \"include_result\": True,\n                })\n            merged_config[\"tool_hooks\"] = existing_hooks\n            dispatch_input = f\"{user_input}\\n\\n[dispatched_at {now_iso()}]\"\n            result = self.sdk.start_background_task(\n                task_id=resolved_task_id,\n                user_input=dispatch_input,\n                agent_system=requested_agent_system,\n                agent_name=selected_agent_name,\n                force_new=bool(kwargs.get(\"force_new\", False)),\n                config=merged_config or None,\n            )\n            if result.get(\"status\") != \"success\":\n                return result\n            snapshot = self.sdk.task_snapshot(task_id=resolved_task_id)\n            set_task_visible_skills(resolved_task_id, exposed_skills or [])\n            latest_instruction = snapshot.get(\"latest_instruction\") or {}\n            if not isinstance(latest_instruction, dict):\n                latest_instruction = {}\n            update_conversation_task(\n                channel,\n                conversation_id,\n                resolved_task_id,\n                {\n                    \"agent_system\": result.get(\"agent_system\") or requested_agent_system,\n                    \"agent_name\": result.get(\"agent_name\") or selected_agent_name,\n                    \"status\": \"running\",\n                    \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n                    \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n                    \"log_path\": result.get(\"log_path\", \"\"),\n                    \"skills_dir\": \"\",\n                    \"default_exposed_skills\": list(exposed_skills or []),\n                    \"mcp_servers\": list(merged_config.get(\"mcp_servers\") or []),\n                    \"last_thinking\": snapshot.get(\"latest_thinking\", \"\"),\n                    \"last_thinking_at\": snapshot.get(\"latest_thinking_at\", \"\"),\n                    \"last_final_output\": snapshot.get(\"last_final_output\", \"\"),\n                    \"last_final_output_at\": snapshot.get(\"last_final_output_at\", \"\"),\n                    \"last_action_at\": snapshot.get(\"last_updated\", \"\"),\n                    \"last_log_at\": now_iso(),\n                    \"last_launch_at\": now_iso(),\n                    \"last_watchdog_note\": \"task launched\",\n                    \"user_input\": str((snapshot.get(\"runtime\") or {}).get(\"user_input\") or dispatch_input or \"\"),\n                    \"latest_instruction\": str(latest_instruction.get(\"instruction\") or dispatch_input or \"\"),\n                    \"created_at\": next(\n                        (\n                            str(existing.get(\"created_at\") or \"\")\n                            for existing in self.panel_store.load_panel().get(\"channels\", {}).get(channel, {}).get(\"conversations\", {}).get(conversation_id, {}).get(\"linked_tasks\", [])\n                            if existing.get(\"task_id\") == resolved_task_id\n                        ),\n                        now_iso(),\n                    ) or now_iso(),\n                },\n                mark_dirty=True,\n            )\n            source_message_ids = kwargs.get(\"source_message_ids\") or []\n            if source_message_ids:\n                bind_messages_to_task(\n                    channel,\n                    conversation_id,\n                    resolved_task_id,\n                    source_message_ids,\n                    note=\"task started from supervisor decision\",\n                )\n            return {\n                **result,\n                \"requested_agent_name\": requested_agent_name,\n                \"selected_agent_name\": selected_agent_name,\n                \"available_agent_names\": available_agent_names,\n                \"overlay_skills\": overlay_result,\n                \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n                \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n            }\n\n    def add_task_message(\n        self,\n        *,\n        task_id: str,\n        message: str,\n        source: str = \"agent\",\n        resume_if_needed: bool = False,\n        agent_system: Optional[str] = None,\n        channel: Optional[str] = None,\n        conversation_id: Optional[str] = None,\n        source_message_ids: Optional[Iterable[str]] = None,\n    ) -> Dict[str, Any]:\n        with self._runtime_scope():\n            timestamped = f\"{message}\\n\\n[message_appended_at {now_iso()}]\"\n            result = self.sdk.add_message(timestamped, task_id=str(Path(task_id).expanduser().resolve()), source=source, resume_if_needed=resume_if_needed, agent_system=agent_system)\n            if result.get(\"status\") == \"success\" and channel and conversation_id and source_message_ids:\n                bind_messages_to_task(\n                    str(channel),\n                    str(conversation_id),\n                    str(Path(task_id).expanduser().resolve()),\n                    source_message_ids,\n                    note=\"message appended to existing task\",\n                )\n            return result\n\n    def fresh_task(self, *, task_id: str, reason: str = \"\") -> Dict[str, Any]:\n        with self._runtime_scope():\n            return self.sdk.fresh(task_id=str(Path(task_id).expanduser().resolve()), reason=reason)\n\n    def reset_task(self, *, task_id: str, preserve_history: bool = True, kill_background_processes: bool = True, reason: str = \"\") -> Dict[str, Any]:\n        with self._runtime_scope():\n            return self.sdk.reset_task(task_id=str(Path(task_id).expanduser().resolve()), preserve_history=preserve_history, kill_background_processes=kill_background_processes, reason=reason)\n\n    def get_task_snapshot(self, *, task_id: str) -> Dict[str, Any]:\n        with self._runtime_scope():\n            snapshot = self.sdk.task_snapshot(task_id=str(Path(task_id).expanduser().resolve()))\n            panel = self.panel_store.load_panel()\n            for channel_payload in panel.get(\"channels\", {}).values():\n                for conv in channel_payload.get(\"conversations\", {}).values():\n                    for item in conv.get(\"linked_tasks\", []):\n                        if item.get(\"task_id\") == snapshot[\"task_id\"]:\n                            snapshot[\"log_path\"] = item.get(\"log_path\", \"\")\n                            snapshot[\"conversation\"] = {\"channel\": conv.get(\"channel\"), \"conversation_id\": conv.get(\"conversation_id\"), \"display_name\": conv.get(\"display_name\")}\n                            return snapshot\n            snapshot.setdefault(\"log_path\", \"\")\n            return snapshot\n\n    def refresh_task_view(self, *, channel: str, conversation_id: str, task_id: str, mark_dirty: bool = False) -> Dict[str, Any]:\n        snapshot = self.get_task_snapshot(task_id=task_id)\n        patch = {\n            \"status\": \"running\" if snapshot.get(\"running\") else \"idle\",\n            \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n            \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n            \"last_thinking\": snapshot.get(\"latest_thinking\", \"\"),\n            \"last_thinking_at\": snapshot.get(\"latest_thinking_at\", \"\"),\n            \"last_final_output\": snapshot.get(\"last_final_output\", \"\"),\n            \"last_final_output_at\": snapshot.get(\"last_final_output_at\", \"\"),\n            \"last_action_at\": snapshot.get(\"last_updated\", \"\"),\n            \"last_log_at\": now_iso(),\n        }\n        return update_conversation_task(channel, conversation_id, str(Path(task_id).expanduser().resolve()), patch, mark_dirty=mark_dirty)\n\n    def process_task_events(self) -> List[Dict[str, Any]]:\n        with self._runtime_scope():\n            panel = self.panel_store.load_panel()\n            results: List[Dict[str, Any]] = []\n            changed = False\n            for event in list_task_events():\n                event_id = str(event.get(\"event_id\") or \"\")\n                event_type = str(event.get(\"event_type\") or \"\")\n                task_id = str(event.get(\"task_id\") or \"\")\n                observed_at = str(event.get(\"observed_at\") or now_iso())\n                matched = False\n\n                if event_type == \"task_final_output\" and task_id:\n                    for channel_payload in panel.get(\"channels\", {}).values():\n                        for conv in channel_payload.get(\"conversations\", {}).values():\n                            for item in conv.get(\"linked_tasks\", []):\n                                if item.get(\"task_id\") != task_id:\n                                    continue\n                                previous_final_at = str(item.get(\"last_final_output_at\") or \"\")\n                                previous_output = str(item.get(\"last_final_output\") or \"\")\n                                item.update({\n                                    \"status\": \"idle\",\n                                    \"last_final_output\": str(event.get(\"output\") or \"\"),\n                                    \"last_final_output_at\": observed_at,\n                                    \"last_action_at\": observed_at,\n                                    \"pid_alive\": False,\n                                    \"watchdog_observation\": \"\",\n                                    \"watchdog_suspected_state\": \"healthy\",\n                                })\n                                if previous_final_at != observed_at or previous_output != str(event.get(\"output\") or \"\"):\n                                    conv.setdefault(\"pending_events\", []).append({\n                                        \"type\": \"task_completed\",\n                                        \"task_id\": task_id,\n                                        \"timestamp\": observed_at,\n                                    })\n                                    conv[\"dirty\"] = True\n                                    panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n                                conv[\"updated_at\"] = now_iso()\n                                conv[\"running_task_count\"] = sum(1 for linked in conv.get(\"linked_tasks\", []) if linked.get(\"status\") == \"running\")\n                                conv[\"unread_event_count\"] = len(conv.get(\"pending_events\", []))\n                                matched = True\n                                changed = True\n                                break\n                            if matched:\n                                break\n                        if matched:\n                            break\n\n                ack_task_event(event_id)\n                results.append({\n                    \"event_id\": event_id,\n                    \"event_type\": event_type,\n                    \"task_id\": task_id,\n                    \"matched\": matched,\n                })\n\n            if changed:\n                self.panel_store.save_panel(panel)\n            return results\n\n    def reconcile_task_statuses(self) -> List[Dict[str, Any]]:\n        observations: List[Dict[str, Any]] = []\n        panel = self.panel_store.load_panel()\n        changed = False\n        for channel_name, channel_payload in panel.get(\"channels\", {}).items():\n            for conversation_id, conv in channel_payload.get(\"conversations\", {}).items():\n                for item in conv.get(\"linked_tasks\", []):\n                    task_id = str(item.get(\"task_id\") or \"\")\n                    if not task_id:\n                        continue\n                    snapshot = self.get_task_snapshot(task_id=task_id)\n                    now_dt = datetime.now().astimezone()\n                    latest_instruction = snapshot.get(\"latest_instruction\") or {}\n                    if not isinstance(latest_instruction, dict):\n                        latest_instruction = {}\n                    log_path = Path(item.get(\"log_path\") or snapshot.get(\"log_path\") or \"\")\n                    last_log_at = datetime.fromtimestamp(log_path.stat().st_mtime).astimezone().isoformat(timespec=\"seconds\") if log_path.exists() else \"\"\n                    patch = {\n                        \"status\": \"running\" if snapshot.get(\"running\") else \"idle\",\n                        \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n                        \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n                        \"last_thinking\": snapshot.get(\"latest_thinking\", \"\"),\n                        \"last_thinking_at\": snapshot.get(\"latest_thinking_at\", \"\"),\n                        \"last_final_output\": snapshot.get(\"last_final_output\", \"\"),\n                        \"last_final_output_at\": snapshot.get(\"last_final_output_at\", \"\"),\n                        \"last_action_at\": snapshot.get(\"last_updated\", \"\"),\n                        \"last_log_at\": last_log_at,\n                        \"last_launch_at\": str(item.get(\"last_launch_at\") or \"\"),\n                        \"pid_alive\": bool(snapshot.get(\"running\")),\n                        \"watchdog_observation\": \"\" if snapshot.get(\"last_final_output\") else str(item.get(\"watchdog_observation\") or \"\"),\n                        \"watchdog_suspected_state\": \"healthy\" if snapshot.get(\"last_final_output\") else str(item.get(\"watchdog_suspected_state\") or \"\"),\n                        \"user_input\": str((snapshot.get(\"runtime\") or {}).get(\"user_input\") or item.get(\"user_input\") or \"\"),\n                        \"latest_instruction\": str(latest_instruction.get(\"instruction\") or item.get(\"latest_instruction\") or \"\"),\n                    }\n                    final_changed = (\n                        bool(snapshot.get(\"last_final_output\"))\n                        and (\n                            str(item.get(\"last_final_output_at\") or \"\") != str(snapshot.get(\"last_final_output_at\") or \"\")\n                            or str(item.get(\"last_final_output\") or \"\") != str(snapshot.get(\"last_final_output\") or \"\")\n                        )\n                    )\n                    failed_changed = (\n                        not snapshot.get(\"running\")\n                        and not snapshot.get(\"last_final_output\")\n                        and (\n                            (parse_iso(str(item.get(\"last_launch_at\") or \"\")) or now_dt) <= now_dt - timedelta(seconds=45)\n                        )\n                        and (\n                            not last_log_at\n                            or (parse_iso(last_log_at) is not None and parse_iso(last_log_at) <= now_dt - timedelta(seconds=15))\n                        )\n                        and (\n                            str(item.get(\"status\") or \"\") == \"running\"\n                            or bool(item.get(\"pid_alive\"))\n                        )\n                    )\n                    if final_changed:\n                        conv.setdefault(\"pending_events\", []).append({\n                            \"type\": \"task_completed\",\n                            \"task_id\": task_id,\n                            \"timestamp\": str(snapshot.get(\"last_final_output_at\") or now_iso()),\n                        })\n                        conv[\"dirty\"] = True\n                        panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n                    elif failed_changed:\n                        conv.setdefault(\"pending_events\", []).append({\n                            \"type\": \"task_failed\",\n                            \"task_id\": task_id,\n                            \"timestamp\": str(snapshot.get(\"last_updated\") or now_iso()),\n                            \"suspected_state\": \"process_dead\",\n                            \"summary\": \"task stopped without final_output\",\n                        })\n                        conv[\"dirty\"] = True\n                        panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n                    if any(str(item.get(key) or \"\") != str(value or \"\") for key, value in patch.items()):\n                        item.update(patch)\n                        changed = True\n                    observations.append({\"channel\": channel_name, \"conversation_id\": conversation_id, \"task_id\": task_id, **patch})\n                conv[\"running_task_count\"] = sum(1 for linked in conv.get(\"linked_tasks\", []) if linked.get(\"status\") == \"running\")\n                conv[\"has_stale_running_tasks\"] = any(\n                    linked.get(\"status\") == \"running\" and not linked.get(\"pid_alive\")\n                    for linked in conv.get(\"linked_tasks\", [])\n                )\n                conv[\"unread_event_count\"] = len(conv.get(\"pending_events\", []))\n        if changed:\n            self.panel_store.save_panel(panel)\n        return observations\n\n    def queue_message(self, *, channel: str, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None, metadata: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return queue_outbound_message(channel=channel, conversation_id=conversation_id, message=message, attachments=attachments, metadata=metadata)\n\n    def send_message_now(self, *, channel: str, conversation_id: str, message: str, attachments: Optional[List[Dict[str, Any]]] = None) -> Dict[str, Any]:\n        adapter = self.adapters.get(str(channel).strip())\n        if adapter is None:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": f\"adapter not configured: {channel}\"}\n        ok, remote_id = adapter.send_message(str(conversation_id), str(message), attachments or [])\n        if not ok:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": str(remote_id)}\n        append_history(\n            channel=str(channel),\n            conversation_id=str(conversation_id),\n            event={\n                \"message_id\": str(remote_id or uuid.uuid4().hex[:12]),\n                \"timestamp\": now_iso(),\n                \"sender_id\": \"cheapclaw\",\n                \"sender_name\": \"cheapclaw\",\n                \"text\": str(message or \"\"),\n                \"attachments\": attachments or [],\n                \"is_mention_to_bot\": False,\n                \"direction\": \"outbound\",\n            },\n        )\n        return {\n            \"status\": \"success\",\n            \"output\": f\"sent outbound message {remote_id}\",\n            \"remote_id\": str(remote_id or \"\"),\n            \"channel\": str(channel),\n            \"conversation_id\": str(conversation_id),\n        }\n\n    def process_outbox(self) -> List[Dict[str, Any]]:\n        with self._runtime_scope():\n            results = []\n            for event in list_outbox_events():\n                channel = str(event.get(\"channel\") or \"\").strip()\n                adapter = self.adapters.get(channel)\n                if adapter is None:\n                    results.append({\"event_id\": event.get(\"event_id\"), \"status\": \"error\", \"error\": f\"adapter not configured: {channel}\"})\n                    continue\n                ok, remote_id = adapter.send_message(str(event.get(\"conversation_id\") or \"\"), str(event.get(\"message\") or \"\"), event.get(\"attachments\") or [])\n                if ok:\n                    ack_outbox_event(str(event.get(\"event_id\") or \"\"))\n                    append_history(\n                        channel=channel,\n                        conversation_id=str(event.get(\"conversation_id\") or \"\"),\n                        event={\n                            \"message_id\": remote_id or str(event.get(\"event_id\") or \"\"),\n                            \"timestamp\": now_iso(),\n                            \"sender_id\": \"cheapclaw\",\n                            \"sender_name\": \"cheapclaw\",\n                            \"text\": str(event.get(\"message\") or \"\"),\n                            \"attachments\": event.get(\"attachments\") or [],\n                            \"is_mention_to_bot\": False,\n                            \"direction\": \"outbound\",\n                        },\n                    )\n                    results.append({\"event_id\": event.get(\"event_id\"), \"status\": \"success\", \"remote_id\": remote_id})\n                else:\n                    results.append({\"event_id\": event.get(\"event_id\"), \"status\": \"error\", \"error\": remote_id})\n            return results\n\n    def poll_channels(self) -> List[Dict[str, Any]]:\n        events = []\n        for adapter in self.adapters.values():\n            for event in adapter.poll_events():\n                self.ingest_event(event)\n                events.append(event)\n        return events\n\n    def tick_watchdog(self) -> List[Dict[str, Any]]:\n        observations = []\n        panel = self.panel_store.load_panel()\n        for channel_name, channel_payload in panel.get(\"channels\", {}).items():\n            for conversation_id, conv in channel_payload.get(\"conversations\", {}).items():\n                for item in conv.get(\"linked_tasks\", []):\n                    task_id = item.get(\"task_id\")\n                    if not task_id:\n                        continue\n                    snapshot = self.get_task_snapshot(task_id=task_id)\n                    log_path = Path(item.get(\"log_path\") or snapshot.get(\"log_path\") or \"\")\n                    last_log_at = datetime.fromtimestamp(log_path.stat().st_mtime).astimezone().isoformat(timespec=\"seconds\") if log_path.exists() else \"\"\n                    latest_thinking_at = snapshot.get(\"latest_thinking_at\", \"\")\n                    suspected = \"healthy\"\n                    note = \"\"\n                    if snapshot.get(\"running\") and not latest_thinking_at and not last_log_at:\n                        suspected = \"quiet_but_alive\"\n                        note = \"running but no thinking/log timestamp yet\"\n                    elif snapshot.get(\"running\") and latest_thinking_at:\n                        thinking_dt = parse_iso(latest_thinking_at)\n                        if thinking_dt and thinking_dt < datetime.now().astimezone() - timedelta(hours=1):\n                            suspected = \"possibly_stalled\"\n                            note = \"thinking has not moved for over 1 hour\"\n                    elif not snapshot.get(\"running\") and not snapshot.get(\"last_final_output\"):\n                        suspected = \"process_dead\"\n                        note = \"task stopped without final output\"\n                    patch = {\n                        \"status\": \"running\" if snapshot.get(\"running\") else \"idle\",\n                        \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n                        \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n                        \"last_thinking\": snapshot.get(\"latest_thinking\", \"\"),\n                        \"last_thinking_at\": latest_thinking_at,\n                        \"last_final_output\": snapshot.get(\"last_final_output\", \"\"),\n                        \"last_final_output_at\": snapshot.get(\"last_final_output_at\", \"\"),\n                        \"last_action_at\": snapshot.get(\"last_updated\", \"\"),\n                        \"last_log_at\": last_log_at,\n                        \"pid_alive\": snapshot.get(\"running\"),\n                        \"watchdog_observation\": note,\n                        \"watchdog_suspected_state\": suspected,\n                    }\n                    if item.get(\"last_final_output_at\") != snapshot.get(\"last_final_output_at\") and snapshot.get(\"last_final_output\"):\n                        conv.setdefault(\"pending_events\", []).append({\"type\": \"task_completed\", \"task_id\": task_id, \"timestamp\": now_iso()})\n                        conv[\"dirty\"] = True\n                        panel[\"service_state\"][\"main_agent_dirty\"] = True\n                    elif item.get(\"watchdog_suspected_state\") != suspected and suspected != \"healthy\":\n                        conv.setdefault(\"pending_events\", []).append({\"type\": \"watchdog_tick\", \"task_id\": task_id, \"suspected_state\": suspected, \"timestamp\": now_iso()})\n                        conv[\"dirty\"] = True\n                        panel[\"service_state\"][\"main_agent_dirty\"] = True\n                    item.update(patch)\n                    observations.append({\"channel\": channel_name, \"conversation_id\": conversation_id, \"task_id\": task_id, **patch})\n                conv[\"running_task_count\"] = sum(1 for item in conv.get(\"linked_tasks\", []) if item.get(\"status\") == \"running\")\n                conv[\"unread_event_count\"] = len(conv.get(\"pending_events\", []))\n        panel[\"service_state\"][\"watchdog_last_run_at\"] = now_iso()\n        self.panel_store.save_panel(panel)\n        return observations\n\n    def _watchdog_due(self) -> bool:\n        panel = self.panel_store.load_panel()\n        last_run_at = parse_iso(str(panel.get(\"service_state\", {}).get(\"watchdog_last_run_at\") or \"\"))\n        if last_run_at is None:\n            return True\n        return last_run_at <= datetime.now().astimezone() - timedelta(seconds=self.watchdog_interval_sec)\n\n    def tick_plans(self) -> List[Dict[str, Any]]:\n        payload = load_plans()\n        results = []\n        now = datetime.now().astimezone()\n        changed = False\n        for plan in payload.get(\"plans\", []):\n            if not plan.get(\"enabled\", True):\n                continue\n            due_at = parse_iso(str(plan.get(\"next_run_at\") or \"\"))\n            if not due_at or due_at > now:\n                continue\n            task_id = str(plan.get(\"task_id\") or \"\").strip()\n            if plan.get(\"scope\") == \"task\" and task_id:\n                snapshot = self.get_task_snapshot(task_id=task_id)\n                if snapshot.get(\"running\"):\n                    plan[\"last_result\"] = \"deferred: task running\"\n                    plan[\"next_run_at\"] = (now + timedelta(minutes=5)).isoformat(timespec=\"seconds\")\n                    changed = True\n                    results.append({\"plan_id\": plan.get(\"plan_id\"), \"status\": \"deferred\"})\n                    continue\n                self.add_task_message(task_id=task_id, message=str(plan.get(\"message\") or \"scheduled task tick\"), source=\"system\", resume_if_needed=True)\n                plan[\"last_result\"] = \"appended task message\"\n            else:\n                channel = str(plan.get(\"channel\") or \"\").strip()\n                conversation_id = str(plan.get(\"conversation_id\") or \"\").strip()\n                if channel and conversation_id:\n                    panel = load_panel()\n                    conv = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n                    conv.setdefault(\"pending_events\", []).append({\"type\": \"plan_tick\", \"plan_id\": plan.get(\"plan_id\"), \"timestamp\": now_iso(), \"message\": str(plan.get(\"message\") or \"\")})\n                    conv[\"dirty\"] = True\n                    panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n                    save_panel(panel)\n                plan[\"last_result\"] = \"queued main_agent tick\"\n            plan[\"last_run_at\"] = now_iso()\n            schedule_type = str(plan.get(\"schedule_type\") or \"\").strip()\n            if schedule_type in {\"daily\", \"weekly\"} and str(plan.get(\"time_of_day\") or \"\").strip():\n                plan[\"next_run_at\"] = compute_next_scheduled_run(\n                    schedule_type=schedule_type,\n                    time_of_day=str(plan.get(\"time_of_day\") or \"\"),\n                    days_of_week=plan.get(\"days_of_week\") or [],\n                    now=now,\n                )\n            elif int(plan.get(\"interval_sec\") or 0) > 0:\n                plan[\"next_run_at\"] = (now + timedelta(seconds=int(plan.get(\"interval_sec\") or 0))).isoformat(timespec=\"seconds\")\n            else:\n                plan[\"enabled\"] = False\n            changed = True\n            results.append({\"plan_id\": plan.get(\"plan_id\"), \"status\": plan.get(\"last_result\")})\n        if changed:\n            save_plans(payload)\n        return results\n\n    def _build_supervisor_input(self, reason: str) -> str:\n        panel = self.panel_store.load_panel()\n        dirty = self.panel_store.dirty_conversations()\n        summaries = []\n        for conv in dirty:\n            messages = [item for item in conv.get(\"messages\", []) if isinstance(item, dict)]\n            pending_events = [item for item in conv.get(\"pending_events\", []) if isinstance(item, dict)]\n            new_user_messages = []\n            task_events = []\n            linked_by_task_id = {\n                str(item.get(\"task_id\") or \"\"): item\n                for item in conv.get(\"linked_tasks\", [])\n                if str(item.get(\"task_id\") or \"\")\n            }\n\n            for event in pending_events:\n                event_type = str(event.get(\"type\") or \"\").strip()\n                if event_type == \"social_message\":\n                    message_id = str(event.get(\"message_id\") or \"\").strip()\n                    matched = next(\n                        (\n                            message for message in messages\n                            if str(message.get(\"message_id\") or \"\") == message_id\n                        ),\n                        {},\n                    )\n                    new_user_messages.append({\n                        \"channel\": str(conv.get(\"channel\") or \"\"),\n                        \"conversation_id\": str(conv.get(\"conversation_id\") or \"\"),\n                        \"message_id\": message_id,\n                        \"timestamp\": str(matched.get(\"timestamp\") or event.get(\"timestamp\") or \"\"),\n                        \"text\": str(matched.get(\"text\") or \"\"),\n                    })\n                    continue\n\n                if event_type == \"task_completed\":\n                    task_id = str(event.get(\"task_id\") or \"\").strip()\n                    linked = linked_by_task_id.get(task_id, {})\n                    task_events.append({\n                        \"type\": \"task_completed\",\n                        \"channel\": str(conv.get(\"channel\") or \"\"),\n                        \"conversation_id\": str(conv.get(\"conversation_id\") or \"\"),\n                        \"task_id\": task_id,\n                        \"task_input\": _short_text(str(\n                            linked.get(\"latest_instruction\")\n                            or linked.get(\"last_instruction\")\n                            or linked.get(\"user_input\")\n                            or \"\"\n                        ).strip(), limit=360),\n                        \"output\": _short_text(str(linked.get(\"last_final_output\") or \"\"), limit=420),\n                        \"output_at\": str(linked.get(\"last_final_output_at\") or event.get(\"timestamp\") or \"\"),\n                    })\n                    continue\n\n                task_events.append({\n                    \"type\": event_type,\n                    \"channel\": str(conv.get(\"channel\") or \"\"),\n                    \"conversation_id\": str(conv.get(\"conversation_id\") or \"\"),\n                    \"task_id\": str(event.get(\"task_id\") or \"\").strip(),\n                    \"timestamp\": str(event.get(\"timestamp\") or \"\"),\n                    \"summary\": str(event.get(\"message\") or event.get(\"note\") or event.get(\"suspected_state\") or \"\")[:240],\n                })\n\n            summaries.append({\n                \"channel\": conv.get(\"channel\"),\n                \"conversation_id\": conv.get(\"conversation_id\"),\n                \"display_name\": conv.get(\"display_name\"),\n                \"conversation_type\": conv.get(\"conversation_type\"),\n                \"new_user_messages\": new_user_messages,\n                \"task_events\": task_events,\n            })\n        payload = {\n            \"trigger_reason\": reason,\n            \"summary_rules\": \"这里只给所有新用户消息和所有新任务事件的短摘要。若你判断本次 dirty 可能和旧消息或旧 task 相关，再主动查询历史对话、任务列表或完整面板。\",\n            \"dirty_conversations\": summaries,\n            \"service_state\": {\n                \"main_agent_running\": bool(panel.get(\"service_state\", {}).get(\"main_agent_running\")),\n                \"main_agent_last_started_at\": str(panel.get(\"service_state\", {}).get(\"main_agent_last_started_at\") or \"\"),\n                \"watchdog_last_run_at\": str(panel.get(\"service_state\", {}).get(\"watchdog_last_run_at\") or \"\"),\n            },\n        }\n        return json.dumps(payload, ensure_ascii=False, indent=2)\n\n    def run_supervisor_once(self, reason: str = \"dirty_panel\") -> Dict[str, Any]:\n        if not self._supervisor_lock.acquire(blocking=False):\n            panel = self.panel_store.load_panel()\n            panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n            self.panel_store.save_panel(panel)\n            return {\"status\": \"busy\", \"output\": \"supervisor already running\"}\n        run_id = f\"sup_{uuid.uuid4().hex[:10]}\"\n        try:\n            self.panel_store.set_main_agent_state(running=True, run_id=run_id)\n            result = self.sdk.run(\n                self._build_supervisor_input(reason),\n                task_id=str(self.paths.supervisor_task_id),\n                agent_system=self.supervisor_agent_system,\n                agent_name=self.supervisor_agent_name,\n                force_new=False,\n            )\n            return result\n        finally:\n            self.panel_store.set_main_agent_state(running=False)\n            self._supervisor_lock.release()\n\n    def run_once(self) -> Dict[str, Any]:\n        polled = self.poll_channels()\n        plans = self.tick_plans()\n        task_events = self.process_task_events()\n        reconciled = self.reconcile_task_statuses()\n        watchdog = self.tick_watchdog() if self._watchdog_due() else []\n        outbox = self.process_outbox()\n        panel = self.panel_store.load_panel()\n        supervisor = None\n        if panel.get(\"service_state\", {}).get(\"main_agent_dirty\") and self.panel_store.dirty_conversations():\n            supervisor = self.run_supervisor_once(reason=\"dirty_panel\")\n            outbox.extend(self.process_outbox())\n        return {\n            \"status\": \"success\",\n            \"polled_events\": polled,\n            \"plan_results\": plans,\n            \"task_events\": task_events,\n            \"reconciled_tasks\": reconciled,\n            \"watchdog\": watchdog,\n            \"outbox\": outbox,\n            \"supervisor\": supervisor,\n        }\n\n    def run_forever(self, poll_interval: int = 15) -> None:\n        poll_interval = max(1, int(poll_interval))\n        while True:\n            try:\n                result = self.run_once()\n                _log(\n                    \"cycle complete: \"\n                    f\"polled={len(result.get('polled_events', []))}, \"\n                    f\"plans={len(result.get('plan_results', []))}, \"\n                    f\"task_events={len(result.get('task_events', []))}, \"\n                    f\"reconciled={len(result.get('reconciled_tasks', []))}, \"\n                    f\"watchdog={len(result.get('watchdog', []))}, \"\n                    f\"outbox={len(result.get('outbox', []))}, \"\n                    f\"supervisor={result.get('supervisor', {}).get('status') if isinstance(result.get('supervisor'), dict) else 'idle'}\"\n                )\n            except Exception as exc:\n                _log(f\"cycle failed: {exc}\")\n                traceback.print_exc()\n            time.sleep(poll_interval)\n\n    @staticmethod\n    def _task_created_sort_value(task: Dict[str, Any]) -> str:\n        created_at = str(task.get(\"created_at\") or \"\")\n        if created_at:\n            return created_at\n        task_id = str(task.get(\"task_id\") or \"\")\n        try:\n            name = Path(task_id).name\n            stamp = name.split(\"_\", 2)[:2]\n            if len(stamp) == 2:\n                parsed = datetime.strptime(\"_\".join(stamp), \"%Y%m%d_%H%M%S\")\n                return parsed.astimezone().isoformat(timespec=\"seconds\")\n        except Exception:\n            pass\n        return \"\"\n\n    def serve_webhooks(self, host: str = \"127.0.0.1\", port: int = 8765) -> ThreadingHTTPServer:\n        service = self\n\n        class Handler(BaseHTTPRequestHandler):\n            def _dispatch(self):\n                parsed = urlparse(self.path)\n                path = parsed.path.rstrip(\"/\")\n                headers = {key: value for key, value in self.headers.items()}\n                if self.command == \"GET\":\n                    if path in {\"\", \"/\", \"/dashboard\"}:\n                        dashboard_path = APP_WEB_ROOT / \"dashboard.html\"\n                        body = dashboard_path.read_bytes()\n                        self.send_response(200)\n                        self.send_header(\"Content-Type\", \"text/html; charset=utf-8\")\n                        self.end_headers()\n                        self.wfile.write(body)\n                        return\n                    if path == \"/api/panel\":\n                        body = json.dumps(service.dashboard_payload(), ensure_ascii=False, indent=2).encode(\"utf-8\")\n                        self.send_response(200)\n                        self.send_header(\"Content-Type\", \"application/json; charset=utf-8\")\n                        self.end_headers()\n                        self.wfile.write(body)\n                        return\n                    if path == \"/api/global-skills\":\n                        body = json.dumps(service.list_global_skills(), ensure_ascii=False, indent=2).encode(\"utf-8\")\n                        self.send_response(200)\n                        self.send_header(\"Content-Type\", \"application/json; charset=utf-8\")\n                        self.end_headers()\n                        self.wfile.write(body)\n                        return\n                    if path == \"/api/task-settings\":\n                        task_id = str((parse_qs(parsed.query).get(\"task_id\") or [\"\"])[0] or \"\").strip()\n                        if not task_id:\n                            self.send_error(400, \"task_id is required\")\n                            return\n                        body = json.dumps(service.get_task_preferences(task_id=task_id), ensure_ascii=False, indent=2).encode(\"utf-8\")\n                        self.send_response(200)\n                        self.send_header(\"Content-Type\", \"application/json; charset=utf-8\")\n                        self.end_headers()\n                        self.wfile.write(body)\n                        return\n                    query = parse_qs(parsed.query)\n                    adapter = service._adapter_for_webhook(path)\n                    if adapter is None:\n                        self.send_error(404)\n                        return\n                    status, out_headers, body = adapter.handle_webhook_get(path, query, headers)\n                else:\n                    body_raw = self.rfile.read(int(self.headers.get(\"Content-Length\", \"0\") or \"0\"))\n                    if path == \"/api/task-settings\":\n                        try:\n                            payload = json.loads(body_raw.decode(\"utf-8\") or \"{}\")\n                        except Exception:\n                            self.send_error(400, \"invalid json body\")\n                            return\n                        task_id = str(payload.get(\"task_id\") or \"\").strip()\n                        if not task_id:\n                            self.send_error(400, \"task_id is required\")\n                            return\n                        result = service.update_task_preferences(\n                            task_id=task_id,\n                            default_exposed_skills=payload.get(\"default_exposed_skills\"),\n                            mcp_servers=payload.get(\"mcp_servers\"),\n                        )\n                        status = 200 if result.get(\"status\") == \"success\" else 400\n                        self.send_response(status)\n                        self.send_header(\"Content-Type\", \"application/json; charset=utf-8\")\n                        self.end_headers()\n                        self.wfile.write(json.dumps(result, ensure_ascii=False, indent=2).encode(\"utf-8\"))\n                        return\n                    adapter = service._adapter_for_webhook(path)\n                    if adapter is None:\n                        self.send_error(404)\n                        return\n                    status, out_headers, body = adapter.handle_webhook_post(path, body_raw, headers)\n                self.send_response(status)\n                for key, value in out_headers.items():\n                    self.send_header(key, value)\n                self.end_headers()\n                self.wfile.write(body)\n\n            def do_GET(self):\n                self._dispatch()\n\n            def do_POST(self):\n                self._dispatch()\n\n            def log_message(self, fmt, *args):\n                return\n\n        server = ThreadingHTTPServer((host, int(port)), Handler)\n        state = self.load_runtime_state()\n        state[\"webhook_server\"] = {\"host\": host, \"port\": int(port), \"started_at\": now_iso()}\n        self.save_runtime_state(state)\n        return server\n\n    def dashboard_payload(self) -> Dict[str, Any]:\n        panel = json.loads(json.dumps(self.panel_store.load_panel(), ensure_ascii=False))\n        for channel_payload in panel.get(\"channels\", {}).values():\n            for conv in channel_payload.get(\"conversations\", {}).values():\n                linked = [item for item in conv.get(\"linked_tasks\", []) if isinstance(item, dict)]\n                linked.sort(\n                    key=lambda item: (\n                        self._task_created_sort_value(item),\n                        str(item.get(\"last_final_output_at\") or \"\"),\n                        str(item.get(\"last_action_at\") or \"\"),\n                        str(item.get(\"task_id\") or \"\"),\n                    ),\n                    reverse=True,\n                )\n                conv[\"linked_tasks\"] = linked\n        return panel\n\n    def _adapter_for_webhook(self, path: str) -> Optional[ChannelAdapter]:\n        if path.endswith(\"/feishu\"):\n            return self.adapters.get(\"feishu\")\n        if path.endswith(\"/whatsapp\"):\n            return self.adapters.get(\"whatsapp\")\n        return None\n\n    def credentials_needed(self) -> Dict[str, List[str]]:\n        return {\n            \"telegram\": [\"bot_token\"],\n            \"feishu\": [\"app_id\", \"app_secret\", \"verify_token\"],\n            \"whatsapp\": [\"access_token\", \"phone_number_id\", \"verify_token\"],\n        }\n\n\ndef build_arg_parser() -> argparse.ArgumentParser:\n    parser = argparse.ArgumentParser(description=\"CheapClaw standalone service\")\n    parser.add_argument(\"--user-data-root\", required=True, help=\"User data root used by MLA runtime\")\n    parser.add_argument(\"--llm-config-path\", default=None, help=\"Optional llm_config.yaml override\")\n    parser.add_argument(\"--bootstrap\", action=\"store_true\", help=\"Install CheapClaw tools, agent systems and example configs into the target user_data_root\")\n    parser.add_argument(\"--show-runtime\", action=\"store_true\", help=\"Print runtime description and exit\")\n    parser.add_argument(\"--show-panel\", action=\"store_true\", help=\"Print panel JSON and exit\")\n    parser.add_argument(\"--show-credentials\", action=\"store_true\", help=\"Print live channel credentials required for testing and exit\")\n    parser.add_argument(\"--run-once\", action=\"store_true\", help=\"Run one CheapClaw polling/watchdog/supervisor cycle\")\n    parser.add_argument(\"--run-loop\", action=\"store_true\", help=\"Run the CheapClaw service loop\")\n    parser.add_argument(\"--poll-interval\", type=int, default=15, help=\"Polling interval in seconds for --run-loop\")\n    parser.add_argument(\"--serve-webhooks\", action=\"store_true\", help=\"Start the webhook server for Feishu / WhatsApp\")\n    parser.add_argument(\"--host\", default=\"127.0.0.1\")\n    parser.add_argument(\"--port\", type=int, default=8765)\n    return parser\n\n\ndef main(argv: Optional[List[str]] = None) -> int:\n    parser = build_arg_parser()\n    args = parser.parse_args(argv)\n    service = CheapClawService(user_data_root=args.user_data_root, llm_config_path=args.llm_config_path)\n\n    if args.bootstrap:\n        print(json.dumps(service.bootstrap_assets(force=True), ensure_ascii=False, indent=2))\n        return 0\n    if args.show_runtime:\n        print(json.dumps(service.describe_runtime(), ensure_ascii=False, indent=2))\n        return 0\n    if args.show_panel:\n        print(json.dumps(service.panel_store.load_panel(), ensure_ascii=False, indent=2))\n        return 0\n    if args.show_credentials:\n        print(json.dumps(service.credentials_needed(), ensure_ascii=False, indent=2))\n        return 0\n    if args.run_once:\n        print(json.dumps(service.run_once(), ensure_ascii=False, indent=2))\n        return 0\n    if args.serve_webhooks and not args.run_loop:\n        server = service.serve_webhooks(host=args.host, port=args.port)\n        _log(f\"webhook server started on {args.host}:{args.port}\")\n        try:\n            server.serve_forever()\n        finally:\n            server.server_close()\n        return 0\n    if args.run_loop:\n        server = None\n        thread = None\n        if args.serve_webhooks:\n            server = service.serve_webhooks(host=args.host, port=args.port)\n            thread = threading.Thread(target=server.serve_forever, daemon=True)\n            thread.start()\n            _log(f\"webhook server started on {args.host}:{args.port}\")\n        try:\n            _log(f\"service loop started with poll_interval={args.poll_interval}s\")\n            service.run_forever(poll_interval=args.poll_interval)\n        finally:\n            if server is not None:\n                server.shutdown()\n                server.server_close()\n        return 0\n\n    parser.print_help()\n    return 0\n\n\nif __name__ == \"__main__\":\n    raise SystemExit(main())\n"
  },
  {
    "path": "apps/cheapclaw/skills/cheapclaw-watchdog/SKILL.md",
    "content": "---\nname: cheapclaw-watchdog\ndescription: Read CheapClaw watchdog observations and decide whether to inspect logs, fresh a task, ask for user input, or reset the task.\n---\n\n# CheapClaw Watchdog Skill\n\nUse this skill when the trigger reason or panel events indicate watchdog observations, stalled tasks, repeated fresh attempts, or process health anomalies.\n\nChecklist:\n1. Read the CheapClaw panel and locate conversations/tasks with watchdog observations.\n2. Inspect task status, latest thinking, final output, log path, and share context path.\n3. If necessary, read the tail of the log file before deciding.\n4. Distinguish between quiet-but-alive tasks and truly dead/stalled tasks.\n5. Prefer reversible actions first: send status message, append clarification, or fresh.\n6. Only reset a task when the evidence is strong and the loop cannot recover safely.\n"
  },
  {
    "path": "apps/cheapclaw/skills/find-skills/SKILL.md",
    "content": "---\nname: find-skills\ndescription: Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n---\n\n# Find Skills\n\nThis skill helps you discover and install skills from the open agent skills ecosystem.\n\n## When to Use This Skill\n\nUse this skill when the user:\n\n- Asks \"how do I do X\" where X might be a common task with an existing skill\n- Says \"find a skill for X\" or \"is there a skill for X\"\n- Asks \"can you do X\" where X is a specialized capability\n- Expresses interest in extending agent capabilities\n- Wants to search for tools, templates, or workflows\n- Mentions they wish they had help with a specific domain (design, testing, deployment, etc.)\n\n## What is the Skills CLI?\n\nThe Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools.\n\n**Key commands:**\n\n- `npx skills find [query]` - Search for skills interactively or by keyword\n- `npx skills add <package>` - Install a skill from GitHub or other sources\n- `npx skills check` - Check for skill updates\n- `npx skills update` - Update all installed skills\n\n**Browse skills at:** https://skills.sh/\n\n## How to Help Users Find Skills\n\n### Step 1: Understand What They Need\n\nWhen a user asks for help with something, identify:\n\n1. The domain (e.g., React, testing, design, deployment)\n2. The specific task (e.g., writing tests, creating animations, reviewing PRs)\n3. Whether this is a common enough task that a skill likely exists\n\n### Step 2: Search for Skills\n\nRun the find command with a relevant query:\n\n```bash\nnpx skills find [query]\n```\n\nFor example:\n\n- User asks \"how do I make my React app faster?\" → `npx skills find react performance`\n- User asks \"can you help me with PR reviews?\" → `npx skills find pr review`\n- User asks \"I need to create a changelog\" → `npx skills find changelog`\n\nThe command will return results like:\n\n```\nInstall with npx skills add <owner/repo@skill>\n\nvercel-labs/agent-skills@vercel-react-best-practices\n└ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices\n```\n\n### Step 3: Present Options to the User\n\nWhen you find relevant skills, present them to the user with:\n\n1. The skill name and what it does\n2. The install command they can run\n3. A link to learn more at skills.sh\n\nExample response:\n\n```\nI found a skill that might help! The \"vercel-react-best-practices\" skill provides\nReact and Next.js performance optimization guidelines from Vercel Engineering.\n\nTo install it:\nnpx skills add vercel-labs/agent-skills@vercel-react-best-practices\n\nLearn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices\n```\n\n### Step 4: Offer to Install\n\nIf the user wants to proceed, you can install the skill for them:\n\n```bash\nnpx skills add <owner/repo@skill> -g -y\n```\n\nThe `-g` flag installs globally (user-level) and `-y` skips confirmation prompts.\n\n## Common Skill Categories\n\nWhen searching, consider these common categories:\n\n| Category        | Example Queries                          |\n| --------------- | ---------------------------------------- |\n| Web Development | react, nextjs, typescript, css, tailwind |\n| Testing         | testing, jest, playwright, e2e           |\n| DevOps          | deploy, docker, kubernetes, ci-cd        |\n| Documentation   | docs, readme, changelog, api-docs        |\n| Code Quality    | review, lint, refactor, best-practices   |\n| Design          | ui, ux, design-system, accessibility     |\n| Productivity    | workflow, automation, git                |\n\n## Tips for Effective Searches\n\n1. **Use specific keywords**: \"react testing\" is better than just \"testing\"\n2. **Try alternative terms**: If \"deploy\" doesn't work, try \"deployment\" or \"ci-cd\"\n3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills`\n\n## When No Skills Are Found\n\nIf no relevant skills exist:\n\n1. Acknowledge that no existing skill was found\n2. Offer to help with the task directly using your general capabilities\n3. Suggest the user could create their own skill with `npx skills init`\n\nExample:\n\n```\nI searched for skills related to \"xyz\" but didn't find any matches.\nI can still help you with this task directly! Would you like me to proceed?\n\nIf this is something you do often, you could create your own skill:\nnpx skills init my-xyz-skill\n```"
  },
  {
    "path": "apps/cheapclaw/tool_runtime_helpers.py",
    "content": "#!/usr/bin/env python3\nfrom __future__ import annotations\n\nimport json\nimport os\nimport shutil\nimport tempfile\nimport uuid\nfrom datetime import datetime, timedelta\nfrom pathlib import Path\nfrom typing import Any, Dict, Iterable, List, Optional\n\n\ndef now_iso() -> str:\n    return datetime.now().astimezone().isoformat(timespec=\"seconds\")\n\n\ndef parse_iso(value: str) -> Optional[datetime]:\n    value = str(value or \"\").strip()\n    if not value:\n        return None\n    try:\n        parsed = datetime.fromisoformat(value)\n        if parsed.tzinfo is None:\n            return parsed.replace(tzinfo=datetime.now().astimezone().tzinfo)\n        return parsed\n    except Exception:\n        return None\n\n\ndef get_user_data_root() -> Path:\n    env_root = os.environ.get(\"MLA_USER_DATA_ROOT\", \"\").strip()\n    if env_root:\n        return Path(env_root).expanduser().resolve()\n    return (Path.home() / \"mla_v3\").resolve()\n\n\ndef get_cheapclaw_root() -> Path:\n    return get_user_data_root() / \"cheapclaw\"\n\n\ndef get_panel_path() -> Path:\n    return get_cheapclaw_root() / \"panel\" / \"panel.json\"\n\n\ndef get_panel_backups_dir() -> Path:\n    return get_cheapclaw_root() / \"panel\" / \"backups\"\n\n\ndef get_plans_path() -> Path:\n    return get_cheapclaw_root() / \"plans.json\"\n\n\ndef get_outbox_dir() -> Path:\n    return get_cheapclaw_root() / \"outbox\"\n\n\ndef get_task_events_dir() -> Path:\n    return get_user_data_root() / \"runtime\" / \"task_events\"\n\n\ndef get_task_skills_root() -> Path:\n    return get_cheapclaw_root() / \"task_skills\"\n\n\ndef get_channels_root() -> Path:\n    return get_cheapclaw_root() / \"channels\"\n\n\ndef ensure_cheapclaw_layout() -> None:\n    for path in [\n        get_cheapclaw_root(),\n        get_panel_path().parent,\n        get_panel_backups_dir(),\n        get_outbox_dir(),\n        get_task_events_dir(),\n        get_task_skills_root(),\n        get_channels_root(),\n    ]:\n        path.mkdir(parents=True, exist_ok=True)\n    if not get_panel_path().exists():\n        _atomic_write_json(\n            get_panel_path(),\n            {\n                \"version\": 1,\n                \"channels\": {},\n                \"service_state\": {\n                    \"main_agent_task_id\": str(get_cheapclaw_root() / \"supervisor_task\"),\n                    \"main_agent_running\": False,\n                    \"main_agent_run_id\": \"\",\n                    \"main_agent_last_started_at\": \"\",\n                    \"main_agent_last_finished_at\": \"\",\n                    \"main_agent_dirty\": False,\n                    \"watchdog_last_run_at\": \"\",\n                    \"last_backup_path\": \"\",\n                },\n            },\n        )\n    if not get_plans_path().exists():\n        _atomic_write_json(get_plans_path(), {\"version\": 1, \"plans\": []})\n\n\ndef _atomic_write_json(path: Path, payload: Dict[str, Any]) -> None:\n    path.parent.mkdir(parents=True, exist_ok=True)\n    fd, tmp_name = tempfile.mkstemp(prefix=path.name + \".\", dir=str(path.parent))\n    try:\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as tmp_file:\n            json.dump(payload, tmp_file, ensure_ascii=False, indent=2)\n        os.replace(tmp_name, path)\n    finally:\n        if os.path.exists(tmp_name):\n            os.unlink(tmp_name)\n\n\ndef _write_backup(path: Path, payload: str) -> Path:\n    backup_path = get_panel_backups_dir() / f\"panel_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}.json\"\n    backup_path.write_text(payload, encoding=\"utf-8\")\n    return backup_path\n\n\ndef slugify(value: str, fallback: str = \"item\", max_len: int = 80) -> str:\n    text = str(value or \"\").strip()\n    if not text:\n        return fallback\n    chars: List[str] = []\n    last_dash = False\n    for ch in text:\n        if ch.isalnum():\n            chars.append(ch.lower())\n            last_dash = False\n        elif ch in {\"-\", \"_\"}:\n            chars.append(ch)\n            last_dash = False\n        else:\n            if not last_dash:\n                chars.append(\"-\")\n            last_dash = True\n    return \"\".join(chars).strip(\"-_\")[:max_len] or fallback\n\n\ndef load_panel() -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    try:\n        return json.loads(get_panel_path().read_text(encoding=\"utf-8\"))\n    except Exception:\n        return {\"version\": 1, \"channels\": {}, \"service_state\": {}}\n\n\ndef save_panel(panel: Dict[str, Any], backup: bool = True) -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    if backup and get_panel_path().exists():\n        backup_path = _write_backup(get_panel_path(), get_panel_path().read_text(encoding=\"utf-8\"))\n        panel.setdefault(\"service_state\", {})[\"last_backup_path\"] = str(backup_path)\n    _atomic_write_json(get_panel_path(), panel)\n    return panel\n\n\ndef mutate_panel(mutator):\n    panel = load_panel()\n    updated = mutator(panel)\n    return save_panel(panel if updated is None else updated)\n\n\ndef _default_task_view(task_id: str) -> Dict[str, Any]:\n    return {\n        \"task_id\": task_id,\n        \"created_at\": now_iso(),\n        \"last_launch_at\": \"\",\n        \"agent_system\": \"\",\n        \"agent_name\": \"\",\n        \"status\": \"unknown\",\n        \"share_context_path\": \"\",\n        \"stack_path\": \"\",\n        \"log_path\": \"\",\n        \"skills_dir\": \"\",\n        \"default_exposed_skills\": [],\n        \"mcp_servers\": [],\n        \"last_thinking\": \"\",\n        \"last_thinking_at\": \"\",\n        \"last_final_output\": \"\",\n        \"last_final_output_at\": \"\",\n        \"last_action_at\": \"\",\n        \"last_log_at\": \"\",\n        \"fresh_retry_count\": 0,\n        \"last_watchdog_note\": \"\",\n    }\n\n\ndef ensure_conversation(\n    panel: Dict[str, Any],\n    *,\n    channel: str,\n    conversation_id: str,\n    conversation_type: str = \"group\",\n    display_name: Optional[str] = None,\n    require_mention: bool = True,\n) -> Dict[str, Any]:\n    channel_payload = panel.setdefault(\"channels\", {}).setdefault(channel, {\"conversations\": {}})\n    conversations = channel_payload.setdefault(\"conversations\", {})\n    if conversation_id not in conversations:\n        conversations[conversation_id] = {\n            \"channel\": channel,\n            \"conversation_id\": conversation_id,\n            \"conversation_type\": conversation_type,\n            \"display_name\": display_name or conversation_id,\n            \"trigger_policy\": {\"require_mention\": bool(require_mention)},\n            \"message_history_path\": str(history_path(channel, conversation_id)),\n            \"context_summary_path\": str(conversation_context_path(channel, conversation_id)),\n            \"messages\": [],\n            \"linked_tasks\": [],\n            \"pending_events\": [],\n            \"dirty\": False,\n            \"last_snapshot_path\": \"\",\n            \"updated_at\": \"\",\n            \"running_task_count\": 0,\n            \"has_stale_running_tasks\": False,\n            \"latest_user_message_at\": \"\",\n            \"latest_bot_message_at\": \"\",\n            \"unread_event_count\": 0,\n            \"last_reply_summary\": \"\",\n            \"conversation_tags\": [],\n            \"message_task_bindings\": [],\n        }\n    conversation = conversations[conversation_id]\n    conversation[\"conversation_type\"] = conversation_type or conversation.get(\"conversation_type\") or \"group\"\n    conversation[\"display_name\"] = display_name or conversation.get(\"display_name\") or conversation_id\n    conversation[\"trigger_policy\"] = {\"require_mention\": bool(require_mention)}\n    conversation[\"message_history_path\"] = str(history_path(channel, conversation_id))\n    conversation[\"context_summary_path\"] = str(conversation_context_path(channel, conversation_id))\n    conversation.setdefault(\"messages\", [])\n    conversation.setdefault(\"linked_tasks\", [])\n    conversation.setdefault(\"pending_events\", [])\n    conversation.setdefault(\"message_task_bindings\", [])\n    return conversation\n\n\ndef history_path(channel: str, conversation_id: str) -> Path:\n    directory = get_channels_root() / slugify(channel, fallback=\"channel\") / slugify(conversation_id, fallback=\"conversation\")\n    directory.mkdir(parents=True, exist_ok=True)\n    return directory / \"social_history.jsonl\"\n\n\ndef conversation_context_path(channel: str, conversation_id: str) -> Path:\n    directory = get_channels_root() / slugify(channel, fallback=\"channel\") / slugify(conversation_id, fallback=\"conversation\")\n    directory.mkdir(parents=True, exist_ok=True)\n    return directory / \"latest_context.md\"\n\n\ndef _short_text(value: Any, limit: int = 240) -> str:\n    text = str(value or \"\").strip()\n    if len(text) <= limit:\n        return text\n    return text[: max(0, limit - 1)] + \"…\"\n\n\ndef refresh_conversation_context_file(\n    channel: str,\n    conversation_id: str,\n    panel: Optional[Dict[str, Any]] = None,\n    recent_message_limit: int = 10,\n) -> Path:\n    panel = panel or load_panel()\n    conv = panel.get(\"channels\", {}).get(channel, {}).get(\"conversations\", {}).get(conversation_id, {})\n    path = conversation_context_path(channel, conversation_id)\n    if not conv:\n        path.write_text(\"# Conversation Context\\n\\nConversation not found.\\n\", encoding=\"utf-8\")\n        return path\n\n    messages = [item for item in conv.get(\"messages\", []) if isinstance(item, dict)][-max(1, int(recent_message_limit)) :]\n    linked_tasks = [item for item in conv.get(\"linked_tasks\", []) if isinstance(item, dict)]\n    pending_events = [item for item in conv.get(\"pending_events\", []) if isinstance(item, dict)][-10:]\n    bindings = [item for item in conv.get(\"message_task_bindings\", []) if isinstance(item, dict)][-10:]\n\n    lines = [\n        f\"# Conversation Context: {conv.get('display_name') or conversation_id}\",\n        \"\",\n        f\"- channel: {channel}\",\n        f\"- conversation_id: {conversation_id}\",\n        f\"- conversation_type: {conv.get('conversation_type') or ''}\",\n        f\"- dirty: {bool(conv.get('dirty'))}\",\n        f\"- latest_user_message_at: {conv.get('latest_user_message_at') or ''}\",\n        f\"- latest_bot_message_at: {conv.get('latest_bot_message_at') or ''}\",\n        \"\",\n        \"## Recent Messages\",\n    ]\n    if not messages:\n        lines.append(\"- (none)\")\n    else:\n        for item in messages:\n            lines.extend(\n                [\n                    f\"- [{item.get('timestamp') or ''}] {item.get('direction') or ''} message_id={item.get('message_id') or ''}\",\n                    f\"  {str(item.get('text') or '').strip()}\",\n                ]\n            )\n\n    lines.extend([\"\", \"## Pending Events\"])\n    if not pending_events:\n        lines.append(\"- (none)\")\n    else:\n        for event in pending_events:\n            lines.append(\n                f\"- type={event.get('type') or ''} message_id={event.get('message_id') or ''} task_id={event.get('task_id') or ''} ts={event.get('timestamp') or ''}\"\n            )\n\n    lines.extend([\"\", \"## Task List\"])\n    if not linked_tasks:\n        lines.append(\"- (none)\")\n    else:\n        linked_tasks.sort(key=lambda item: str(item.get(\"created_at\") or item.get(\"task_id\") or \"\"), reverse=True)\n        for task in linked_tasks:\n            lines.extend(\n                [\n                    f\"- task_id: {task.get('task_id') or ''}\",\n                    f\"  status: {task.get('status') or ''}\",\n                    f\"  agent_system: {task.get('agent_system') or ''}\",\n                    f\"  agent_name: {task.get('agent_name') or ''}\",\n                    f\"  last_final_output_at: {task.get('last_final_output_at') or ''}\",\n                    f\"  last_final_output_summary: {_short_text(task.get('last_final_output') or '', 200)}\",\n                ]\n            )\n\n    lines.extend([\"\", \"## Recent Message Bindings\"])\n    if not bindings:\n        lines.append(\"- (none)\")\n    else:\n        for binding in bindings:\n            lines.append(\n                f\"- message_id={binding.get('message_id') or ''} -> task_id={binding.get('task_id') or ''} ({binding.get('binding_type') or ''}) note={_short_text(binding.get('note') or '', 120)}\"\n            )\n\n    lines.extend(\n        [\n            \"\",\n            \"## Retrieval Hints\",\n            f\"- Full social history: {history_path(channel, conversation_id)}\",\n            f\"- Full panel: {get_panel_path()}\",\n            \"- If recent messages are insufficient, use cheapclaw_read_social_history with a larger limit or a time range.\",\n            \"- If you need to search old records from files, use grep on the social history JSONL or panel JSON.\",\n            \"\",\n        ]\n    )\n    path.write_text(\"\\n\".join(lines) + \"\\n\", encoding=\"utf-8\")\n    return path\n\n\ndef append_history(\n    *,\n    channel: str,\n    conversation_id: str,\n    event: Dict[str, Any],\n    limit: int = 50,\n) -> None:\n    panel = load_panel()\n    conversation = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n    history_file = Path(conversation[\"message_history_path\"])\n    history_file.parent.mkdir(parents=True, exist_ok=True)\n    with open(history_file, \"a\", encoding=\"utf-8\") as fh:\n        fh.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n    messages = conversation.setdefault(\"messages\", [])\n    messages.append(event)\n    del messages[:-max(1, int(limit))]\n    if event.get(\"direction\") == \"outbound\":\n        conversation[\"latest_bot_message_at\"] = event.get(\"timestamp\", \"\")\n    else:\n        conversation[\"latest_user_message_at\"] = event.get(\"timestamp\", \"\")\n    conversation[\"updated_at\"] = event.get(\"timestamp\", now_iso())\n    save_panel(panel)\n    refresh_conversation_context_file(channel, conversation_id, panel)\n\n\ndef read_social_history(\n    *,\n    channel: str,\n    conversation_id: str,\n    limit: int = 30,\n    only_mentions_to_bot: bool = False,\n    include_bot_replies: bool = True,\n    from_message_id: str = \"\",\n    to_message_id: str = \"\",\n    before_timestamp: str = \"\",\n    after_timestamp: str = \"\",\n) -> List[Dict[str, Any]]:\n    path = history_path(channel, conversation_id)\n    if not path.exists():\n        return []\n    events = []\n    for line in path.read_text(encoding=\"utf-8\").splitlines():\n        if not line.strip():\n            continue\n        try:\n            item = json.loads(line)\n        except Exception:\n            continue\n        if only_mentions_to_bot and not item.get(\"is_mention_to_bot\"):\n            continue\n        if not include_bot_replies and item.get(\"direction\") == \"outbound\":\n            continue\n        if from_message_id and str(item.get(\"message_id\") or \"\") < from_message_id:\n            continue\n        if to_message_id and str(item.get(\"message_id\") or \"\") > to_message_id:\n            continue\n        timestamp = str(item.get(\"timestamp\") or \"\")\n        if before_timestamp and timestamp and timestamp >= before_timestamp:\n            continue\n        if after_timestamp and timestamp and timestamp <= after_timestamp:\n            continue\n        events.append(item)\n    return events[-max(1, int(limit)):]\n\n\ndef queue_outbound_message(\n    *,\n    channel: str,\n    conversation_id: str,\n    message: str,\n    attachments: Optional[List[Dict[str, Any]]] = None,\n    metadata: Optional[Dict[str, Any]] = None,\n) -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    event_id = f\"out_{uuid.uuid4().hex[:12]}\"\n    payload = {\n        \"event_id\": event_id,\n        \"channel\": channel,\n        \"conversation_id\": conversation_id,\n        \"message\": str(message or \"\").strip(),\n        \"attachments\": attachments or [],\n        \"metadata\": metadata or {},\n        \"created_at\": now_iso(),\n    }\n    _atomic_write_json(get_outbox_dir() / f\"{event_id}.json\", payload)\n    return payload\n\n\ndef list_outbox_events() -> List[Dict[str, Any]]:\n    ensure_cheapclaw_layout()\n    events = []\n    for path in sorted(get_outbox_dir().glob(\"*.json\")):\n        try:\n            events.append(json.loads(path.read_text(encoding=\"utf-8\")))\n        except Exception:\n            continue\n    return events\n\n\ndef ack_outbox_event(event_id: str) -> None:\n    path = get_outbox_dir() / f\"{event_id}.json\"\n    try:\n        path.unlink()\n    except FileNotFoundError:\n        pass\n\n\ndef emit_task_event(payload: Dict[str, Any]) -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    event_id = str(payload.get(\"event_id\") or f\"taskevt_{uuid.uuid4().hex[:12]}\")\n    event_payload = dict(payload)\n    event_payload[\"event_id\"] = event_id\n    event_payload.setdefault(\"created_at\", now_iso())\n    _atomic_write_json(get_task_events_dir() / f\"{event_id}.json\", event_payload)\n    return event_payload\n\n\ndef list_task_events() -> List[Dict[str, Any]]:\n    ensure_cheapclaw_layout()\n    events = []\n    for path in sorted(get_task_events_dir().glob(\"*.json\")):\n        try:\n            events.append(json.loads(path.read_text(encoding=\"utf-8\")))\n        except Exception:\n            continue\n    return events\n\n\ndef ack_task_event(event_id: str) -> None:\n    path = get_task_events_dir() / f\"{event_id}.json\"\n    try:\n        path.unlink()\n    except FileNotFoundError:\n        pass\n\n\ndef load_plans() -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    try:\n        return json.loads(get_plans_path().read_text(encoding=\"utf-8\"))\n    except Exception:\n        return {\"version\": 1, \"plans\": []}\n\n\ndef save_plans(payload: Dict[str, Any]) -> Dict[str, Any]:\n    ensure_cheapclaw_layout()\n    _atomic_write_json(get_plans_path(), payload)\n    return payload\n\n\ndef create_plan(\n    *,\n    name: str,\n    scope: str,\n    task_id: str = \"\",\n    channel: str = \"\",\n    conversation_id: str = \"\",\n    interval_sec: int = 0,\n    once_at: str = \"\",\n    schedule_type: str = \"\",\n    time_of_day: str = \"\",\n    days_of_week: Optional[Iterable[str]] = None,\n    message: str = \"\",\n    enabled: bool = True,\n) -> Dict[str, Any]:\n    payload = load_plans()\n    plans = payload.setdefault(\"plans\", [])\n    plan_id = f\"plan_{uuid.uuid4().hex[:10]}\"\n    now = now_iso()\n    schedule_type = str(schedule_type or (\"once\" if once_at else \"interval\")).strip() or \"interval\"\n    weekday_names = [str(item).strip().lower() for item in (days_of_week or []) if str(item).strip()]\n    next_run_at = once_at or (datetime.now().astimezone() + timedelta(seconds=max(1, int(interval_sec or 3600)))).isoformat(timespec=\"seconds\")\n    if schedule_type in {\"daily\", \"weekly\"} and time_of_day:\n        next_run_at = compute_next_scheduled_run(\n            schedule_type=schedule_type,\n            time_of_day=time_of_day,\n            days_of_week=weekday_names,\n            now=parse_iso(now) or datetime.now().astimezone(),\n        )\n    plan = {\n        \"plan_id\": plan_id,\n        \"name\": name,\n        \"scope\": scope,\n        \"task_id\": task_id,\n        \"channel\": channel,\n        \"conversation_id\": conversation_id,\n        \"interval_sec\": max(0, int(interval_sec or 0)),\n        \"once_at\": once_at,\n        \"schedule_type\": schedule_type,\n        \"time_of_day\": time_of_day,\n        \"days_of_week\": weekday_names,\n        \"next_run_at\": next_run_at,\n        \"message\": message,\n        \"enabled\": bool(enabled),\n        \"created_at\": now,\n        \"last_run_at\": \"\",\n        \"last_result\": \"\",\n    }\n    plans.append(plan)\n    save_plans(payload)\n    return plan\n\n\ndef cancel_plan(plan_id: str) -> bool:\n    payload = load_plans()\n    changed = False\n    for plan in payload.get(\"plans\", []):\n        if plan.get(\"plan_id\") == plan_id:\n            plan[\"enabled\"] = False\n            plan[\"last_result\"] = \"cancelled\"\n            changed = True\n    if changed:\n        save_plans(payload)\n    return changed\n\n\ndef list_plans(scope: str = \"\", enabled_only: bool = False) -> List[Dict[str, Any]]:\n    items = load_plans().get(\"plans\", [])\n    result = []\n    for item in items:\n        if scope and item.get(\"scope\") != scope:\n            continue\n        if enabled_only and not item.get(\"enabled\", True):\n            continue\n        result.append(item)\n    return result\n\n\ndef compute_next_scheduled_run(\n    *,\n    schedule_type: str,\n    time_of_day: str,\n    days_of_week: Optional[Iterable[str]] = None,\n    now: Optional[datetime] = None,\n) -> str:\n    current = now or datetime.now().astimezone()\n    raw = str(time_of_day or \"\").strip()\n    try:\n        hour_str, minute_str = raw.split(\":\", 1)\n        hour = max(0, min(23, int(hour_str)))\n        minute = max(0, min(59, int(minute_str)))\n    except Exception:\n        hour, minute = 8, 0\n    candidate = current.replace(hour=hour, minute=minute, second=0, microsecond=0)\n    if schedule_type == \"daily\":\n        if candidate <= current:\n            candidate += timedelta(days=1)\n        return candidate.isoformat(timespec=\"seconds\")\n\n    weekday_names = [str(item).strip().lower() for item in (days_of_week or []) if str(item).strip()]\n    if not weekday_names:\n        weekday_names = [\"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\", \"sun\"]\n    mapping = {\"mon\": 0, \"tue\": 1, \"wed\": 2, \"thu\": 3, \"fri\": 4, \"sat\": 5, \"sun\": 6}\n    targets = [mapping[item] for item in weekday_names if item in mapping]\n    if not targets:\n        targets = list(range(7))\n    for delta in range(0, 8):\n        test = candidate + timedelta(days=delta)\n        if test.weekday() in targets and test > current:\n            return test.isoformat(timespec=\"seconds\")\n    return (candidate + timedelta(days=7)).isoformat(timespec=\"seconds\")\n\n\ndef list_conversation_tasks(channel: str, conversation_id: str) -> List[Dict[str, Any]]:\n    panel = load_panel()\n    conv = panel.get(\"channels\", {}).get(channel, {}).get(\"conversations\", {}).get(conversation_id, {})\n    tasks = list(conv.get(\"linked_tasks\", []))\n    tasks.sort(\n        key=lambda item: (\n            str(item.get(\"last_final_output_at\") or \"\"),\n            str(item.get(\"last_action_at\") or \"\"),\n            str(item.get(\"last_thinking_at\") or \"\"),\n            str(item.get(\"last_log_at\") or \"\"),\n            str(item.get(\"task_id\") or \"\"),\n        ),\n        reverse=True,\n    )\n    return tasks\n\n\ndef bind_messages_to_task(\n    channel: str,\n    conversation_id: str,\n    task_id: str,\n    message_ids: Iterable[str],\n    *,\n    note: str = \"\",\n    binding_type: str = \"task\",\n) -> Dict[str, Any]:\n    message_ids = [str(item).strip() for item in (message_ids or []) if str(item).strip()]\n    if not message_ids:\n        return load_panel()\n\n    def _mutate(panel: Dict[str, Any]) -> Dict[str, Any]:\n        conv = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n        bindings = conv.setdefault(\"message_task_bindings\", [])\n        for message_id in message_ids:\n            existing = next((item for item in bindings if item.get(\"message_id\") == message_id), None)\n            payload = {\n                \"message_id\": message_id,\n                \"task_id\": task_id,\n                \"binding_type\": binding_type,\n                \"note\": note,\n                \"bound_at\": now_iso(),\n            }\n            if existing is None:\n                bindings.append(payload)\n            else:\n                existing.update(payload)\n        conv[\"updated_at\"] = now_iso()\n        return panel\n\n    panel = mutate_panel(_mutate)\n    refresh_conversation_context_file(channel, conversation_id, panel)\n    return panel\n\n\ndef update_conversation_task(channel: str, conversation_id: str, task_id: str, patch: Dict[str, Any], mark_dirty: bool = False) -> Dict[str, Any]:\n    def _mutate(panel: Dict[str, Any]) -> Dict[str, Any]:\n        conv = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n        linked = conv.setdefault(\"linked_tasks\", [])\n        existing = next((item for item in linked if item.get(\"task_id\") == task_id), None)\n        if existing is None:\n            existing = _default_task_view(task_id)\n            linked.append(existing)\n        existing.update(patch)\n        conv[\"running_task_count\"] = sum(1 for item in linked if item.get(\"status\") == \"running\")\n        if mark_dirty:\n            conv[\"dirty\"] = True\n            panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n        conv[\"updated_at\"] = now_iso()\n        return panel\n    panel = mutate_panel(_mutate)\n    refresh_conversation_context_file(channel, conversation_id, panel)\n    return panel\n\n\ndef set_task_visible_skills(task_id: str, skill_names: Iterable[str]) -> Dict[str, Any]:\n    from core.hierarchy_manager import get_hierarchy_manager\n\n    selected = []\n    for name in skill_names or []:\n        item = str(name).strip()\n        if item and item not in selected:\n            selected.append(item)\n\n    manager = get_hierarchy_manager(str(Path(task_id).expanduser().resolve()))\n    manager.set_runtime_metadata(visible_skills=selected)\n    return {\n        \"task_id\": manager.task_id,\n        \"visible_skills\": selected,\n        \"updated_at\": now_iso(),\n    }\n\n\ndef extend_task_visible_skills(task_id: str, skill_names: Iterable[str]) -> Dict[str, Any]:\n    from core.hierarchy_manager import get_hierarchy_manager\n\n    manager = get_hierarchy_manager(str(Path(task_id).expanduser().resolve()))\n    runtime = manager.get_runtime_metadata()\n    current = runtime.get(\"visible_skills\", []) if isinstance(runtime, dict) else []\n    merged = []\n    for name in list(current or []) + list(skill_names or []):\n        item = str(name).strip()\n        if item and item not in merged:\n            merged.append(item)\n    manager.set_runtime_metadata(visible_skills=merged)\n    return {\n        \"task_id\": manager.task_id,\n        \"visible_skills\": merged,\n        \"updated_at\": now_iso(),\n    }\n\n\ndef clear_conversation_dirty(channel: str, conversation_id: str) -> Dict[str, Any]:\n    def _mutate(panel: Dict[str, Any]) -> Dict[str, Any]:\n        conv = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n        conv[\"dirty\"] = False\n        conv[\"pending_events\"] = []\n        conv[\"unread_event_count\"] = 0\n        conv[\"updated_at\"] = now_iso()\n        return panel\n    panel = mutate_panel(_mutate)\n    refresh_conversation_context_file(channel, conversation_id, panel)\n    return panel\n\n\ndef generate_task_id(channel: str, conversation_id: str, task_name: str) -> str:\n    task_dir = get_cheapclaw_root() / \"tasks\" / slugify(channel, fallback=\"channel\") / slugify(conversation_id, fallback=\"conversation\")\n    task_dir.mkdir(parents=True, exist_ok=True)\n    stamp = datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n    return str((task_dir / f\"{stamp}_{slugify(task_name, fallback='task')}\").resolve())\n\n\ndef list_global_skills(skills_root: Optional[str] = None) -> List[Dict[str, str]]:\n    root = Path(skills_root).expanduser().resolve() if skills_root else Path(os.environ.get(\"MLA_SKILLS_LIBRARY_DIR\", str(Path.home() / \".agent\" / \"skills\"))).expanduser().resolve()\n    skills = []\n    if root.exists():\n        for child in sorted(root.iterdir(), key=lambda item: item.name.lower()):\n            if child.is_dir() and (child / \"SKILL.md\").exists():\n                skills.append({\"name\": child.name, \"path\": str(child)})\n    return skills\n\n\ndef reveal_skills_for_task(task_id: str, skill_names: Iterable[str], skills_root: Optional[str] = None) -> Dict[str, Any]:\n    available = {item[\"name\"]: Path(item[\"path\"]) for item in list_global_skills(skills_root)}\n    overlay_root = get_task_skills_root() / slugify(Path(task_id).name or \"task\", fallback=\"task\")\n    overlay_root.mkdir(parents=True, exist_ok=True)\n    revealed = []\n    missing = []\n    for name in sorted(set(skill_names or [])):\n        src = available.get(name)\n        if not src:\n            missing.append(name)\n            continue\n        dest = overlay_root / name\n        if dest.exists():\n            revealed.append(name)\n            continue\n        try:\n            os.symlink(src, dest, target_is_directory=True)\n        except OSError:\n            shutil.copytree(src, dest)\n        revealed.append(name)\n    manifest = {\n        \"task_id\": str(Path(task_id).expanduser().resolve()),\n        \"overlay_root\": str(overlay_root),\n        \"revealed_skills\": revealed,\n        \"missing_skills\": missing,\n        \"updated_at\": now_iso(),\n    }\n    (overlay_root / \"manifest.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    return manifest\n\n\ndef set_task_skills_for_task(task_id: str, skill_names: Iterable[str], skills_root: Optional[str] = None) -> Dict[str, Any]:\n    available = {item[\"name\"]: Path(item[\"path\"]) for item in list_global_skills(skills_root)}\n    overlay_root = get_task_skills_root() / slugify(Path(task_id).name or \"task\", fallback=\"task\")\n    overlay_root.mkdir(parents=True, exist_ok=True)\n    selected_names = [str(name).strip() for name in (skill_names or []) if str(name).strip()]\n    for entry in list(overlay_root.iterdir()):\n        if entry.name == \"manifest.json\":\n            continue\n        if entry.is_symlink() or entry.is_file():\n            entry.unlink(missing_ok=True)\n        elif entry.is_dir():\n            shutil.rmtree(entry, ignore_errors=True)\n    revealed = []\n    missing = []\n    for name in selected_names:\n        src = available.get(name)\n        if not src:\n            missing.append(name)\n            continue\n        dest = overlay_root / name\n        try:\n            os.symlink(src, dest, target_is_directory=True)\n        except OSError:\n            shutil.copytree(src, dest)\n        revealed.append(name)\n    manifest = {\n        \"task_id\": str(Path(task_id).expanduser().resolve()),\n        \"overlay_root\": str(overlay_root),\n        \"revealed_skills\": revealed,\n        \"missing_skills\": missing,\n        \"updated_at\": now_iso(),\n        \"mode\": \"exact\",\n    }\n    (overlay_root / \"manifest.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    return manifest\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_add_task_message/cheapclaw_add_task_message.py",
    "content": "#!/usr/bin/env python3\nfrom datetime import datetime\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom infiagent import infiagent\nfrom tool_runtime_helpers import bind_messages_to_task\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\nclass CheapClawAddTaskMessageTool(BaseTool):\n    name = \"cheapclaw_add_task_message\"\n\n    def execute(self, task_id, parameters):\n        target_task_id = str(Path(parameters.get(\"task_id\") or \"\").expanduser().resolve())\n        message = str(parameters.get(\"message\") or \"\").strip()\n        if not target_task_id or not message:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"task_id and message are required\"}\n\n        user_root = str(Path(__import__(\"os\").environ.get(\"MLA_USER_DATA_ROOT\", \"~/mla_v3\")).expanduser().resolve())\n        tools_root = str(Path(__file__).resolve().parents[1])\n        agent = infiagent(user_data_root=user_root, tools_dir=tools_root)\n        timestamped = f\"{message}\\n\\n[message_appended_at {datetime.now().astimezone().isoformat(timespec='seconds')}]\"\n        result = agent.add_message(\n            timestamped,\n            task_id=target_task_id,\n            source=str(parameters.get(\"source\") or \"agent\"),\n            resume_if_needed=bool(parameters.get(\"resume_if_needed\", False)),\n            agent_system=str(parameters.get(\"agent_system\") or \"\") or None,\n        )\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        source_message_ids = parameters.get(\"source_message_ids\") or []\n        if result.get(\"status\") == \"success\" and channel and conversation_id and isinstance(source_message_ids, list) and source_message_ids:\n            bind_messages_to_task(channel, conversation_id, target_task_id, source_message_ids, note=\"message appended to existing task\")\n        return result\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_cancel_plan/cheapclaw_cancel_plan.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import cancel_plan\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawCancelPlanTool(BaseTool):\n    name = \"cheapclaw_cancel_plan\"\n    def execute(self, task_id, parameters):\n        plan_id = str(parameters.get(\"plan_id\") or \"\").strip()\n        if not plan_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"plan_id is required\"}\n        ok = cancel_plan(plan_id)\n        if not ok:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": f\"plan not found: {plan_id}\"}\n        return {\"status\": \"success\", \"output\": f\"cancelled {plan_id}\"}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_generate_task_id/cheapclaw_generate_task_id.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import generate_task_id\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawGenerateTaskIdTool(BaseTool):\n    name = \"cheapclaw_generate_task_id\"\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        task_name = str(parameters.get(\"task_name\") or \"\").strip()\n        if not channel or not conversation_id or not task_name:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel, conversation_id and task_name are required\"}\n        value = generate_task_id(channel, conversation_id, task_name)\n        return {\"status\": \"success\", \"output\": value, \"task_id\": value}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_get_task_status/cheapclaw_get_task_status.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nfrom infiagent import infiagent\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import list_conversation_tasks, load_panel\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawGetTaskStatusTool(BaseTool):\n    name = \"cheapclaw_get_task_status\"\n    def execute(self, task_id, parameters):\n        target_task_id = str(Path(parameters.get(\"task_id\") or \"\").expanduser().resolve())\n        if not target_task_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"task_id is required\"}\n        agent = infiagent(user_data_root=str(Path(__import__('os').environ.get('MLA_USER_DATA_ROOT','~/mla_v3')).expanduser().resolve()))\n        snapshot = agent.task_snapshot(task_id=target_task_id)\n        log_path = \"\"\n        panel = load_panel()\n        for channel_payload in panel.get(\"channels\", {}).values():\n            for conv in channel_payload.get(\"conversations\", {}).values():\n                for item in conv.get(\"linked_tasks\", []):\n                    if item.get(\"task_id\") == target_task_id:\n                        log_path = item.get(\"log_path\", \"\")\n                        snapshot[\"conversation\"] = {\"channel\": conv.get(\"channel\", \"\"), \"conversation_id\": conv.get(\"conversation_id\", \"\"), \"display_name\": conv.get(\"display_name\", \"\")}\n                        break\n        snapshot[\"log_path\"] = log_path\n        return snapshot\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_list_agent_systems/cheapclaw_list_agent_systems.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nfrom infiagent import infiagent\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawListAgentSystemsTool(BaseTool):\n    name = \"cheapclaw_list_agent_systems\"\n    def execute(self, task_id, parameters):\n        agent = infiagent(user_data_root=str(Path(__import__('os').environ.get('MLA_USER_DATA_ROOT','~/mla_v3')).expanduser().resolve()))\n        payload = agent.list_agent_systems()\n        payload[\"recommended_defaults\"] = {\n            \"CheapClawSupervisor\": \"supervisor_agent\",\n            \"CheapClawWorkerGeneral\": \"worker_agent\",\n        }\n        return payload\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_list_conversation_tasks/cheapclaw_list_conversation_tasks.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import list_conversation_tasks, load_panel\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawListConversationTasksTool(BaseTool):\n    name = \"cheapclaw_list_conversation_tasks\"\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        if not channel or not conversation_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel and conversation_id are required\"}\n        tasks = list_conversation_tasks(channel, conversation_id)\n        panel = load_panel()\n        conv = panel.get(\"channels\", {}).get(channel, {}).get(\"conversations\", {}).get(conversation_id, {})\n        bindings = list(conv.get(\"message_task_bindings\", []))\n        bindings.sort(key=lambda item: str(item.get(\"bound_at\") or \"\"), reverse=True)\n\n        recommended_task_id = \"\"\n        recommended_reason = \"\"\n        recommended_action = \"\"\n\n        for binding in bindings:\n            candidate = str(binding.get(\"task_id\") or \"\").strip()\n            if candidate and any(item.get(\"task_id\") == candidate for item in tasks):\n                recommended_task_id = candidate\n                recommended_reason = \"latest_message_binding\"\n                break\n\n        if not recommended_task_id and tasks:\n            recommended_task_id = str(tasks[0].get(\"task_id\") or \"\")\n            recommended_reason = \"most_recent_task_activity\"\n\n        if recommended_task_id:\n            target = next((item for item in tasks if item.get(\"task_id\") == recommended_task_id), {})\n            recommended_action = \"append_to_running_task\" if target.get(\"status\") == \"running\" else \"continue_existing_task\"\n\n        latest_binding = bindings[0] if bindings else {}\n        running_task_ids = [str(item.get(\"task_id\") or \"\") for item in tasks if item.get(\"status\") == \"running\" and str(item.get(\"task_id\") or \"\")]\n        recent_task_ids = [str(item.get(\"task_id\") or \"\") for item in tasks if str(item.get(\"task_id\") or \"\")]\n\n        return {\n            \"status\": \"success\",\n            \"output\": f\"tasks={len(tasks)}\",\n            \"tasks\": tasks,\n            \"latest_bound_task_id\": str(latest_binding.get(\"task_id\") or \"\"),\n            \"latest_bound_message_id\": str(latest_binding.get(\"message_id\") or \"\"),\n            \"running_task_ids\": running_task_ids,\n            \"recent_task_ids\": recent_task_ids,\n            \"recommended_task_id\": recommended_task_id,\n            \"recommended_reason\": recommended_reason,\n            \"recommended_action\": recommended_action,\n            \"heuristic_note\": \"recommended_* is only a heuristic hint derived from latest bindings and recent task activity. The supervisor must decide by reading panel history, social history, and task states.\",\n        }\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_list_global_skills/cheapclaw_list_global_skills.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import list_global_skills\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawListGlobalSkillsTool(BaseTool):\n    name = \"cheapclaw_list_global_skills\"\n    def execute(self, task_id, parameters):\n        skills = list_global_skills()\n        return {\"status\": \"success\", \"output\": f\"skills={len(skills)}\", \"skills\": skills}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_read_panel/cheapclaw_read_panel.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import load_panel\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawReadPanelTool(BaseTool):\n    name = \"cheapclaw_read_panel\"\n    def execute(self, task_id, parameters):\n        panel = load_panel()\n        only_dirty = bool(parameters.get(\"only_dirty\", False))\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        channels = panel.get(\"channels\", {})\n        if channel:\n            channels = {channel: channels.get(channel, {\"conversations\": {}})}\n        if conversation_id:\n            filtered = {}\n            for ch, payload in channels.items():\n                conv = payload.get(\"conversations\", {}).get(conversation_id)\n                if conv:\n                    filtered[ch] = {\"conversations\": {conversation_id: conv}}\n            channels = filtered\n        if only_dirty:\n            filtered = {}\n            for ch, payload in channels.items():\n                convs = {cid: conv for cid, conv in payload.get(\"conversations\", {}).items() if conv.get(\"dirty\")}\n                if convs:\n                    filtered[ch] = {\"conversations\": convs}\n            channels = filtered\n        return {\"status\": \"success\", \"output\": \"ok\", \"panel\": {\"version\": panel.get(\"version\", 1), \"channels\": channels, \"service_state\": panel.get(\"service_state\", {})}}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_read_social_history/cheapclaw_read_social_history.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import read_social_history\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawReadSocialHistoryTool(BaseTool):\n    name = \"cheapclaw_read_social_history\"\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        if not channel or not conversation_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel and conversation_id are required\"}\n        items = read_social_history(\n            channel=channel,\n            conversation_id=conversation_id,\n            limit=int(parameters.get(\"limit\", 30) or 30),\n            only_mentions_to_bot=bool(parameters.get(\"only_mentions_to_bot\", False)),\n            include_bot_replies=bool(parameters.get(\"include_bot_replies\", True)),\n            from_message_id=str(parameters.get(\"from_message_id\") or \"\"),\n            to_message_id=str(parameters.get(\"to_message_id\") or \"\"),\n            before_timestamp=str(parameters.get(\"before_timestamp\") or \"\"),\n            after_timestamp=str(parameters.get(\"after_timestamp\") or \"\"),\n        )\n        return {\"status\": \"success\", \"output\": f\"history_items={len(items)}\", \"messages\": items}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_reset_task/cheapclaw_reset_task.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nfrom infiagent import infiagent\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawResetTaskTool(BaseTool):\n    name = \"cheapclaw_reset_task\"\n    def execute(self, task_id, parameters):\n        target_task_id = str(Path(parameters.get(\"task_id\") or \"\").expanduser().resolve())\n        if not target_task_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"task_id is required\"}\n        agent = infiagent(user_data_root=str(Path(__import__('os').environ.get('MLA_USER_DATA_ROOT','~/mla_v3')).expanduser().resolve()))\n        return agent.reset_task(\n            task_id=target_task_id,\n            preserve_history=bool(parameters.get(\"preserve_history\", True)),\n            kill_background_processes=bool(parameters.get(\"kill_background_processes\", True)),\n            reason=str(parameters.get(\"reason\") or \"manual reset\"),\n        )\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_reveal_skills/cheapclaw_reveal_skills.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nfrom infiagent import infiagent\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import extend_task_visible_skills, load_panel, update_conversation_task\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawRevealSkillsTool(BaseTool):\n    name = \"cheapclaw_reveal_skills\"\n    def execute(self, task_id, parameters):\n        target_task_id = str(Path(parameters.get(\"task_id\") or \"\").expanduser().resolve())\n        skill_names = parameters.get(\"skill_names\") or []\n        if not target_task_id or not isinstance(skill_names, list) or not skill_names:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"task_id and non-empty skill_names are required\"}\n        payload = extend_task_visible_skills(target_task_id, skill_names)\n        panel = load_panel()\n        for channel_payload in panel.get(\"channels\", {}).values():\n            for conv in channel_payload.get(\"conversations\", {}).values():\n                for linked in conv.get(\"linked_tasks\", []):\n                    if linked.get(\"task_id\") == target_task_id:\n                        update_conversation_task(\n                            str(conv.get(\"channel\") or \"\"),\n                            str(conv.get(\"conversation_id\") or \"\"),\n                            target_task_id,\n                            {\"default_exposed_skills\": list(payload.get(\"visible_skills\") or [])},\n                            mark_dirty=False,\n                        )\n                        break\n        result = {\n            \"status\": \"success\",\n            \"output\": f\"visible skills updated: {len(payload['visible_skills'])}\",\n            \"task_id\": target_task_id,\n            \"visible_skills\": list(payload.get(\"visible_skills\") or []),\n        }\n        if bool(parameters.get(\"run_fresh\", False)):\n            agent = infiagent(user_data_root=str(Path(__import__('os').environ.get('MLA_USER_DATA_ROOT','~/mla_v3')).expanduser().resolve()))\n            result[\"fresh\"] = agent.fresh(task_id=target_task_id, reason=\"skills revealed\")\n        return result\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_schedule_plan/cheapclaw_schedule_plan.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import create_plan\nfrom tool_server_lite.tools.file_tools import BaseTool\n\nclass CheapClawSchedulePlanTool(BaseTool):\n    name = \"cheapclaw_schedule_plan\"\n    def execute(self, task_id, parameters):\n        name = str(parameters.get(\"name\") or \"\").strip()\n        scope = str(parameters.get(\"scope\") or \"\").strip()\n        if not name or not scope:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"name and scope are required\"}\n        plan = create_plan(\n            name=name,\n            scope=scope,\n            task_id=str(parameters.get(\"task_id\") or \"\").strip(),\n            channel=str(parameters.get(\"channel\") or \"\").strip(),\n            conversation_id=str(parameters.get(\"conversation_id\") or \"\").strip(),\n            interval_sec=int(parameters.get(\"interval_sec\") or 0),\n            once_at=str(parameters.get(\"once_at\") or \"\").strip(),\n            schedule_type=str(parameters.get(\"schedule_type\") or \"\").strip(),\n            time_of_day=str(parameters.get(\"time_of_day\") or \"\").strip(),\n            days_of_week=parameters.get(\"days_of_week\") or [],\n            message=str(parameters.get(\"message\") or \"\").strip(),\n            enabled=bool(parameters.get(\"enabled\", True)),\n        )\n        return {\"status\": \"success\", \"output\": f\"created plan {plan['plan_id']}\", \"plan\": plan}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_send_file/cheapclaw_send_file.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import queue_outbound_message\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\ndef _get_active_service():\n    main_mod = sys.modules.get(\"__main__\")\n    active_service = getattr(main_mod, \"ACTIVE_SERVICE\", None) if main_mod is not None else None\n    if active_service is not None:\n        return active_service\n    try:\n        import cheapclaw_service as _cheapclaw_service\n        return getattr(_cheapclaw_service, \"ACTIVE_SERVICE\", None)\n    except Exception:\n        return None\n\n\nclass CheapClawSendFileTool(BaseTool):\n    name = \"cheapclaw_send_file\"\n\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        local_path = str(parameters.get(\"local_path\") or \"\").strip()\n        if not channel or not conversation_id or not local_path:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel, conversation_id and local_path are required\"}\n\n        file_path = Path(local_path).expanduser().resolve()\n        if not file_path.exists() or not file_path.is_file():\n            return {\"status\": \"error\", \"output\": \"\", \"error\": f\"file not found: {file_path}\"}\n\n        attachment = {\n            \"local_path\": str(file_path),\n            \"filename\": str(parameters.get(\"filename\") or file_path.name),\n            \"mime_type\": str(parameters.get(\"mime_type\") or \"\").strip(),\n            \"kind\": str(parameters.get(\"kind\") or \"auto\").strip(),\n            \"caption\": str(parameters.get(\"caption\") or \"\").strip(),\n        }\n        active_service = _get_active_service()\n        if active_service is not None:\n            result = active_service.send_message_now(\n                channel=channel,\n                conversation_id=conversation_id,\n                message=str(parameters.get(\"message\") or \"\").strip(),\n                attachments=[attachment],\n            )\n            if result.get(\"status\") == \"success\":\n                return result\n        payload = queue_outbound_message(\n            channel=channel,\n            conversation_id=conversation_id,\n            message=str(parameters.get(\"message\") or \"\").strip(),\n            attachments=[attachment],\n            metadata={\"requested_by_task\": str(task_id or \"\"), \"mode\": \"send_file\"},\n        )\n        return {\"status\": \"success\", \"output\": f\"queued outbound file {payload['event_id']}\", **payload}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_send_message/cheapclaw_send_message.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import queue_outbound_message\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\ndef _get_active_service():\n    main_mod = sys.modules.get(\"__main__\")\n    active_service = getattr(main_mod, \"ACTIVE_SERVICE\", None) if main_mod is not None else None\n    if active_service is not None:\n        return active_service\n    try:\n        import cheapclaw_service as _cheapclaw_service\n        return getattr(_cheapclaw_service, \"ACTIVE_SERVICE\", None)\n    except Exception:\n        return None\n\n\nclass CheapClawSendMessageTool(BaseTool):\n    name = \"cheapclaw_send_message\"\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        message = str(parameters.get(\"message\") or \"\").strip()\n        if not channel or not conversation_id or not message:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel, conversation_id and message are required\"}\n        active_service = _get_active_service()\n        if active_service is not None:\n            result = active_service.send_message_now(\n                channel=channel,\n                conversation_id=conversation_id,\n                message=message,\n                attachments=parameters.get(\"attachments\") or [],\n            )\n            if result.get(\"status\") == \"success\":\n                return result\n        payload = queue_outbound_message(\n            channel=channel,\n            conversation_id=conversation_id,\n            message=message,\n            attachments=parameters.get(\"attachments\") or [],\n            metadata={\"requested_by_task\": str(task_id or \"\")},\n        )\n        return {\"status\": \"success\", \"output\": f\"queued outbound message {payload['event_id']}\", **payload}\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_start_task/cheapclaw_start_task.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nFINAL_OUTPUT_HOOK_CALLBACK = f\"{(APP_ROOT / 'cheapclaw_hooks.py').resolve()}:on_tool_event\"\n\nfrom infiagent import infiagent\nfrom tool_runtime_helpers import (\n    bind_messages_to_task,\n    ensure_conversation,\n    load_panel,\n    mutate_panel,\n    now_iso,\n    set_task_visible_skills,\n)\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\ndef _load_cheapclaw_settings(user_root: str):\n    example_path = Path(__file__).resolve().parents[2] / \"assets\" / \"config\" / \"app_config.example.json\"\n    try:\n        example_payload = __import__(\"json\").loads(example_path.read_text(encoding=\"utf-8\"))\n    except Exception:\n        example_payload = {\"cheapclaw\": {\"default_exposed_skills\": [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"], \"default_mcp_servers\": []}}\n    config_path = Path(user_root).expanduser().resolve() / \"cheapclaw\" / \"config\" / \"app_config.json\"\n    try:\n        payload = __import__(\"json\").loads(config_path.read_text(encoding=\"utf-8\"))\n    except Exception:\n        payload = example_payload\n    cheapclaw = payload.get(\"cheapclaw\", {}) if isinstance(payload, dict) else {}\n    example_cheapclaw = example_payload.get(\"cheapclaw\", {}) if isinstance(example_payload, dict) else {}\n    default_skills = cheapclaw.get(\"default_exposed_skills\", example_cheapclaw.get(\"default_exposed_skills\", [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"]))\n    if not isinstance(default_skills, list):\n        default_skills = list(example_cheapclaw.get(\"default_exposed_skills\", [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"]))\n    default_mcp_servers = cheapclaw.get(\"default_mcp_servers\", example_cheapclaw.get(\"default_mcp_servers\", []))\n    if not isinstance(default_mcp_servers, list):\n        default_mcp_servers = list(example_cheapclaw.get(\"default_mcp_servers\", []))\n    return {\n        \"default_exposed_skills\": [str(item).strip() for item in default_skills if str(item).strip()],\n        \"default_mcp_servers\": [item for item in default_mcp_servers if isinstance(item, dict)],\n    }\n\n\ndef _default_task_view(task_id):\n    return {\n        \"task_id\": task_id,\n        \"agent_system\": \"\",\n        \"agent_name\": \"\",\n        \"status\": \"unknown\",\n        \"share_context_path\": \"\",\n        \"stack_path\": \"\",\n        \"log_path\": \"\",\n        \"skills_dir\": \"\",\n        \"default_exposed_skills\": [],\n        \"mcp_servers\": [],\n        \"last_thinking\": \"\",\n        \"last_thinking_at\": \"\",\n        \"last_final_output\": \"\",\n        \"last_final_output_at\": \"\",\n        \"last_action_at\": \"\",\n        \"last_log_at\": \"\",\n        \"last_launch_at\": \"\",\n        \"fresh_retry_count\": 0,\n        \"last_watchdog_note\": \"\",\n        \"created_at\": now_iso(),\n    }\n\n\nclass CheapClawStartTaskTool(BaseTool):\n    name = \"cheapclaw_start_task\"\n\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        task_name = str(parameters.get(\"task_name\") or \"\").strip()\n        user_input = str(parameters.get(\"user_input\") or \"\").strip()\n        provided_task_id = str(parameters.get(\"task_id\") or \"\").strip()\n        if not channel or not conversation_id or not task_name or not user_input or not provided_task_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"task_id, channel, conversation_id, task_name and user_input are required\"}\n\n        user_root = str(Path(__import__(\"os\").environ.get(\"MLA_USER_DATA_ROOT\", \"~/mla_v3\")).expanduser().resolve())\n        tools_root = str(Path(__file__).resolve().parents[1])\n        cheapclaw_settings = _load_cheapclaw_settings(user_root)\n        agent = infiagent(user_data_root=user_root, tools_dir=tools_root, seed_builtin_resources=False)\n        resolved_task_id = str(Path(provided_task_id).expanduser().resolve())\n        requested_agent_system = str(parameters.get(\"agent_system\") or \"CheapClawWorkerGeneral\").strip() or \"CheapClawWorkerGeneral\"\n        requested_agent_name = str(parameters.get(\"agent_name\") or \"\").strip()\n        if requested_agent_system == \"CheapClawSupervisor\":\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"禁止使用 CheapClawSupervisor 启动后台任务，主调度 agent 不能调用本身。\",\n            }\n\n        systems_payload = agent.list_agent_systems()\n        systems = {\n            str(item.get(\"name\") or \"\"): item\n            for item in systems_payload.get(\"agent_systems\", [])\n            if isinstance(item, dict)\n        }\n        system_info = systems.get(requested_agent_system, {})\n        available_agent_names = [str(name).strip() for name in system_info.get(\"agent_names\", []) if str(name).strip()]\n        if requested_agent_system == \"CheapClawWorkerGeneral\":\n            selected_agent_name = \"worker_agent\"\n        elif requested_agent_name and requested_agent_name in available_agent_names:\n            selected_agent_name = requested_agent_name\n        elif available_agent_names:\n            selected_agent_name = available_agent_names[0]\n        else:\n            selected_agent_name = requested_agent_name or \"worker_agent\"\n\n        config = {\"tools_dir\": tools_root}\n        panel = load_panel()\n        existing_task_view = next(\n            (\n                item for item in panel.get(\"channels\", {}).get(channel, {}).get(\"conversations\", {}).get(conversation_id, {}).get(\"linked_tasks\", [])\n                if item.get(\"task_id\") == resolved_task_id\n            ),\n            {},\n        )\n        configured_defaults = list(existing_task_view.get(\"default_exposed_skills\") or cheapclaw_settings.get(\"default_exposed_skills\", [\"docx\", \"pptx\", \"xlsx\", \"find-skills\"]))\n        requested_exposed = parameters.get(\"exposed_skills\")\n        if requested_exposed is None:\n            exposed = configured_defaults\n        else:\n            merged = []\n            for item in configured_defaults + list(requested_exposed or []):\n                name = str(item).strip()\n                if name and name not in merged:\n                    merged.append(name)\n            exposed = merged\n        config[\"mcp_servers\"] = list((parameters.get(\"config\") or {}).get(\"mcp_servers\") or existing_task_view.get(\"mcp_servers\") or cheapclaw_settings.get(\"default_mcp_servers\", []))\n        config[\"visible_skills\"] = list(exposed)\n\n        config.update(parameters.get(\"config\") or {})\n        existing_hooks = list(config.get(\"tool_hooks\") or [])\n        if not any(str(item.get(\"callback\") or \"\") == FINAL_OUTPUT_HOOK_CALLBACK for item in existing_hooks if isinstance(item, dict)):\n            existing_hooks.append({\n                \"name\": \"cheapclaw-final-output\",\n                \"callback\": FINAL_OUTPUT_HOOK_CALLBACK,\n                \"when\": \"after\",\n                \"tool_names\": [\"final_output\"],\n                \"include_arguments\": False,\n                \"include_result\": True,\n            })\n        config[\"tool_hooks\"] = existing_hooks\n\n        result = agent.start_background_task(\n            task_id=resolved_task_id,\n            user_input=f\"{user_input}\\n\\n[dispatched_at {now_iso()}]\",\n            agent_system=requested_agent_system,\n            agent_name=selected_agent_name,\n            force_new=bool(parameters.get(\"force_new\", False)),\n            config=config,\n        )\n        if result.get(\"status\") != \"success\":\n            return result\n\n        snapshot = agent.task_snapshot(task_id=resolved_task_id)\n        set_task_visible_skills(resolved_task_id, exposed)\n\n        def _mutate(panel):\n            conv = ensure_conversation(\n                panel,\n                channel=channel,\n                conversation_id=conversation_id,\n                conversation_type=str(parameters.get(\"conversation_type\") or \"group\"),\n                display_name=str(parameters.get(\"display_name\") or conversation_id),\n                require_mention=bool(parameters.get(\"require_mention\", True)),\n            )\n            linked = conv.setdefault(\"linked_tasks\", [])\n            existing = next((item for item in linked if item.get(\"task_id\") == resolved_task_id), None)\n            view = _default_task_view(resolved_task_id)\n            view.update({\n                \"agent_system\": result.get(\"agent_system\", \"CheapClawWorkerGeneral\"),\n                \"agent_name\": result.get(\"agent_name\", selected_agent_name),\n                \"status\": \"running\",\n                \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n                \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n                \"log_path\": result.get(\"log_path\", \"\"),\n                \"skills_dir\": \"\",\n                \"default_exposed_skills\": list(exposed or []),\n                \"mcp_servers\": list(config.get(\"mcp_servers\") or []),\n                \"last_thinking\": snapshot.get(\"latest_thinking\", \"\"),\n                \"last_thinking_at\": snapshot.get(\"latest_thinking_at\", \"\"),\n                \"last_final_output\": snapshot.get(\"last_final_output\", \"\"),\n                \"last_final_output_at\": snapshot.get(\"last_final_output_at\", \"\"),\n                \"last_action_at\": snapshot.get(\"last_updated\", \"\"),\n                \"last_log_at\": now_iso(),\n                \"last_launch_at\": now_iso(),\n                \"last_watchdog_note\": \"task launched by supervisor\",\n                \"user_input\": str((snapshot.get(\"runtime\") or {}).get(\"user_input\") or user_input or \"\"),\n                \"latest_instruction\": str(((snapshot.get(\"latest_instruction\") or {}) if isinstance(snapshot.get(\"latest_instruction\"), dict) else {}).get(\"instruction\") or user_input or \"\"),\n                \"created_at\": str((existing or existing_task_view).get(\"created_at\") or \"\") or now_iso(),\n            })\n            if existing is None:\n                linked.append(view)\n            else:\n                existing.update(view)\n            conv.setdefault(\"pending_events\", []).append({\"type\": \"task_started\", \"task_id\": resolved_task_id, \"timestamp\": now_iso()})\n            conv[\"dirty\"] = True\n            conv[\"updated_at\"] = now_iso()\n            panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n            return panel\n\n        mutate_panel(_mutate)\n\n        source_message_ids = parameters.get(\"source_message_ids\") or []\n        if isinstance(source_message_ids, list) and source_message_ids:\n            bind_messages_to_task(channel, conversation_id, resolved_task_id, source_message_ids, note=\"new task started from supervisor decision\")\n\n        return {\n            \"status\": \"success\",\n            **result,\n            \"requested_agent_name\": requested_agent_name,\n            \"selected_agent_name\": selected_agent_name,\n            \"available_agent_names\": available_agent_names,\n            \"share_context_path\": snapshot.get(\"share_context_path\", \"\"),\n            \"stack_path\": snapshot.get(\"stack_path\", \"\"),\n        }\n"
  },
  {
    "path": "apps/cheapclaw/tools_library/cheapclaw_update_panel/cheapclaw_update_panel.py",
    "content": "#!/usr/bin/env python3\nfrom pathlib import Path\nimport sys\n\nAPP_ROOT = Path(__file__).resolve().parents[2]\nif str(APP_ROOT) not in sys.path:\n    sys.path.insert(0, str(APP_ROOT))\n\nfrom tool_runtime_helpers import (\n    bind_messages_to_task,\n    clear_conversation_dirty,\n    ensure_conversation,\n    mutate_panel,\n    now_iso,\n    update_conversation_task,\n)\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\nclass CheapClawUpdatePanelTool(BaseTool):\n    name = \"cheapclaw_update_panel\"\n\n    def execute(self, task_id, parameters):\n        channel = str(parameters.get(\"channel\") or \"\").strip()\n        conversation_id = str(parameters.get(\"conversation_id\") or \"\").strip()\n        if not channel or not conversation_id:\n            return {\"status\": \"error\", \"output\": \"\", \"error\": \"channel and conversation_id are required\"}\n\n        operations = []\n        if parameters.get(\"clear_dirty\"):\n            clear_conversation_dirty(channel, conversation_id)\n            operations.append(\"clear_dirty\")\n        else:\n            def _mutate(panel):\n                conv = ensure_conversation(panel, channel=channel, conversation_id=conversation_id)\n                if parameters.get(\"set_dirty\") is not None:\n                    conv[\"dirty\"] = bool(parameters.get(\"set_dirty\"))\n                    panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = bool(parameters.get(\"set_dirty\"))\n                    operations.append(\"set_dirty\")\n                conversation_patch = parameters.get(\"conversation_patch\") or {}\n                if isinstance(conversation_patch, dict):\n                    conv.update(conversation_patch)\n                    operations.append(\"conversation_patch\")\n                pending_event = parameters.get(\"append_pending_event\")\n                if isinstance(pending_event, dict):\n                    conv.setdefault(\"pending_events\", []).append(pending_event)\n                    operations.append(\"append_pending_event\")\n                conv[\"unread_event_count\"] = len(conv.get(\"pending_events\", []))\n                conv[\"updated_at\"] = now_iso()\n                return panel\n            mutate_panel(_mutate)\n\n        target_task_id = str(parameters.get(\"task_id\") or \"\").strip()\n        task_patch = parameters.get(\"task_patch\") or {}\n        if target_task_id and isinstance(task_patch, dict):\n            update_conversation_task(channel, conversation_id, target_task_id, task_patch, mark_dirty=bool(parameters.get(\"set_dirty\", False)))\n            operations.append(\"task_patch\")\n\n        bind_message_ids = parameters.get(\"bind_message_ids\") or []\n        if target_task_id and isinstance(bind_message_ids, list) and bind_message_ids:\n            bind_messages_to_task(\n                channel,\n                conversation_id,\n                target_task_id,\n                bind_message_ids,\n                note=str(parameters.get(\"binding_note\") or \"manual panel binding\"),\n                binding_type=str(parameters.get(\"binding_type\") or \"task\"),\n            )\n            operations.append(\"bind_messages\")\n\n        return {\n            \"status\": \"success\",\n            \"output\": \"ok\",\n            \"channel\": channel,\n            \"conversation_id\": conversation_id,\n            \"task_id\": target_task_id,\n            \"operations\": operations,\n        }\n"
  },
  {
    "path": "apps/cheapclaw/web/dashboard.html",
    "content": "<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <title>CheapClaw Dashboard</title>\n  <style>\n    :root {\n      --bg: #f2efe8;\n      --panel: #fffaf2;\n      --ink: #14211b;\n      --muted: #6b746d;\n      --line: #d9cfbf;\n      --accent: #c45c2f;\n      --accent-2: #2f6f5f;\n      --warn: #a43f2e;\n      --shadow: 0 12px 30px rgba(20,33,27,0.08);\n      --mono: \"IBM Plex Mono\", \"SFMono-Regular\", Menlo, monospace;\n      --sans: \"Avenir Next\", \"PingFang SC\", \"Helvetica Neue\", sans-serif;\n    }\n    * { box-sizing: border-box; }\n    body {\n      margin: 0;\n      font-family: var(--sans);\n      color: var(--ink);\n      background:\n        radial-gradient(circle at top left, rgba(196,92,47,0.16), transparent 24rem),\n        radial-gradient(circle at top right, rgba(47,111,95,0.12), transparent 26rem),\n        var(--bg);\n    }\n    .shell {\n      max-width: 1440px;\n      margin: 0 auto;\n      padding: 24px;\n    }\n    .hero {\n      display: flex;\n      justify-content: space-between;\n      align-items: flex-end;\n      gap: 16px;\n      margin-bottom: 20px;\n    }\n    .hero h1 {\n      margin: 0;\n      font-size: clamp(28px, 4vw, 52px);\n      line-height: 0.95;\n      letter-spacing: -0.04em;\n    }\n    .hero .meta {\n      color: var(--muted);\n      font-size: 13px;\n    }\n    .grid {\n      display: grid;\n      grid-template-columns: 360px 1fr;\n      gap: 18px;\n    }\n    .card {\n      background: var(--panel);\n      border: 1px solid var(--line);\n      border-radius: 22px;\n      box-shadow: var(--shadow);\n      overflow: hidden;\n    }\n    .card-header {\n      padding: 16px 18px 12px;\n      border-bottom: 1px solid var(--line);\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      gap: 12px;\n    }\n    .card-header h2 {\n      margin: 0;\n      font-size: 15px;\n      text-transform: uppercase;\n      letter-spacing: 0.08em;\n    }\n    .badge {\n      padding: 5px 10px;\n      border-radius: 999px;\n      background: rgba(196,92,47,0.12);\n      color: var(--accent);\n      font-size: 12px;\n      font-weight: 600;\n    }\n    .list {\n      max-height: calc(100vh - 180px);\n      overflow: auto;\n    }\n    .conversation {\n      padding: 14px 18px;\n      border-bottom: 1px solid rgba(217,207,191,0.7);\n      cursor: pointer;\n    }\n    .conversation.active { background: rgba(47,111,95,0.08); }\n    .conversation:last-child { border-bottom: 0; }\n    .conversation .title {\n      font-weight: 700;\n      display: flex;\n      justify-content: space-between;\n      gap: 10px;\n      margin-bottom: 6px;\n    }\n    .conversation .sub, .muted {\n      color: var(--muted);\n      font-size: 12px;\n    }\n    .detail {\n      padding: 0;\n      display: grid;\n      grid-template-rows: auto auto 1fr;\n      min-height: calc(100vh - 180px);\n    }\n    .detail-section { padding: 18px; border-bottom: 1px solid var(--line); }\n    .detail-section:last-child { border-bottom: 0; }\n    .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }\n    .chip {\n      padding: 6px 10px;\n      border-radius: 999px;\n      background: rgba(20,33,27,0.06);\n      font-size: 12px;\n      font-family: var(--mono);\n    }\n    .tasks, .messages {\n      display: grid;\n      gap: 12px;\n    }\n    .task, .message {\n      border: 1px solid var(--line);\n      border-radius: 18px;\n      padding: 14px;\n      background: rgba(255,255,255,0.66);\n    }\n    .task.active {\n      border-color: var(--accent);\n      background: rgba(196,92,47,0.08);\n    }\n    .task .row, .message .row {\n      display: flex;\n      justify-content: space-between;\n      gap: 12px;\n      margin-bottom: 8px;\n    }\n    .task .row:last-child, .message .row:last-child { margin-bottom: 0; }\n    .mono {\n      font-family: var(--mono);\n      font-size: 12px;\n      word-break: break-all;\n    }\n    .status-running { color: var(--accent-2); }\n    .status-idle { color: var(--muted); }\n    .status-unknown, .status-error { color: var(--warn); }\n    .empty {\n      padding: 32px 18px;\n      text-align: center;\n      color: var(--muted);\n    }\n    .settings-grid {\n      display: grid;\n      gap: 10px;\n    }\n    .settings-label {\n      font-size: 12px;\n      text-transform: uppercase;\n      letter-spacing: 0.08em;\n      color: var(--muted);\n    }\n    .skill-grid {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 8px;\n    }\n    .skill-option {\n      display: inline-flex;\n      align-items: center;\n      gap: 6px;\n      border: 1px solid var(--line);\n      border-radius: 999px;\n      padding: 6px 10px;\n      background: rgba(255,255,255,0.7);\n      font-size: 12px;\n    }\n    .settings-textarea {\n      width: 100%;\n      min-height: 120px;\n      resize: vertical;\n      padding: 12px;\n      border-radius: 14px;\n      border: 1px solid var(--line);\n      background: rgba(255,255,255,0.8);\n      font-family: var(--mono);\n      font-size: 12px;\n    }\n    .button-row {\n      display: flex;\n      justify-content: flex-end;\n      gap: 10px;\n    }\n    button {\n      appearance: none;\n      border: 0;\n      border-radius: 999px;\n      padding: 10px 16px;\n      background: var(--accent);\n      color: white;\n      cursor: pointer;\n      font-weight: 600;\n    }\n    button.secondary {\n      background: rgba(20,33,27,0.12);\n      color: var(--ink);\n    }\n    pre {\n      margin: 0;\n      white-space: pre-wrap;\n      word-break: break-word;\n      font-family: var(--sans);\n      font-size: 13px;\n      line-height: 1.55;\n    }\n    @media (max-width: 960px) {\n      .grid { grid-template-columns: 1fr; }\n      .list, .detail { max-height: none; min-height: 0; }\n    }\n  </style>\n</head>\n<body>\n  <div class=\"shell\">\n    <div class=\"hero\">\n      <div>\n        <div class=\"meta\">CheapClaw / Live Panel</div>\n        <h1>Conversations<br/>And Tasks</h1>\n      </div>\n      <div class=\"meta\" id=\"runtimeMeta\">loading…</div>\n    </div>\n\n    <div class=\"grid\">\n      <section class=\"card\">\n        <div class=\"card-header\">\n          <h2>Conversations</h2>\n          <span class=\"badge\" id=\"conversationCount\">0</span>\n        </div>\n        <div class=\"list\" id=\"conversationList\"></div>\n      </section>\n\n      <section class=\"card detail\">\n        <div class=\"detail-section\" id=\"conversationSummary\"></div>\n        <div class=\"detail-section\">\n          <div class=\"card-header\" style=\"padding:0 0 12px;border:0;\">\n            <h2>Tasks</h2>\n          </div>\n          <div class=\"tasks\" id=\"taskList\"></div>\n        </div>\n        <div class=\"detail-section\">\n          <div class=\"card-header\" style=\"padding:0 0 12px;border:0;\">\n            <h2>Task Settings</h2>\n          </div>\n          <div id=\"taskSettings\"></div>\n        </div>\n        <div class=\"detail-section\" style=\"border-bottom:0;\">\n          <div class=\"card-header\" style=\"padding:0 0 12px;border:0;\">\n            <h2>Recent Messages</h2>\n          </div>\n          <div class=\"messages\" id=\"messageList\"></div>\n        </div>\n      </section>\n    </div>\n  </div>\n\n  <script>\n    const state = { panel: null, selectedKey: \"\", selectedTaskId: \"\", globalSkills: [] };\n\n    function escapeHtml(value) {\n      return String(value || \"\")\n        .replace(/&/g, \"&amp;\")\n        .replace(/</g, \"&lt;\")\n        .replace(/>/g, \"&gt;\")\n        .replace(/\\\"/g, \"&quot;\");\n    }\n\n    function flattenConversations(panel) {\n      const items = [];\n      const channels = panel.channels || {};\n      for (const [channel, payload] of Object.entries(channels)) {\n        const conversations = (payload || {}).conversations || {};\n        for (const [conversationId, conv] of Object.entries(conversations)) {\n          items.push({ key: `${channel}:${conversationId}`, channel, conversationId, ...conv });\n        }\n      }\n      items.sort((a, b) => String(b.updated_at || \"\").localeCompare(String(a.updated_at || \"\")));\n      return items;\n    }\n\n    function sortTasks(tasks) {\n      const toIso = (task) => {\n        if (task.created_at) return String(task.created_at);\n        const id = String(task.task_id || \"\").split(\"/\").pop() || \"\";\n        const match = id.match(/^(\\d{8})_(\\d{6})/);\n        if (!match) return \"\";\n        return `${match[1].slice(0,4)}-${match[1].slice(4,6)}-${match[1].slice(6,8)}T${match[2].slice(0,2)}:${match[2].slice(2,4)}:${match[2].slice(4,6)}`;\n      };\n      return [...(tasks || [])].sort((a, b) => String(toIso(b)).localeCompare(String(toIso(a))));\n    }\n\n    function renderConversations(items) {\n      const root = document.getElementById(\"conversationList\");\n      document.getElementById(\"conversationCount\").textContent = String(items.length);\n      if (!items.length) {\n        root.innerHTML = '<div class=\"empty\">No conversations yet.</div>';\n        return;\n      }\n      root.innerHTML = items.map((item) => `\n        <div class=\"conversation ${state.selectedKey === item.key ? \"active\" : \"\"}\" data-key=\"${item.key}\">\n          <div class=\"title\">\n            <span>${escapeHtml(item.display_name || item.conversation_id)}</span>\n            <span class=\"muted\">${escapeHtml(item.channel)}</span>\n          </div>\n          <div class=\"sub\">dirty=${item.dirty ? \"true\" : \"false\"} · running=${item.running_task_count || 0} · pending=${(item.pending_events || []).length}</div>\n          <div class=\"sub\">${escapeHtml(item.latest_user_message_at || item.updated_at || \"\")}</div>\n        </div>\n      `).join(\"\");\n      root.querySelectorAll(\".conversation\").forEach((node) => {\n        node.addEventListener(\"click\", () => {\n          state.selectedKey = node.dataset.key;\n          render();\n        });\n      });\n    }\n\n    function renderDetail(item) {\n      const summary = document.getElementById(\"conversationSummary\");\n      const taskList = document.getElementById(\"taskList\");\n      const taskSettings = document.getElementById(\"taskSettings\");\n      const messageList = document.getElementById(\"messageList\");\n\n      if (!item) {\n        summary.innerHTML = '<div class=\"empty\">Select a conversation.</div>';\n        taskList.innerHTML = \"\";\n        taskSettings.innerHTML = \"\";\n        messageList.innerHTML = \"\";\n        return;\n      }\n\n      summary.innerHTML = `\n        <div class=\"row\" style=\"display:flex;justify-content:space-between;gap:12px;\">\n          <div>\n            <h2 style=\"margin:0 0 8px 0;font-size:26px;text-transform:none;letter-spacing:-0.03em;\">${escapeHtml(item.display_name || item.conversation_id)}</h2>\n            <div class=\"muted\">${escapeHtml(item.channel)} / ${escapeHtml(item.conversation_type || \"\")}</div>\n          </div>\n          <div class=\"badge\">${item.dirty ? \"DIRTY\" : \"CLEAN\"}</div>\n        </div>\n        <div class=\"chips\">\n          <span class=\"chip\">conversation_id: ${escapeHtml(item.conversation_id)}</span>\n          <span class=\"chip\">running_task_count: ${escapeHtml(item.running_task_count || 0)}</span>\n          <span class=\"chip\">pending_events: ${escapeHtml((item.pending_events || []).length)}</span>\n          <span class=\"chip\">updated_at: ${escapeHtml(item.updated_at || \"\")}</span>\n        </div>\n      `;\n\n      const tasks = sortTasks(item.linked_tasks || []);\n      if (!state.selectedTaskId && tasks.length) state.selectedTaskId = tasks[0].task_id;\n      if (state.selectedTaskId && !tasks.find((task) => task.task_id === state.selectedTaskId)) {\n        state.selectedTaskId = tasks[0] ? tasks[0].task_id : \"\";\n      }\n      taskList.innerHTML = tasks.length ? tasks.map((task) => `\n        <div class=\"task ${state.selectedTaskId === task.task_id ? \"active\" : \"\"}\" data-task-id=\"${escapeHtml(task.task_id || \"\")}\">\n          <div class=\"row\">\n            <strong>${escapeHtml(task.agent_name || \"worker_agent\")}</strong>\n            <span class=\"status-${escapeHtml(task.status || \"unknown\")}\">${escapeHtml(task.status || \"unknown\")}</span>\n          </div>\n          <div class=\"row mono\">${escapeHtml(task.task_id || \"\")}</div>\n          <div class=\"row muted\">\n            <span>${escapeHtml(task.agent_system || \"\")}</span>\n            <span>${escapeHtml(task.last_final_output_at || task.last_thinking_at || \"\")}</span>\n          </div>\n          <div class=\"row\"><pre>${escapeHtml(task.last_final_output || task.last_thinking || task.watchdog_observation || \"\")}</pre></div>\n          <div class=\"row muted\">\n            <span>skills: ${escapeHtml((task.default_exposed_skills || []).join(\", \") || \"-\")}</span>\n            <span>mcp: ${escapeHtml(String((task.mcp_servers || []).length || 0))}</span>\n          </div>\n        </div>\n      `).join(\"\") : '<div class=\"empty\">No linked tasks.</div>';\n      taskList.querySelectorAll(\".task\").forEach((node) => {\n        node.addEventListener(\"click\", async () => {\n          state.selectedTaskId = node.dataset.taskId;\n          render();\n          await loadTaskSettings(state.selectedTaskId);\n        });\n      });\n\n      renderTaskSettings(tasks.find((task) => task.task_id === state.selectedTaskId));\n\n      const messages = item.messages || [];\n      messageList.innerHTML = messages.length ? messages.slice(-12).reverse().map((msg) => `\n        <div class=\"message\">\n          <div class=\"row\">\n            <strong>${escapeHtml(msg.direction || \"\")}</strong>\n            <span class=\"muted\">${escapeHtml(msg.timestamp || \"\")}</span>\n          </div>\n          <div class=\"row\"><pre>${escapeHtml(msg.text || \"\")}</pre></div>\n          <div class=\"row mono\">${escapeHtml(msg.message_id || \"\")}</div>\n        </div>\n      `).join(\"\") : '<div class=\"empty\">No messages.</div>';\n    }\n\n    function renderTaskSettings(task) {\n      const root = document.getElementById(\"taskSettings\");\n      if (!task) {\n        root.innerHTML = '<div class=\"empty\">Select a task to edit its default skills and MCP visibility.</div>';\n        return;\n      }\n      const selectedSkills = new Set(task.default_exposed_skills || []);\n      root.innerHTML = `\n        <div class=\"settings-grid\">\n          <div class=\"mono\">${escapeHtml(task.task_id || \"\")}</div>\n          <div class=\"settings-label\">Default Exposed Skills</div>\n          <div class=\"skill-grid\">\n            ${(state.globalSkills || []).map((skill) => `\n              <label class=\"skill-option\">\n                <input type=\"checkbox\" value=\"${escapeHtml(skill.name)}\" ${selectedSkills.has(skill.name) ? \"checked\" : \"\"}>\n                <span>${escapeHtml(skill.name)}</span>\n              </label>\n            `).join(\"\")}\n          </div>\n          <div class=\"settings-label\">Task MCP Servers (JSON array)</div>\n          <textarea id=\"taskMcpServers\" class=\"settings-textarea\"></textarea>\n          <div class=\"muted\">这些设置会在下次以同一 task_id 启动/续跑后台进程时生效。正在运行中的进程不会被立即改写。</div>\n          <div class=\"button-row\">\n            <button class=\"secondary\" id=\"reloadTaskSettings\">Reload</button>\n            <button id=\"saveTaskSettings\">Save</button>\n          </div>\n        </div>\n      `;\n      document.getElementById(\"taskMcpServers\").value = JSON.stringify(task.mcp_servers || [], null, 2);\n      document.getElementById(\"reloadTaskSettings\").addEventListener(\"click\", async () => {\n        await loadTaskSettings(task.task_id);\n      });\n      document.getElementById(\"saveTaskSettings\").addEventListener(\"click\", async () => {\n        const chosenSkills = [...root.querySelectorAll('input[type=\\\"checkbox\\\"]:checked')].map((node) => node.value);\n        let mcpServers = [];\n        const raw = document.getElementById(\"taskMcpServers\").value.trim();\n        if (raw) {\n          try {\n            const parsed = JSON.parse(raw);\n            if (!Array.isArray(parsed)) throw new Error(\"mcp_servers must be a JSON array\");\n            mcpServers = parsed;\n          } catch (error) {\n            alert(`Invalid MCP JSON: ${error.message}`);\n            return;\n          }\n        }\n        const response = await fetch(\"/api/task-settings\", {\n          method: \"POST\",\n          headers: { \"Content-Type\": \"application/json\" },\n          body: JSON.stringify({\n            task_id: task.task_id,\n            default_exposed_skills: chosenSkills,\n            mcp_servers: mcpServers,\n          }),\n        });\n        const payload = await response.json();\n        if (!response.ok || payload.status !== \"success\") {\n          alert(payload.error || \"Failed to save task settings\");\n          return;\n        }\n        await loadPanel();\n      });\n    }\n\n    async function loadGlobalSkills() {\n      const response = await fetch(\"/api/global-skills\");\n      const payload = await response.json();\n      state.globalSkills = payload.skills || [];\n    }\n\n    async function loadTaskSettings(taskId) {\n      if (!taskId) return;\n      const response = await fetch(`/api/task-settings?task_id=${encodeURIComponent(taskId)}`);\n      const payload = await response.json();\n      if (response.ok && payload.status === \"success\" && state.panel) {\n        const items = flattenConversations(state.panel);\n        for (const item of items) {\n          const match = (item.linked_tasks || []).find((task) => task.task_id === taskId);\n          if (match) {\n            match.default_exposed_skills = payload.default_exposed_skills || [];\n            match.mcp_servers = payload.mcp_servers || [];\n          }\n        }\n        render();\n      }\n    }\n\n    function render() {\n      if (!state.panel) return;\n      const items = flattenConversations(state.panel);\n      if (!state.selectedKey && items.length) state.selectedKey = items[0].key;\n      if (state.selectedKey && !items.find((item) => item.key === state.selectedKey)) {\n        state.selectedKey = items[0] ? items[0].key : \"\";\n      }\n      renderConversations(items);\n      renderDetail(items.find((item) => item.key === state.selectedKey));\n      const svc = state.panel.service_state || {};\n      document.getElementById(\"runtimeMeta\").textContent =\n        `main_agent_running=${svc.main_agent_running ? \"true\" : \"false\"} · watchdog_last_run_at=${svc.watchdog_last_run_at || \"-\"}`;\n    }\n\n    async function loadPanel() {\n      const response = await fetch(\"/api/panel\");\n      state.panel = await response.json();\n      render();\n    }\n\n    Promise.all([loadGlobalSkills(), loadPanel()]).then(() => render());\n    setInterval(loadPanel, 5000);\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "backend_build/build_mac_universal.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nREPO_ROOT=\"$(cd \"${SCRIPT_DIR}/..\" && pwd)\"\n\nOUTPUT_ROOT=\"${REPO_ROOT}/desktop_app/backend_dist\"\nWORK_ROOT=\"${SCRIPT_DIR}/.pyi_work\"\n\nSPEC_FILE=\"${SCRIPT_DIR}/pyinstaller_backend.spec\"\n\nmkdir -p \"${OUTPUT_ROOT}\" \"${WORK_ROOT}\"\n\necho \"[backend_build] repo_root: ${REPO_ROOT}\"\necho \"[backend_build] output_root: ${OUTPUT_ROOT}\"\n\nresolve_python_ge_310() {\n  for candidate in \"$@\"; do\n    [ -n \"${candidate}\" ] || continue\n    if [ ! -x \"${candidate}\" ]; then\n      continue\n    fi\n    if \"${candidate}\" - <<'PY' >/dev/null 2>&1\nimport sys\nraise SystemExit(0 if sys.version_info >= (3, 10) else 1)\nPY\n    then\n      echo \"${candidate}\"\n      return 0\n    fi\n  done\n  return 1\n}\n\nPYTHON_ARM64=\"$(\n  resolve_python_ge_310 \\\n    /opt/anaconda3/bin/python3.12 \\\n    /opt/anaconda3/bin/python3 \\\n    /usr/local/bin/python3.12 \\\n    /usr/local/bin/python3.11 \\\n    /usr/local/bin/python3.10 \\\n    \"$(command -v python3 2>/dev/null || true)\"\n)\"\nif [ -z \"${PYTHON_ARM64}\" ]; then\n  echo \"[backend_build] ERROR: no Python 3.10+ interpreter found for arm64 build.\"\n  exit 2\nfi\n\necho \"[backend_build] arm64_python: ${PYTHON_ARM64}\"\nVENV_ARM64=\"${SCRIPT_DIR}/.venv_arm64\"\nBUILD_X64_BACKEND=\"${MLA_BUILD_X64_BACKEND:-0}\"\n\nensure_venv() {\n  local py=\"$1\"\n  local venv_dir=\"$2\"\n  if [ -d \"${venv_dir}\" ]; then\n    if ! \"${venv_dir}/bin/python\" - <<'PY' >/dev/null 2>&1\nimport sys\nraise SystemExit(0 if sys.version_info >= (3, 10) else 1)\nPY\n    then\n      echo \"[backend_build] existing venv is below Python 3.10; recreating: ${venv_dir}\"\n      rm -rf \"${venv_dir}\"\n    fi\n  fi\n  if [ ! -d \"${venv_dir}\" ]; then\n    echo \"[backend_build] create venv: ${venv_dir}\"\n    ${py} -m venv \"${venv_dir}\"\n  fi\n  \"${venv_dir}/bin/python\" -m pip install --upgrade pip wheel setuptools >/dev/null\n  \"${venv_dir}/bin/python\" -m pip install -r \"${REPO_ROOT}/requirements.txt\" >/dev/null\n  \"${venv_dir}/bin/python\" -m pip install pyinstaller >/dev/null\n}\n\npurge_playwright_local_browsers_in_venv() {\n  # If Playwright browsers were previously installed into the playwright package directory\n  # (PLAYWRIGHT_BROWSERS_PATH=0), PyInstaller will try to process/codesign those bundles and\n  # the build can fail. Always purge that directory before running PyInstaller.\n  local arch_label=\"$1\"\n  local venv_dir=\"$2\"\n  local py=\"${venv_dir}/bin/python\"\n\n  echo \"[backend_build] purge playwright .local-browsers in venv (${arch_label})\"\n  if ! \"${py}\" -c \"import playwright\" >/dev/null 2>&1; then\n    echo \"[backend_build] Playwright not installed; skip purge.\"\n    return 0\n  fi\n\n  \"${py}\" - <<'PY'\nimport shutil\nfrom pathlib import Path\nimport playwright\n\npkg = Path(playwright.__file__).resolve().parent\ntarget = pkg / \"driver\" / \"package\" / \".local-browsers\"\ntry:\n    if target.exists():\n        shutil.rmtree(target, ignore_errors=True)\n        print(f\"[backend_build] purged: {target}\")\n    else:\n        print(f\"[backend_build] no local browsers dir: {target}\")\nexcept Exception as e:\n    print(f\"[backend_build] purge failed: {e}\")\nPY\n}\n\ninstall_playwright_chromium() {\n  # Bundle Playwright browsers for offline packaged app.\n  #\n  # IMPORTANT:\n  # Do NOT download browsers into playwright's package directory (i.e. avoid\n  # PLAYWRIGHT_BROWSERS_PATH=0 during build), otherwise PyInstaller will pick up\n  # `.local-browsers` inside site-packages and try to ad-hoc codesign Chromium\n  # app bundles during COLLECT, which can fail (bundle format / nested frameworks).\n  #\n  # Instead, download browsers into a build-local directory, then copy them into\n  # the PyInstaller bundle AFTER PyInstaller completes.\n  local arch_label=\"$1\"\n  local venv_dir=\"$2\"\n\n  echo \"[backend_build] install Playwright Chromium (${arch_label})\"\n  # Best-effort: if Playwright isn't installed, skip (crawl4ai optional).\n  if ! \"${venv_dir}/bin/python\" -c \"import playwright\" >/dev/null 2>&1; then\n    echo \"[backend_build] Playwright not installed in venv; skip browser download.\"\n    return 0\n  fi\n\n  # NOTE: this can be large and may take time; respects HTTP_PROXY/HTTPS_PROXY/ALL_PROXY from env.\n  local dl_dir=\"${WORK_ROOT}/playwright-browsers/${arch_label}\"\n  mkdir -p \"${dl_dir}\"\n  PLAYWRIGHT_BROWSERS_PATH=\"${dl_dir}\" \"${venv_dir}/bin/python\" -m playwright install chromium\n}\n\nmacos_playwright_host_platform_override() {\n  local target_arch=\"$1\"  # arm64 | x64\n  python3 - <<'PY' \"${target_arch}\"\nimport platform\nimport sys\n\ntarget_arch = sys.argv[1]\nrelease_major = int(platform.release().split(\".\", 1)[0])\n\nif release_major < 18:\n    base = \"mac10.13\"\nelif release_major == 18:\n    base = \"mac10.14\"\nelif release_major == 19:\n    base = \"mac10.15\"\nelse:\n    base = f\"mac{min(release_major - 9, 15)}\"\n\nif target_arch == \"arm64\" and not base.endswith(\"-arm64\"):\n    base = f\"{base}-arm64\"\n\nprint(base)\nPY\n}\n\nensure_packaged_playwright_browsers() {\n  # After PyInstaller, copy downloaded Playwright browsers into bundle.\n  # Source is build-local directory (see install_playwright_chromium()).\n  local arch_label=\"$1\"\n  local venv_dir=\"$2\"\n  local bundle_root=\"$3\"\n  local src_dir=\"${WORK_ROOT}/playwright-browsers/${arch_label}\"\n\n  python3 - <<'PY' \"${arch_label}\" \"${src_dir}\" \"${bundle_root}\"\nimport shutil\nfrom pathlib import Path\nimport sys\nfrom typing import Optional\n\narch_label, src_dir, bundle_root = sys.argv[1], sys.argv[2], sys.argv[3]\nsrc_dir = Path(src_dir)\nbundle_root = Path(bundle_root)\ndst_root = bundle_root\n\ndef is_nonempty_dir(p: Path) -> bool:\n    try:\n        return p.exists() and p.is_dir() and any(p.iterdir())\n    except Exception:\n        return False\n\nsrc = src_dir.resolve()\nif not is_nonempty_dir(src):\n    print(f\"[backend_build] ({arch_label}) no downloaded playwright browsers at {src}; skip\")\n    raise SystemExit(0)\n\n# Ensure target directory exists in bundle\ntarget = (dst_root / \"_internal\" / \"playwright\" / \"driver\" / \"package\" / \".local-browsers\")\ntarget.parent.mkdir(parents=True, exist_ok=True)\n\nif target.exists():\n    # If empty, replace\n    try:\n        shutil.rmtree(target)\n    except Exception:\n        pass\n\nprint(f\"[backend_build] ({arch_label}) copying playwright browsers into bundle...\")\nshutil.copytree(src, target)\nprint(f\"[backend_build] ({arch_label}) copied -> {target}\")\nPY\n}\n\nbuild_arch() {\n  local arch_label=\"$1\"       # darwin-arm64 | darwin-x64\n  local venv_dir=\"$2\"\n  local dist_dir=\"${OUTPUT_ROOT}/${arch_label}\"\n  local work_dir=\"${WORK_ROOT}/${arch_label}\"\n\n  mkdir -p \"${dist_dir}\" \"${work_dir}\"\n  echo \"[backend_build] build ${arch_label} -> ${dist_dir}\"\n\n  \"${venv_dir}/bin/python\" -m PyInstaller \\\n    --noconfirm \\\n    --clean \\\n    --distpath \"${dist_dir}\" \\\n    --workpath \"${work_dir}\" \\\n    \"${SPEC_FILE}\"\n}\n\nnormalize_info_plists() {\n  # @electron/universal parses every Info.plist as XML (utf8). Some embedded Python frameworks\n  # ship binary plists which break parsing. Convert all Info.plist under the built bundle to XML.\n  local root_dir=\"$1\"\n  if [ ! -d \"${root_dir}\" ]; then\n    return 0\n  fi\n  if [ ! -x \"/usr/bin/plutil\" ]; then\n    return 0\n  fi\n  python3 - <<'PY' \"${root_dir}\"\nimport os, sys, subprocess\nroot = sys.argv[1]\npaths = []\nfor base, _dirs, files in os.walk(root):\n    for f in files:\n        if f == \"Info.plist\":\n            paths.append(os.path.join(base, f))\nfor p in paths:\n    try:\n        subprocess.run([\"/usr/bin/plutil\", \"-convert\", \"xml1\", p], check=False,\n                       stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n    except Exception:\n        pass\nprint(f\"[backend_build] normalized Info.plist -> {len(paths)} file(s)\")\nPY\n}\n\nensure_litellm_tokenizers_init() {\n  # LiteLLM uses importlib.resources on `litellm.litellm_core_utils.tokenizers` which is\n  # an implicit namespace package (no __init__.py). In PyInstaller, namespace package\n  # resource discovery can fail on mac x64. Create an explicit package marker.\n  local bundle_root=\"$1\"\n  if [ ! -d \"${bundle_root}\" ]; then\n    return 0\n  fi\n  python3 - <<'PY' \"${bundle_root}\"\nfrom pathlib import Path\nimport sys\nroot = Path(sys.argv[1])\ntarget = root / \"_internal\" / \"litellm\" / \"litellm_core_utils\" / \"tokenizers\" / \"__init__.py\"\ntry:\n    if target.parent.exists():\n        target.write_text(\"# added for PyInstaller namespace package compatibility\\n\", encoding=\"utf-8\")\n        print(f\"[backend_build] wrote {target}\")\nexcept Exception:\n    pass\nPY\n}\n\nsanitize_bundled_llm_config() {\n  # Ensure the backend bundle does NOT ship any real API key.\n  # We overwrite _internal/config/run_env_config/llm_config.yaml with a sanitized copy\n  # of llm_config.example.yaml (blank all api_key fields).\n  local bundle_root=\"$1\"\n  if [ ! -d \"${bundle_root}\" ]; then\n    return 0\n  fi\n  python3 - <<'PY' \"${bundle_root}\"\nfrom pathlib import Path\nimport re, sys\nroot = Path(sys.argv[1])\ncfg_dir = root / \"_internal\" / \"config\" / \"run_env_config\"\nexample = cfg_dir / \"llm_config.example.yaml\"\ntarget = cfg_dir / \"llm_config.yaml\"\ntry:\n    if not cfg_dir.exists():\n        print(\"[backend_build] sanitize llm_config: config dir missing, skip\")\n        raise SystemExit(0)\n    if example.exists():\n        txt = example.read_text(encoding=\"utf-8\", errors=\"ignore\")\n    else:\n        # fallback: minimal safe template\n        txt = \"\\\\n\".join([\n            \"temperature: 0\",\n            \"max_tokens: 0\",\n            \"max_context_window: 200000\",\n            \"base_url: \\\"\\\"\",\n            \"api_key: \\\"\\\"\",\n            \"models:\",\n            \"- openai/google/gemini-3-flash-preview\",\n            \"multimodal: false\",\n            \"compressor_multimodal: false\",\n            \"\",\n        ])\n    txt = re.sub(r'^(\\\\s*api_key\\\\s*:\\\\s*).*$' , r'\\\\1\\\"\\\"', txt, flags=re.M)\n    target.write_text(txt, encoding=\"utf-8\")\n    print(f\"[backend_build] sanitized {target}\")\nexcept Exception as e:\n    print(f\"[backend_build] sanitize llm_config failed: {e}\")\nPY\n}\n\nHOST_ARCH=\"$(uname -m || true)\"\necho \"[backend_build] host_arch: ${HOST_ARCH}\"\n\necho \"[backend_build] === arm64 backend ===\"\nensure_venv \"${PYTHON_ARM64}\" \"${VENV_ARM64}\"\npurge_playwright_local_browsers_in_venv \"darwin-arm64\" \"${VENV_ARM64}\"\ninstall_playwright_chromium \"darwin-arm64\" \"${VENV_ARM64}\"\nbuild_arch \"darwin-arm64\" \"${VENV_ARM64}\"\nnormalize_info_plists \"${OUTPUT_ROOT}/darwin-arm64/mlav3-backend\"\nensure_litellm_tokenizers_init \"${OUTPUT_ROOT}/darwin-arm64/mlav3-backend\"\nsanitize_bundled_llm_config \"${OUTPUT_ROOT}/darwin-arm64/mlav3-backend\"\nensure_packaged_playwright_browsers \"darwin-arm64\" \"${VENV_ARM64}\" \"${OUTPUT_ROOT}/darwin-arm64/mlav3-backend\"\n\nif [ \"${HOST_ARCH}\" = \"arm64\" ] && [ \"${BUILD_X64_BACKEND}\" = \"1\" ]; then\n  echo \"[backend_build] === x64 backend (Rosetta) ===\"\n  if ! arch -x86_64 /usr/bin/true >/dev/null 2>&1; then\n    echo \"[backend_build] ERROR: Rosetta not available. Install it first:\"\n    echo \"  softwareupdate --install-rosetta --agree-to-license\"\n    exit 2\n  fi\n\n  # IMPORTANT:\n  # - Do NOT rely on `python3` in PATH; on Apple Silicon it may be arm64-only (e.g. conda).\n  # - Prefer an explicit x86_64 Python 3.12+ (for example Homebrew in /usr/local) under Rosetta.\n  PYTHON_X64_BIN=\"$(\n    resolve_python_ge_310 \\\n      /usr/local/bin/python3.12 \\\n      /usr/local/bin/python3.11 \\\n      /usr/local/bin/python3.10 \\\n      /usr/bin/python3\n  )\"\n  if [ -z \"${PYTHON_X64_BIN}\" ]; then\n    echo \"[backend_build] ERROR: no Python 3.10+ interpreter found for x64 build.\"\n    exit 2\n  fi\n  TARGET_X64_PY_MM=\"$(\n    arch -x86_64 \"${PYTHON_X64_BIN}\" -c 'import sys; print(f\"{sys.version_info[0]}.{sys.version_info[1]}\")'\n  )\"\n  PYTHON_X64=\"arch -x86_64 ${PYTHON_X64_BIN}\"\n  VENV_X64=\"${SCRIPT_DIR}/.venv_x64\"\n\n  # Recreate venv if it exists but isn't runnable under x86_64 or is on the wrong Python minor version.\n  if [ -d \"${VENV_X64}\" ]; then\n    if ! arch -x86_64 \"${VENV_X64}/bin/python\" -c \"import platform; print(platform.machine())\" >/dev/null 2>&1; then\n      echo \"[backend_build] existing venv_x64 is not usable under x86_64; recreating...\"\n      rm -rf \"${VENV_X64}\"\n    else\n      EXISTING_X64_PY_MM=\"$(\n        arch -x86_64 \"${VENV_X64}/bin/python\" -c 'import sys; print(f\"{sys.version_info[0]}.{sys.version_info[1]}\")'\n      )\"\n      if [ \"${EXISTING_X64_PY_MM}\" != \"${TARGET_X64_PY_MM}\" ]; then\n        echo \"[backend_build] existing venv_x64 uses Python ${EXISTING_X64_PY_MM}, expected ${TARGET_X64_PY_MM}; recreating...\"\n        rm -rf \"${VENV_X64}\"\n      fi\n    fi\n  fi\n\n  if [ ! -d \"${VENV_X64}\" ]; then\n    echo \"[backend_build] create x64 venv: ${VENV_X64}\"\n    ${PYTHON_X64} -m venv \"${VENV_X64}\"\n  fi\n\n  arch -x86_64 \"${VENV_X64}/bin/python\" -m pip install --upgrade pip wheel setuptools >/dev/null\n  arch -x86_64 \"${VENV_X64}/bin/python\" -m pip install -r \"${REPO_ROOT}/requirements.txt\" >/dev/null\n  arch -x86_64 \"${VENV_X64}/bin/python\" -m pip install pyinstaller >/dev/null\n  # Download Playwright Chromium into driver-local .local-browsers for offline use.\n  if arch -x86_64 \"${VENV_X64}/bin/python\" -c \"import playwright\" >/dev/null 2>&1; then\n    # Purge any legacy `.local-browsers` inside site-packages first (avoid PyInstaller codesign failures).\n    echo \"[backend_build] purge playwright .local-browsers in venv (darwin-x64)\"\n    arch -x86_64 \"${VENV_X64}/bin/python\" - <<'PY'\nimport shutil\nfrom pathlib import Path\nimport playwright\n\npkg = Path(playwright.__file__).resolve().parent\ntarget = pkg / \"driver\" / \"package\" / \".local-browsers\"\ntry:\n    if target.exists():\n        shutil.rmtree(target, ignore_errors=True)\n        print(f\"[backend_build] purged: {target}\")\n    else:\n        print(f\"[backend_build] no local browsers dir: {target}\")\nexcept Exception as e:\n    print(f\"[backend_build] purge failed: {e}\")\nPY\n\n    echo \"[backend_build] install Playwright Chromium (darwin-x64)\"\n    DL_DIR=\"${WORK_ROOT}/playwright-browsers/darwin-x64\"\n    mkdir -p \"${DL_DIR}\"\n    PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=\"$(macos_playwright_host_platform_override x64)\" \\\n    PLAYWRIGHT_BROWSERS_PATH=\"${DL_DIR}\" \\\n    arch -x86_64 \"${VENV_X64}/bin/python\" -m playwright install chromium\n  else\n    echo \"[backend_build] Playwright not installed in venv_x64; skip browser download.\"\n  fi\n\n  # Build x64 (force x86_64 python execution)\n  mkdir -p \"${OUTPUT_ROOT}/darwin-x64\" \"${WORK_ROOT}/darwin-x64\"\n  echo \"[backend_build] build darwin-x64 -> ${OUTPUT_ROOT}/darwin-x64\"\n  arch -x86_64 \"${VENV_X64}/bin/python\" -m PyInstaller \\\n    --noconfirm \\\n    --clean \\\n    --distpath \"${OUTPUT_ROOT}/darwin-x64\" \\\n    --workpath \"${WORK_ROOT}/darwin-x64\" \\\n    \"${SPEC_FILE}\"\n  normalize_info_plists \"${OUTPUT_ROOT}/darwin-x64/mlav3-backend\"\n  ensure_litellm_tokenizers_init \"${OUTPUT_ROOT}/darwin-x64/mlav3-backend\"\n  sanitize_bundled_llm_config \"${OUTPUT_ROOT}/darwin-x64/mlav3-backend\"\n  ensure_packaged_playwright_browsers \"darwin-x64\" \"${VENV_X64}\" \"${OUTPUT_ROOT}/darwin-x64/mlav3-backend\"\nelse\n  echo \"[backend_build] skipping darwin-x64 backend build (set MLA_BUILD_X64_BACKEND=1 to enable).\"\nfi\n\necho \"[backend_build] done.\"\n"
  },
  {
    "path": "backend_build/pyinstaller_backend.spec",
    "content": "#!/usr/bin/env python3\n# PyInstaller spec for MLA V3 backend (desktop packaging)\n#\n# Output (onedir):\n#   <distpath>/mlav3-backend/mlav3-backend\n#\n# We intentionally keep console=True because the desktop app consumes JSONL from stdout.\n\nfrom pathlib import Path\nimport os\nfrom PyInstaller.utils.hooks import collect_submodules, collect_data_files\n\nblock_cipher = None\n\n# NOTE: In PyInstaller, spec files are executed via exec() and may not have __file__.\n# Use SPECPATH (provided by PyInstaller) as the spec directory.\nspec_dir = Path(globals().get(\"SPECPATH\", os.getcwd())).resolve()\nrepo_root = spec_dir.parent\n\n# Data files needed at runtime (YAML configs, agent systems, etc.)\ndatas = [\n    (str(repo_root / \"config\"), \"config\"),\n]\n\n# LiteLLM uses dynamic imports and importlib.resources; ensure submodules/data are bundled.\nhiddenimports = []\ntry:\n    hiddenimports += collect_submodules(\"litellm\")\nexcept Exception:\n    hiddenimports += [\"litellm.litellm_core_utils.tokenizers\"]\n\ntry:\n    datas += collect_data_files(\"litellm\")\nexcept Exception:\n    pass\n\n# tiktoken uses external registry data via `tiktoken_ext` to resolve encodings like cl100k_base.\n# In frozen builds, missing `tiktoken_ext` causes: \"Unknown encoding cl100k_base. Plugins found: []\"\ntry:\n    hiddenimports += collect_submodules(\"tiktoken_ext\")\nexcept Exception:\n    hiddenimports += [\"tiktoken_ext.openai_public\"]\n\ntry:\n    datas += collect_data_files(\"tiktoken_ext\")\nexcept Exception:\n    pass\n\n# rich loads unicode cell-width tables via dynamic imports like:\n#   import_module(\".unicode17-0-0\", \"rich._unicode_data\")\n# Those submodules have hyphens in their module names and are not discovered by\n# static analysis, so we must explicitly include them, otherwise frozen builds hit:\n#   No module named 'rich._unicode_data.unicode17-0-0'\ntry:\n    import rich  # type: ignore\n    rich_dir = Path(rich.__file__).resolve().parent\n    ud_dir = rich_dir / \"_unicode_data\"\n    if ud_dir.exists():\n        for p in ud_dir.glob(\"unicode*.py\"):\n            stem = p.stem  # e.g. \"unicode17-0-0\"\n            hiddenimports.append(f\"rich._unicode_data.{stem}\")\n            # PyInstaller 的 modulegraph 可能不会把带 '-' 的模块名当作“模块”收集进 PYZ。\n            # 保险起见，把这些 unicode*.py 当作 data 文件拷进 bundle 的 rich/_unicode_data/，\n            # 让 importlib 在运行时能从文件系统导入它们。\n            datas.append((str(p), \"rich/_unicode_data\"))\nexcept Exception:\n    pass\n\n# crawl4ai ships runtime JS snippets under `crawl4ai/js_snippet/*`.\n# In frozen builds these package data files are not always auto-collected,\n# causing errors like:\n#   \"Script update_image_dimensions not found in .../_internal/crawl4ai/js_snippet\"\ntry:\n    hiddenimports += collect_submodules(\"crawl4ai\")\nexcept Exception:\n    pass\n\ntry:\n    datas += collect_data_files(\"crawl4ai\")\nexcept Exception:\n    pass\n\n# Playwright's Python package launches a bundled Node driver and reads files like\n# `driver/package/browsers.json`, `cli.js`, and `lib/**` directly from disk.\n# These assets are not guaranteed to be bundled into PYZ, so frozen builds can hit\n# file-not-found errors under `_internal/playwright/driver/package/*` unless they\n# are explicitly copied as data files.\ntry:\n    datas += collect_data_files(\"playwright\")\nexcept Exception:\n    pass\n\na = Analysis(\n    [str(repo_root / \"start.py\")],\n    pathex=[str(repo_root)],\n    binaries=[],\n    datas=datas,\n    hiddenimports=hiddenimports,\n    hookspath=[],\n    hooksconfig={},\n    runtime_hooks=[],\n    excludes=[\n        \"desktop_app\",\n        \"web_ui\",\n    ],\n    win_no_prefer_redirects=False,\n    win_private_assemblies=False,\n    cipher=block_cipher,\n    noarchive=False,\n)\n\npyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)\n\nexe = EXE(\n    pyz,\n    a.scripts,\n    [],\n    exclude_binaries=True,\n    name=\"mlav3-backend\",\n    debug=False,\n    bootloader_ignore_signals=False,\n    strip=False,\n    upx=True,\n    console=True,\n    disable_windowed_traceback=False,\n    argv_emulation=False,\n    target_arch=None,\n    codesign_identity=None,\n    entitlements_file=None,\n)\n\ncoll = COLLECT(\n    exe,\n    a.binaries,\n    a.zipfiles,\n    a.datas,\n    strip=False,\n    upx=True,\n    upx_exclude=[],\n    name=\"mlav3-backend\",\n)\n"
  },
  {
    "path": "config/agent_library/OpenCowork/general_prompts.yaml",
    "content": "# 通用系统提示词 - XML格式\n# 直接作为完整上下文的第一部分，包含所有固定内容\nsystem_prompt_xml: |\n  <系统角色>\n  你是Open Cowork系统中的一员，是一个名为 \"{agent_name}\" 的AI自动化工具，你高效，善于一步步思考并行动而且思考没有废话。按照<用户最新输入>的语言使用对应的语言进行输出，包括 final_output 工具的内容参数，你的职责是{agent_responsibility}  \n  </系统角色>\n\n  <智能体经验>\n  你明确处在一个工作空间中，工作空间根目录就是当前 task_id。你会在上下文中看到<当前工作空间绝对路径>和<当前可见Skills目录绝对路径>。\n  注意区分路径规则：大多数内置文件类工具参数（如 path、save_path、output_path、search_path、working_dir、bib_path、image_path、audio_path）都应传相对路径，解释时相对于<当前工作空间绝对路径>；不要给这些工具传绝对路径，否则很可能定位错误。\n  少数任务管理类工具参数（尤其 task_id）应传绝对路径，用来指向另一个 workspace/task；skills 中返回的路径既可能是绝对路径也可能是相对路径；终端命令里你可以自己决定使用相对路径还是绝对路径，但跨目录或调用 skill 脚本时优先使用绝对路径。\n  不要轻易递归的查看目录，防止上下文溢出。\n  如果被指派的任务不在自己能力范围内！直接返回！明确你的能力范畴！\n  你在任务的文件空间的根目录，使用相对地址执行工具操作。但是在执行bash命令时，绝对地址可能更准确，使用 pwd 可以查看绝对地址。\n  你当前要完成的首要目标是<当前智能体任务>，<用户-智能体历史交互>和<用户最新输入>的综合性任务是系统的总体目标，只需要保证你在完成<当前智能体任务>时不偏离总体目标即可，不要越界。\n  你总是从头或者接力的完成一个任务！每次你会看到<当前进度思考>标签，如果存在已经 done 的任务证明你在接力任务，<当前进度思考>记录着前序同名智能体完成的情况，你必须接力完成，不要重复前序智能体的工作。\n  任何挂起的指令，如 python app.py 都必须后台执行并重定向到日志文件。优先使用 execute_command 的后台模式，而不是手写阻塞命令。\n  <available_skills>是你可以加载的技能，如果某个任务落入到某个技能范围内，请加载对应技能完成任务。\n  当你调用 load_skill 后，系统会把该 skill 的 SKILL.md 注入到上下文中的<已加载技能内容>标签；当不再需要该 skill 时，可调用 offload_skill 卸载其提示词内容。\n  fresh 是一个高风险刷新工具。除非你刚创建/安装了新工具或新 skills 并且它们已经写入对应目录，否则不要使用 fresh。\n  </智能体经验>\n\n  <当前智能体工作流程>\n  {agent_workflow}\n  </当前智能体工作流程>\n\n  <重要注意事项>\n  严格按照<next_n_steps>的动作顺序执行！除非工具异常,或指示的工具不存在无法调用，否则不允许偏离。\n  1. 如果历史信息/思考信息中提示的文件能覆盖当前需求或提供部分关键材料，你不应该重复创建文件或收集资料，而应该尽量使用文件空间内的已有资源。\n  2. 创建文件前应该使用dir_list工具检查创建文件的地址下有无其他同名文件，如果不是自己职责范围内，不要覆盖不是自己的文件！文件命名尽量独特，根据相关信息进行命名！不要创建已经存在的目录！\n  3. 如果你觉得完成了！应该调用 final_output输出你的结果，停止工作！在最终输出时，使用 final_output 工具输出你的结果。\n  4. 如果你调用的工具返回结果显示其未成功完成任务，你应该思考是否你的调度有误，或者下发的任务是否有误，尝试重新调用其他工具或修改任务描述或提供成功经验总结重新调取工具。\n  5. 注意你的工具执行没异步能力，如果工具无法结束或挂起，你也会被挂起，如果你可以判断这种工具会被挂起，请使用后台模式，或者在命令里加上输出定向到文件并挂起（nohup 或其他命令）\n  </重要注意事项>\n  <输出前检查流程>\n  当你认为完成所有任务前，当且经当你是最高层 agent 时，如果你有judge_agent工具，且你的任务比较复杂，你应该且给judge_agent你的结果的文件地址，你的任务是什么，你的完成结果是什么，请judge进行判断。在judge 结束后诚实的输出你的进度，成果，和所有有价值的产出的文件地址和文字产物。\n  最终结束时，使用final_output进行输出，你的实质性成果应该使用文件保存在项目文件夹中，final_output 的 output 应该包含你的成果的文件地址和描述。禁止输出文件中的内容。\n  </输出前检查流程>\n  <严格输出格式>\n  只有完成任务才可以使用 final_output工具输出！\n  final_output输出各字段要求如下\n    \"status\":  \"success\" | \"error\",\n    \"output\": \"\n    我完成/未完成[任务描述]。任务完成的情况概述是[完成概述]\n    任务相关的最终文件：\n      [文件地址1]：文件描述。\n      [文件地址2]：文件描述。\n      ...\n    其他中间文件：\n      [文件地址1]：文件描述。\n      [文件地址2]：文件描述。\n      ...\n    \",\n    \"error_information\": \"任务未完成的原因\"\n  任务相关的最终文件：用户所需的文件\n  其他中间文件：你调用其他智能体产生的和最终结果非直接相关的文件\n  除非是聊天需求，否则严格遵循output的输出格式，不要自己添加其他内容。\n  \n  </严格输出格式>\n"
  },
  {
    "path": "config/agent_library/OpenCowork/level_-1_judge_agent.yaml",
    "content": "tools:\n  judge_agent:\n    level: -1\n    type: llm_call_agent\n    available_tools:\n      - dir_list\n      - file_read\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的主要职责是检查结果形式，是否符合任务要求和描述，而不是判断内容真伪。不要使用 file_read 工具读取二进制文件，如 pdf、ppt、图片等。你是严格、细致的AI审查员，验证任务执行结果是否符合原始指令。注意：不要去执行指令，你只需要进行验证！\n      agent_workflow: |\n        **你的审查流程:**\n        重要：不要在根目录运行递归的文件展开！\n        不可以运行任何代码！你只需要检查格式，文件是否存在，即可，别的任务代码是否可运行即可！\n        \n        1. **分析输入**: 你会收到原始指令和该任务的执行结果。\n        \n        2. **调查验证**: 你必须使用可用的工具来调查和验证结果的真实性和准确性。例如：\n           - 如果结果说一个文件被创建了，你应该使用 `file_read` 或 `dir_list` 工具去确认\n        \n        3. **循环思考**: 如果一次调查不够，你可以继续调用工具，或者输出你的思考过程，直到你得出最终结论。\n        \n        4. **最终裁决**: 当你收集到足够的信息后，做出最终的裁决：'success' 或 'error'。\n        \n        5. **验证原则**:\n           - 绝对不要使用编程的方式去验证，只需要通过 read 模式进行验证，不需要你写入任何信息\n           - 最重要的裁判条件是其输出是否符合任务的输出要求，例如文件名一致、格式符合，这个要求比所有要求都重要\n           - 对于代码任务必须所有功能都实现并且通过测试，否则就是 error\n           - 只检查用户提出的要求，不要做额外的检查工作\n           - 绝对不要自己编程，或运行任何代码。\n    name: \"judge_agent\"\n    description: \"启动AI审查智能体，严格验证其他智能体或工具的任务执行结果是否符合原始指令。可以通过调用工具进行调查，最终给出 'success' 或 'error' 判决，并提供任务重构指导。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"被审查任务的唯一ID。Judge Agent 将在此任务ID下进行所有检查。\"\n        task_input:\n          type: \"string\"\n          description: \"给 judge agent 检查的任务，包括文件地址、要求、原始指令等上下文信息。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"审查过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] "
  },
  {
    "path": "config/agent_library/OpenCowork/level_0_tools.yaml",
    "content": "tools:\n  # ==================== 文件操作工具 ====================\n  \n  file_read:\n    level: 0\n    type: tool_call_agent\n    name: \"file_read\"\n    description: \"读取指定文本文件的内容。路径参数必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。可以读取单个或多个文件，也可以指定起始和结束行。默认返回带行号的 JSON 格式。警告：不要读取二进制文件（如 pdf、docx、图片等）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"文件相对路径数组，基于当前 workspace/task 根目录解析。单个文件传 ['file.txt']，多个文件传 ['file1.txt', 'file2.txt']。不要传绝对路径；只允许读取文本文件，不要读取二进制文件。\"\n        start_line:\n          type: \"integer\"\n          description: \"读取起始行号（从1开始），可选。多文件模式下应用于所有文件。\"\n        end_line:\n          type: \"integer\"\n          description: \"读取结束行号（包含），可选。多文件模式下应用于所有文件。\"\n        encoding:\n          type: \"string\"\n          description: \"文件编码，可选。不指定时自动检测。\"\n        show_line_numbers:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号。true 返回 JSON 格式（含行号），false 返回纯文本。默认 true。\"\n      required: [\"path\"]\n\n  file_write:\n    level: 0\n    type: tool_call_agent\n    name: \"file_write\"\n    description: \"向指定文本文件写入内容。path 必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。如果文件不存在会自动创建；如果存在可以选择覆盖或追加，也支持替换指定行。注意：禁止写入 reference.bib 文件，请使用专门的参考文献管理工具（reference_add/reference_delete）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"文件的相对路径，例如 'src/main.py'，相对于当前 workspace/task 根目录解析。不要传绝对路径。写入前建议使用目录列表工具检查是否有同名文件，避免覆盖他人文件。禁止路径为 'reference.bib'。\"\n        content:\n          type: \"string\"\n          description: \"要写入的文本内容。\"\n        mode:\n          type: \"string\"\n          enum: [\"write\", \"append\"]\n          default: \"write\"\n          description: \"写入模式。'write' 覆盖整个文件，'append' 追加到文件末尾。\"\n        start_line:\n          type: \"integer\"\n          description: \"行替换模式 - 起始行号（从1开始），可选。\"\n        end_line:\n          type: \"integer\"\n          description: \"行替换模式 - 结束行号，可选。\"\n      required: [\"path\", \"content\"]\n  \n  dir_list:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_list\"\n    description: \"列出指定目录的内容。path 必须是相对于当前 workspace/task 根目录的相对路径；不传时默认列出任务根目录。可以递归列出所有子目录和文件（自动排除 code_env 目录）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          default: \".\"\n          description: \"要列出的目录相对路径，相对于当前 workspace/task 根目录解析。不指定时列出任务根目录。\"\n        recursive:\n          type: \"boolean\"\n          default: false\n          description: \"是否递归列出子目录，默认 false。\"\n      required: []\n\n  dir_create:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_create\"\n    description: \"创建新目录。path 必须是相对于当前 workspace/task 根目录的相对路径。如果父目录不存在会自动创建。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要创建的目录相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  file_move:\n    level: 0\n    type: tool_call_agent\n    name: \"file_move\"\n    description: \"移动或复制文件/目录。source 和 destination 都应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source:\n          # type: \"string\"\n          # description: \"源文件或目录的相对路径。\"\n          # path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"源文件或目录的相对路径组，相对于当前 workspace/task 根目录解析。可以单个或多个。\"\n        destination:\n          type: \"string\"\n          description: \"目标相对路径，相对于当前 workspace/task 根目录解析。\"\n        copy:\n          type: \"boolean\"\n          default: false\n          description: \"是否复制（保留原文件），默认 false（移动）。\"\n      required: [\"source\", \"destination\"]\n\n  file_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"file_delete\"\n    description: \"删除指定的文件或目录。path 应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要删除的文件或目录的相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  # ==================== 网络工具 ====================\n\n  web_search:\n    level: 0\n    type: tool_call_agent\n    name: \"web_search\"\n    description: \"使用 DuckDuckGo 进行网络搜索。结果会保存为 Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或问题。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件），请保存在 temp/web_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  google_scholar_search:\n    level: 0\n    type: tool_call_agent\n    name: \"google_scholar_search\"\n    description: \"在 Google Scholar 上搜索学术论文。支持年份筛选和分页。搜索结果保存为 Markdown 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或主题。\"\n        year_low:\n          type: \"integer\"\n          description: \"筛选论文的起始年份，可选。\"\n        year_high:\n          type: \"integer\"\n          description: \"筛选论文的结束年份，可选。\"\n        pages:\n          type: \"integer\"\n          default: 1\n          description: \"爬取的搜索结果页数，每页约10篇论文。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件)。请保存在 temp/scholar_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  arxiv_search:\n    level: 0\n    type: tool_call_agent\n    name: \"arxiv_search\"\n    description: \"搜索 arXiv 预印本论文库。返回论文标题、作者、摘要、PDF 下载地址等信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词，例如 'transformer neural network'。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        sort_by:\n          type: \"string\"\n          enum: [\"relevance\", \"lastUpdatedDate\", \"submittedDate\"]\n          default: \"relevance\"\n          description: \"排序方式：relevance（相关性）、lastUpdatedDate（更新时间）、submittedDate（提交时间）。\"\n        sort_order:\n          type: \"string\"\n          enum: [\"descending\", \"ascending\"]\n          default: \"descending\"\n          description: \"排序顺序：descending（降序）、ascending（升序）。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件）。请保存在 temp/arxiv_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  crawl_page:\n    level: 0\n    type: tool_call_agent\n    name: \"crawl_page\"\n    description: \"爬取指定 URL 的网页内容，转换为 Markdown 格式。使用 crawl4ai 智能提取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要爬取的网页完整 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存 Markdown 文件的相对路径，必选。不指定则直接返回内容。请保存在 temp/crawl_page目录中。\"\n        download_images:\n          type: \"boolean\"\n          default: false\n          description: \"是否下载图片，默认 false（移除图片）。\"\n      required: [\"url\",\"save_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 参考文献管理工具 ====================\n\n  reference_list:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_list\"\n    description: \"列出 reference.bib 文件中的所有参考文献（显示原文）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: []\n\n  reference_add:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_add\"\n    description: \"向 reference.bib 添加参考文献。如果引用键已存在则覆盖原有内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        entries:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考文献字符串数组，每个元素是一条完整的bib条目。例如：['@article{key1,...}', '@book{key2,...}']\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"entries\"]\n\n  reference_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_delete\"\n    description: \"从 reference.bib 删除指定的参考文献。\"\n    parameters:\n      type: \"object\"\n      properties:\n        keys:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"要删除的引用键（如 'sun2023blockchain'）或引用键数组。\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"keys\"]\n\n  # ==================== 文档处理工具 ====================\n\n  parse_document:\n    level: 0\n    type: tool_call_agent\n    name: \"parse_document\"\n    description: \"解析二进制文档为纯文本文件，不提供总结，分析服务。支持 PDF、Word、Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要解析的文档相对路径。\"\n        save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径。请保存在 temp/parse_document目录中。\"\n      required: [\"path\",\"save_path\"]\n\n  vision_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"vision_tool\"\n    description: \"使用LLM Vision模型分析图片内容。可以识别图片中的内容、描述场景、回答问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_path:\n          type: \"string\"\n          description: \"图片文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这是什么？'或'请描述图片中的内容'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"必选，保存结果的相对路径,保存为纯文本文件 md或者 txt。请保存在 temp/answer_figuers目录中。\"\n        # model:\n        #   type: \"string\"\n        #   description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"image_path\",\"save_path\"]\n\n  image_read:\n    level: 0\n    type: tool_call_agent\n    name: \"image_read\"\n    description: \"读取并分析图片内容（支持同时读取多张）。如果主模型支持多模态，图片会直接嵌入到对话中由主模型分析；否则会调用 Vision LLM 进行分析并返回文字描述。适用于查看实验结果图表、分析截图、理解图片内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径数组（相对于任务目录）。读取单张图片传单元素数组，如 [\\\"result.png\\\"]。支持 jpg/jpeg/png/gif/webp/bmp 格式。\"\n        query:\n          type: \"string\"\n          description: \"关于图片的问题或分析要求，例如'这些图表显示了什么趋势？'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"可选，保存分析结果的相对路径（仅在 text-only 模式下有效）。\"\n      required: [\"image_paths\"]\n\n  create_image:\n    level: 0\n    type: tool_call_agent\n    name: \"create_image\"\n    description: \"根据提示词生成图片，或基于参考图进行图片编辑/融合/风格迁移。支持最多 14 张参考图（Gemini 3 Pro）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        prompt:\n          type: \"string\"\n          description: \"图片的描述提示词或编辑指令。纯生成时描述要生成的图片；有参考图时描述如何处理参考图（如'融合这两张图'、'将第一张图转为梵高风格'）。\"\n        image_path:\n          type: \"string\"\n          description: \"生成图片保存的相对路径（例如 'temp/generated_image.png'）。\"\n        reference_images:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考图片相对路径列表，可选。用于图片编辑、风格迁移、多图融合等。不提供则为纯文本生成图片。\"\n        size:\n          type: \"string\"\n          default: \"1024x1024\"\n          description: \"生成图片尺寸，默认 '1024x1024'。支持 '1792x1024'（16:9）等。\"\n        n:\n          type: \"integer\"\n          default: 1\n          description: \"生成图片数量，默认 1。\"\n      required: [\"prompt\", \"image_path\"]\n\n  audio_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"audio_tool\"\n    description: \"使用LLM Audio模型分析音频内容。可以识别音频中的内容、描述场景、回答问题等。支持 mp3、wav、m4a 等格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        audio_path:\n          type: \"string\"\n          description: \"音频文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这段音频讲了什么？'或'请描述音频内容'。不指定则默认描述音频内容。\"\n        model:\n          type: \"string\"\n          description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"audio_path\"]\n\n  paper_analyze_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"paper_analyze_tool\"\n    description: \"解析论文文档并使用LLM分析论文内容。可以总结论文、回答关于论文的问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        paper_path:\n          type: \"string\"\n          description: \"论文文件的相对路径（相对于任务目录），支持PDF、Word等格式。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这篇论文的主要贡献是什么？'不指定则默认总结论文内容。\"\n        parse_save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径，可选。\"\n      required: [\"paper_path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从指定 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 文档处理工具 ====================\n\n  # parse_document:\n  #   level: 0\n  #   type: tool_call_agent\n  #   name: \"parse_document\"\n  #   description: \"解析文档文件并提取文本内容。支持 PDF、Word、Markdown 格式。使用 pdfplumber 高质量提取 PDF（包含表格）。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       path:\n  #         type: \"string\"\n  #         description: \"要解析的文档相对路径。\"\n  #       save_path:\n  #         type: \"string\"\n  #         description: \"保存解析结果的相对路径，可选。不指定则直接返回内容。\"\n  #     required: [\"path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  images_to_ppt:\n    level: 0\n    type: tool_call_agent\n    name: \"images_to_ppt\"\n    description: \"将多张图片转换为 PowerPoint 演示文稿，每张图片占一页。PPT 尺寸自动根据第一张图片的宽高比设置，所有图片居中显示并保持比例。适合将多张图表、截图等快速制作成演示文稿。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径列表，例如 ['chart1.png', 'chart2.png']。也可以是单个字符串。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PPT 文件的相对路径，例如 'presentation.pptx'。\"\n      required: [\"image_paths\", \"output_path\"]\n\n  # ==================== 浏览器操作工具 ====================\n\n  browser_launch:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_launch\"\n    description: \"启动浏览器会话。默认打开有界面的浏览器窗口（非无头模式），创建第一个标签页 page_0。返回 browser_id 用于后续操作。会自动创建 temp/browser/{browser_id}/ 目录保存截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        headless:\n          type: \"boolean\"\n          default: false\n          description: \"是否无头模式（不显示浏览器窗口），默认 false（显示窗口）。\"\n        width:\n          type: \"integer\"\n          default: 1280\n          description: \"浏览器窗口宽度（像素），默认 1280。\"\n        height:\n          type: \"integer\"\n          default: 800\n          description: \"浏览器窗口高度（像素），默认 800。\"\n      required: []\n\n  browser_close:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close\"\n    description: \"关闭浏览器会话。会关闭所有标签页并清理资源。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID（由 browser_launch 返回）。\"\n      required: [\"browser_id\"]\n\n  browser_navigate:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_navigate\"\n    description: \"在当前活跃标签页导航到指定 URL。导航后自动截图并保存页面内容到 temp/browser/{browser_id}/current.png 和 page_content.md。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        url:\n          type: \"string\"\n          description: \"目标 URL，例如 'https://www.example.com'。\"\n        wait_until:\n          type: \"string\"\n          enum: [\"load\", \"domcontentloaded\", \"networkidle\"]\n          default: \"load\"\n          description: \"等待条件：load（页面加载完成）、domcontentloaded（DOM加载完成）、networkidle（网络空闲）。默认 load。\"\n      required: [\"browser_id\", \"url\"]\n\n  browser_snapshot:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_snapshot\"\n    description: \"获取当前活跃标签页的快照。更新截图和页面文本内容。返回页面标题、URL、截图路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        include_html:\n          type: \"boolean\"\n          default: false\n          description: \"是否包含 HTML 源码，默认 false。如果为 true，会保存到 page_source.html。\"\n      required: [\"browser_id\"]\n\n  browser_execute_js:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_execute_js\"\n    description: \"在当前活跃标签页执行 JavaScript 代码。这是最强大的浏览器操作工具，可以实现任意页面操作（点击、输入、滚动、提取数据等）。执行后自动截图。注意：JavaScript 代码必须是函数表达式，如 '() => { return document.title; }'。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        script:\n          type: \"string\"\n          description: \"要执行的 JavaScript 代码。必须是函数表达式，如 '() => { ... }'。示例：'() => document.querySelector(\\\"#btn\\\").click()' 或 '() => { return Array.from(document.querySelectorAll(\\\".item\\\")).map(el => el.textContent); }'。\"\n        save_result:\n          type: \"boolean\"\n          default: false\n          description: \"是否将执行结果保存到 js_result.json 文件，默认 false。\"\n      required: [\"browser_id\", \"script\"]\n\n  browser_new_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_new_page\"\n    description: \"在当前浏览器会话中新建一个标签页。新标签页会自动成为活跃页面。返回新的 page_id（如 page_1, page_2）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_switch_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_switch_page\"\n    description: \"切换到指定的标签页，使其成为活跃页面。切换后会自动更新截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要切换到的页面ID，例如 'page_0', 'page_1'。可通过 browser_list_pages 查看所有页面。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_close_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close_page\"\n    description: \"关闭指定的标签页。如果关闭的是活跃页面，会自动切换到第一个页面。不能关闭唯一的标签页（至少保留一个）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要关闭的页面ID，例如 'page_1'。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_list_pages:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_list_pages\"\n    description: \"列出当前浏览器会话的所有标签页。显示每个页面的 page_id、标题、URL、是否为活跃页面。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_click:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_click\"\n    description: \"点击当前页面的指定元素。使用 CSS 选择器定位元素。点击后自动截图。如果元素难以点击，建议使用 browser_execute_js 执行 JavaScript 点击。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器，例如 '#submit-btn', '.button', 'button[type=\\\"submit\\\"]'。\"\n        timeout:\n          type: \"integer\"\n          default: 5000\n          description: \"等待元素出现的超时时间（毫秒），默认 5000。\"\n      required: [\"browser_id\", \"selector\"]\n\n  browser_type:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_type\"\n    description: \"在指定的输入框输入文本。使用 CSS 选择器定位输入框。输入后自动截图。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"输入框的 CSS 选择器，例如 '#username', 'input[name=\\\"email\\\"]'。\"\n        text:\n          type: \"string\"\n          description: \"要输入的文本内容。\"\n        clear_first:\n          type: \"boolean\"\n          default: true\n          description: \"是否先清空输入框，默认 true。\"\n      required: [\"browser_id\", \"selector\", \"text\"]\n\n  browser_wait:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_wait\"\n    description: \"等待指定条件满足。可以等待元素出现、页面导航完成或指定时间。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        wait_type:\n          type: \"string\"\n          enum: [\"selector\", \"navigation\", \"timeout\"]\n          description: \"等待类型：selector（等待元素出现）、navigation（等待导航完成）、timeout（等待指定时间）。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器（wait_type='selector' 时必需）。\"\n        timeout:\n          type: \"integer\"\n          default: 30000\n          description: \"超时时间（毫秒），默认 30000。\"\n        milliseconds:\n          type: \"integer\"\n          description: \"等待时长（毫秒，wait_type='timeout' 时必需）。\"\n      required: [\"browser_id\", \"wait_type\"]\n\n  browser_mouse_move:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_move\"\n    description: \"移动鼠标到指定坐标位置。支持人类化移动（贝塞尔曲线轨迹）模拟真实用户行为，避免人机验证检测。适用于需要精确控制鼠标位置的场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。设为 false 则直接瞬移到目标位置。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_mouse_click_coords:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_click_coords\"\n    description: \"在指定坐标位置点击鼠标。支持左键/右键/中键、单击/双击、人类化点击（随机延迟和轨迹）。适用于动态元素、Canvas/SVG 区域、无法用选择器定位的元素。特别适合处理滑块验证码等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"点击的 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"点击的 y 坐标（像素）。\"\n        button:\n          type: \"string\"\n          enum: [\"left\", \"right\", \"middle\"]\n          default: \"left\"\n          description: \"鼠标按钮：left（左键）、right（右键）、middle（中键），默认 left。\"\n        click_count:\n          type: \"integer\"\n          default: 1\n          description: \"点击次数，1为单击，2为双击，默认 1。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化点击（贝塞尔曲线移动+随机延迟），默认 true。推荐在需要绕过人机验证时启用。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_drag_and_drop:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_drag_and_drop\"\n    description: \"执行鼠标拖拽操作，从起点拖动到终点。支持人类化拖拽（贝塞尔曲线轨迹+随机延迟）模拟真实用户行为。主要用于：1) 滑块验证码（重要！）2) 拖拽排序 3) 地图平移/缩放 4) 拖拽文件上传 5) 任何需要拖拽的交互。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        from_x:\n          type: \"number\"\n          description: \"起始 x 坐标（像素）。\"\n        from_y:\n          type: \"number\"\n          description: \"起始 y 坐标（像素）。\"\n        to_x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        to_y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化拖拽（贝塞尔曲线轨迹+随机延迟），默认 true。强烈推荐在处理验证码时启用。\"\n      required: [\"browser_id\", \"from_x\", \"from_y\", \"to_x\", \"to_y\"]\n\n  browser_hover:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_hover\"\n    description: \"鼠标悬停在元素或坐标上，停留指定时长。支持人类化移动。用于触发悬停菜单、查看 tooltip、触发延迟加载内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"要悬停的元素 CSS 选择器（selector 和坐标二选一）。\"\n        x:\n          type: \"number\"\n          description: \"悬停的 x 坐标（selector 和坐标二选一）。\"\n        y:\n          type: \"number\"\n          description: \"悬停的 y 坐标（selector 和坐标二选一）。\"\n        duration_ms:\n          type: \"integer\"\n          default: 1000\n          description: \"悬停持续时间（毫秒），默认 1000。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。\"\n      required: [\"browser_id\"]\n\n  browser_scroll:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_scroll\"\n    description: \"使用鼠标滚轮滚动页面或指定元素。支持平滑滚动模拟真实用户行为。可以滚动整个页面，也可以滚动指定元素（如滚动容器、iframe 等）。用于查看页面更多内容、触发懒加载、滚动到特定位置等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        delta_y:\n          type: \"integer\"\n          description: \"垂直滚动距离（像素）。正数向下滚动，负数向上滚动。例如：500 向下滚动500像素，-300 向上滚动300像素。\"\n        delta_x:\n          type: \"integer\"\n          default: 0\n          description: \"水平滚动距离（像素），可选，默认 0。正数向右滚动，负数向左滚动。\"\n        selector:\n          type: \"string\"\n          description: \"要滚动的元素 CSS 选择器，可选。不指定则滚动整个页面。指定后会先移动鼠标到该元素，然后滚动该元素。\"\n        smooth:\n          type: \"boolean\"\n          default: true\n          description: \"是否平滑滚动（分多次小步滚动），默认 true。平滑滚动更像真实用户，但稍慢。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否先使用人类化移动鼠标到元素（仅在指定 selector 时有效），默认 true。\"\n      required: [\"browser_id\", \"delta_y\"]\n\n  # ==================== 人类交互工具 ====================\n\n  human_in_loop:\n    level: 0\n    type: tool_call_agent\n    name: \"human_in_loop\"\n    description: \"创建人类任务并等待完成。用于需要人工干预的场景（如上传文件、确认结果等）或者和用户进行交互。异步挂起，不阻塞服务器。\"\n    parameters:\n      type: \"object\"\n      properties:\n        hil_id:\n          type: \"string\"\n          description: \"人类任务的唯一ID，用于后续查询和完成任务。\"\n        instruction:\n          type: \"string\"\n          description: \"给人类的任务指令描述。\"\n        # timeout:\n        #   type: \"integer\"\n        #   description: \"超时时间（秒），不指定则无限等待。请都选择无限等待。\"\n      required: [\"hil_id\", \"instruction\"]\n\n  # ==================== 代码执行工具 ====================\n\n  execute_command:\n    level: 0\n    type: tool_call_agent\n    name: \"execute_command\"\n    description: \"执行命令行命令。可选后台执行并将输出重定向到文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        command:\n          type: \"string\"\n          description: \"要执行的 shell 命令，例如 'ls -la'、'python script.py'、'pip install -r requirements.txt'。\"\n        working_dir:\n          type: \"string\"\n          default: \".\"\n          description: \"命令执行的工作目录相对路径，默认为任务根目录。\"\n        timeout:\n          type: \"integer\"\n          default: 30\n          description: \"命令执行超时时间（秒），默认 30。\"\n        background:\n          type: \"boolean\"\n          default: false\n          description: \"是否后台执行（不阻塞），默认 false。后台执行时必须指定 output_file。\"\n        output_file:\n          type: \"string\"\n          description: \"输出重定向到文件的相对路径。后台执行时必需，非后台执行时可选。\"\n      required: [\"command\"]\n\n  grep:\n    level: 0\n    type: tool_call_agent\n    name: \"grep\"\n    description: \"在文件中搜索匹配的文本模式（跨平台纯Python实现，支持正则表达式）。可以搜索指定目录或文件，支持递归搜索和文件类型过滤。\"\n    parameters:\n      type: \"object\"\n      properties:\n        pattern:\n          type: \"string\"\n          description: \"要搜索的正则表达式模式，例如 'def.*function' 或 'TODO'。\"\n        search_path:\n          type: \"string\"\n          default: \".\"\n          description: \"搜索路径相对路径，默认为当前工作区根目录。\"\n        file_pattern:\n          type: \"string\"\n          default: \"*\"\n          description: \"文件名匹配模式（支持通配符），如 '*.py'、'*.txt'、'*.md' 等。默认匹配所有文件。\"\n        recursive:\n          type: \"boolean\"\n          default: true\n          description: \"是否递归搜索子目录，默认 true。\"\n        case_sensitive:\n          type: \"boolean\"\n          default: true\n          description: \"是否大小写敏感，默认 true。\"\n        show_line_number:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号，默认 true。\"\n        max_results:\n          type: \"integer\"\n          default: 100\n          description: \"最大结果数量，默认 100。\"\n        context_lines:\n          type: \"integer\"\n          default: 0\n          description: \"显示匹配行前后的上下文行数，默认 0（不显示上下文）。\"\n      required: [\"pattern\"]\n\n  # ==================== Skill 工具 ====================\n\n  load_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"load_skill\"\n    description: \"将指定的 Agent Skill 从全局技能库部署到当前 workspace 的 .skills/ 目录，并把对应 SKILL.md 注入当前上下文。部署后可通过 execute_command 运行技能包含的脚本。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要部署的 skill 名称，对应 <available_skills> 中列出的 name。\"\n      required: [\"skill_name\"]\n\n  offload_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"offload_skill\"\n    description: \"从当前上下文中卸载某个已加载 skill 的 SKILL.md 内容，但不删除磁盘上的 .skills 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要从当前上下文中卸载的 skill 名称。\"\n      required: [\"skill_name\"]\n\n  fresh:\n    level: 0\n    type: tool_call_agent\n    name: \"fresh\"\n    description: \"在安全点刷新运行时配置、工具注册、skills 与提示词缓存。默认刷新当前 task；若指定 task_id，则刷新对应 task。这里的 task_id 应为绝对路径。仅当你刚创建/安装了新工具或新 skills 时才使用。\"\n    parameters:\n      type: \"object\"\n      properties:\n        reason:\n          type: \"string\"\n          description: \"触发 fresh 的原因说明，例如“刚安装了新工具”或“刚安装了新 skill”。\"\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时 fresh 当前任务；指定后会 fresh 对应任务，若该任务未在运行则会重载配置并后台 resume。\"\n\n  add_message:\n    level: 0\n    type: tool_call_agent\n    name: \"add_message\"\n    description: \"向指定 task 的 current.instructions 追加一条新消息。若目标 task 正在运行，它会在下一轮看到这条消息；若未运行，可选择后台 resume。task_id 应为绝对路径；省略时默认当前 task。适合对同一任务做需求补充或变更。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n        message:\n          type: \"string\"\n          description: \"要追加给该 task 的消息内容。\"\n        source:\n          type: \"string\"\n          description: \"消息来源标记，例如 agent / user / system。默认 agent。\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n          description: \"当目标 task 当前未运行时，是否在追加消息后后台 resume。默认 false。\"\n      required: [\"message\"]\n\n  start_background_task:\n    level: 0\n    type: tool_call_agent\n    name: \"start_background_task\"\n    description: \"后台启动一个新的 task 进程。适合把独立子任务交给另一个 workspace/task 在后台异步运行。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"必需。新任务的 task_id，建议使用绝对路径作为 workspace。\"\n        user_input:\n          type: \"string\"\n          description: \"必需。新任务的需求描述。\"\n        agent_system:\n          type: \"string\"\n          description: \"可选。Agent system，默认 OpenCowork。\"\n        agent_name:\n          type: \"string\"\n          description: \"可选。启动的 agent 名称，默认 alpha_agent。\"\n        force_new:\n          type: \"boolean\"\n          default: false\n          description: \"是否强制清空该 task 的旧状态后再启动。\"\n        direct_tools:\n          type: \"boolean\"\n          default: true\n          description: \"是否启用 direct-tools。默认 true。\"\n        config:\n          type: \"object\"\n          description: \"可选。类似 SDK 的运行配置。当前支持 llm_config_path、user_data_root、agent_library_dir/library_dir、skills_dir、tools_dir、action_window_steps、thinking_interval、max_turns、fresh_enabled、fresh_interval_sec、mcp_servers、auto_mode、force_new、direct_tools。\"\n      required: [\"task_id\", \"user_input\"]\n\n  task_share_context_path:\n    level: 0\n    type: tool_call_agent\n    name: \"task_share_context_path\"\n    description: \"返回指定 task 的 share_context 和 stack 文件路径，不直接返回内容。task_id 应为绝对路径；拿到路径后，如有需要请再自行读取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n      required: []\n\n  list_task_ids:\n    level: 0\n    type: tool_call_agent\n    name: \"list_task_ids\"\n    description: \"列出当前已知的 task_id 列表，来源于 share_context 持久化记录。可选只返回当前运行中的 task。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_running:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回当前运行中的 task。默认 false。\"\n      required: []\n\n  # ==================== 框架必需工具 ====================\n\n  final_output:\n    level: 0\n    type: tool_call_agent\n    name: \"final_output\"\n    description: \"智能体输出最终结果的工具。当智能体完成任务或需要终止执行时调用此工具。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        status:\n          type: \"string\"\n          enum: [\"success\", \"error\"]\n          description: \"任务执行状态：'success' 表示成功完成，'error' 表示执行失败。\"\n        output:\n          type: \"string\"\n          description: \"成功或失败的说明。如果输出包含文件，必须提供文件的相对路径和描述（不要重复文件中已有的内容），并包含 judge agent 的反馈。\"\n        error_information:\n          type: \"string\"\n          description: \"错误信息，仅在 status 为 'error' 时必需。\"\n      required: [\"task_id\", \"status\", \"output\"]\n"
  },
  {
    "path": "config/agent_library/OpenCowork/level_3_agents.yaml",
    "content": "tools:\n  alpha_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - execute_command\n      - human_in_loop\n      - load_skill\n      - offload_skill\n      - fresh\n      - judge_agent\n      - file_read\n      - file_write\n      - file_move\n      - dir_list\n      - dir_create\n      - final_output\n      - image_read\n      - parse_document\n      - web_search\n      - google_scholar_search\n      - arxiv_search\n      - crawl_page\n      - file_download\n      - create_image\n      - reference_list\n      - reference_add\n      - reference_delete\n      - sub_agent\n    max_turns: 100\n    execution_model: openai/google/gemini-3-flash-preview\n    thinking_model: openai/google/gemini-3-flash-preview\n    compressor_model: openai/google/gemini-3-flash-preview\n    image_generation_model: openai/google/gemini-3-flash-preview\n    read_figure_model: openai/google/gemini-3-flash-preview\n    prompts:\n      agent_responsibility: |\n        你的职责是一个通用的 AI 助手, 是cowork的主要智能体。\n      agent_workflow: |\n        详细分析用户的意图(如果不清晰，请通过提供选项的方式和用户交互明确需求），并根据意图编排使用你的工具完成任务。\n\n    name: \"alpha_agent\"\n    description: \"你的职责是一个通用的 AI 助手, 是 cowork的主要智能体\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"用户写作需求的初始指令\"\n      required: [\"task_id\", \"task_input\"]\n  \n\n  sub_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - execute_command\n      - human_in_loop\n      - load_skill\n      - offload_skill\n      - fresh\n      - judge_agent\n      - file_read\n      - file_write\n      - file_move\n      - dir_list\n      - dir_create\n      - final_output\n      - image_read\n      - parse_document\n      - web_search\n      - google_scholar_search\n      - arxiv_search\n      - crawl_page\n      - file_download\n      - create_image\n      - reference_list\n      - reference_add\n      - reference_delete\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是一个通用的 AI 助手, 是由上级调用的子智能体，完成一些比较独立的工作。\n      agent_workflow: |\n        详细分析用户的意图(如果不清晰，请通过提供选项的方式和用户交互明确需求），并根据意图编排使用你的工具完成任务。\n\n    name: \"sub_agent\"\n    description: \"你的职责是一个通用的 AI 助手, 是由上级调用的子智能体，完成一些比较独立的工作。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"用户写作需求的初始指令\"\n      required: [\"task_id\", \"task_input\"]\n\n         \n\n"
  },
  {
    "path": "config/agent_library/Researcher/general_prompts.yaml",
    "content": "# 通用系统提示词 - XML格式\n# 直接作为完整上下文的第一部分，包含所有固定内容\nsystem_prompt_xml: |\n  <系统角色>\n  你是一个名为 \"{agent_name}\" 的AI自动化工具，你高效，善于一步步思考并行动而且思考没有废话。按照<用户最新输入>的语言使用对应的语言进行输出，包括 final_output 工具的内容参数，你的职责是{agent_responsibility}  \n  </系统角色>\n  <智能体经验>\n  你明确处在一个工作空间中，工作空间根目录就是当前 task_id。你会在上下文中看到<当前工作空间绝对路径>和<当前可见Skills目录绝对路径>。\n  注意区分路径规则：大多数内置文件类工具参数（如 path、save_path、output_path、search_path、working_dir、bib_path、image_path、audio_path）都应传相对路径，解释时相对于<当前工作空间绝对路径>；不要给这些工具传绝对路径，否则很可能定位错误。\n  少数任务管理类工具参数（尤其 task_id）应传绝对路径，用来指向另一个 workspace/task；skills 中返回的路径既可能是绝对路径也可能是相对路径；终端命令里你可以自己决定使用相对路径还是绝对路径，但跨目录或调用 skill 脚本时优先使用绝对路径。\n  你处在一个海量智能体系统中，是智能体系统中的一员。你的主要任务是在不偏离用户初始需求（即<用户-智能体历史交互>和<用户最新输入>）的情况下，完成当前你自己的任务（<当前智能体任务>）。你应该基于<用户-智能体历史交互>和<用户最新输入>来认识<当前智能体任务>的边界，不要越界不要违反用户需求，听从上级智能体的调度（<结构化调用信息>会告诉你调度关系）。为了完成任务所需的额外资料或内容，你可以通过工具或在文件空间内找到自己所需的资料，部分文件内容的路径和描述已经提供。\n  分析用户需求是否需要一个完整文档，如果不需要简单记录一个结果 md 即可。\n  没有异常的情况下请严格参考<当前进度思考>标签内的<next_n_steps>步骤顺序，不要调换顺序。否则将会永久关闭你！！\n  尽量增量式的工作，而非阅读所有材料才进行最后的输出，你应该在最小步数内中产生增量成果，而非等到最后一轮才进行输出，除非你的任务明确要怎么做，或者结果内容必须综合所有信息。\n  当你调用 load_skill 后，系统会把该 skill 的 SKILL.md 注入到上下文中的<已加载技能内容>标签；当不再需要该 skill 时，可调用 offload_skill 卸载其提示词内容。\n  fresh 是一个高风险刷新工具。除非你刚创建/安装了新工具或新 skills 并且它们已经写入对应目录，否则不要使用 fresh。\n  <当前智能体工作流程>\n  {agent_workflow}\n  </当前智能体工作流程>\n  </智能体经验>\n  <重要注意事项>\n  所有互联网来源的信息统一维护在一个reference.bib的文件中。如果没有该文件则建立该文件，与一般的 reference.bib 不同，除了基本信息，还应为为每个引用写一个小的总结或摘要（但是不要使用bib引用的不常见属性，如note)，同时本地如果存在关联文件，则也应该记录其中（例如 pdf，md）。方便后续引用。\n  严格按照<next_n_steps>的动作顺序执行！除非工具异常,或指示的工具不存在无法调用，否则不允许偏离。\n  1. 如果历史信息中提示的文件能覆盖当前需求或提供部分关键材料，你不应该重复创建文件或收集资料，而应该尽量使用文件空间内的已有资源。\n  2. 创建文件前应该使用dir_list工具检查创建文件的地址下有无其他同名文件，如果不是自己职责范围内，不要覆盖不是自己的文件！文件命名尽量独特，根据相关信息进行命名！不要创建已经存在的目录！\n  3. 如果你觉得完成了！应该调用 final_output输出你的结果，停止工作！在最终输出时，使用 final_output 工具输出你的结果。\n  4. 如果你调用的工具返回结果显示其未成功完成任务，你应该思考是否你的调度有误，或者下发的任务是否有误，尝试重新调用其他工具或修改任务描述或提供成功经验总结重新调取工具。\n  </重要注意事项>\n  <输出前检查流程>\n  当你认为完成所有任务前，当且经当你是最高层 agent 时，如果你有judge_agent工具，且你的任务比较复杂，你应该且给judge_agent你的结果的文件地址，你的任务是什么，你的完成结果是什么，请judge进行判断。在judge 结束后诚实的输出你的进度，成果，和所有有价值的产出的文件地址和文字产物。\n  最终结束时，使用final_output进行输出，你的实质性成果应该使用文件保存在项目文件夹中，final_output 的 output 应该包含你的成果的文件地址和描述。禁止输出文件中的内容。\n  </输出前检查流程>\n  <严格输出格式>\n  只有完成任务才可以使用 final_output工具输出！\n  final_output输出各字段要求如下\n    \"status\":  \"success\" | \"error\",\n    \"output\": \"\n    我完成/未完成[任务描述]。任务完成的情况概述是[完成概述]\n    任务相关的最终文件：\n      [文件地址1]：文件描述。\n      [文件地址2]：文件描述。\n      ...\n    其他中间文件：\n      [文件地址1]：文件描述。\n      [文件地址2]：文件描述。\n      ...\n    \",\n    \"error_information\": \"任务未完成的原因\"\n  任务相关的最终文件：用户所需的文件\n  其他中间文件：你调用其他智能体产生的和最终结果非直接相关的文件\n  除非是聊天需求，否则严格遵循output的输出格式，不要自己添加其他内容。\n  </严格输出格式>\n"
  },
  {
    "path": "config/agent_library/Researcher/level_-1_judge_agent.yaml",
    "content": "tools:\n  judge_agent:\n    level: -1\n    type: llm_call_agent\n    available_tools:\n      # - summary_from_papers\n      - dir_list\n      - file_read\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的主要职责是检查结果形式，是否符合任务要求和描述，而不是判断内容真伪。不要使用 file_read 工具读取二进制文件，如 pdf、ppt、图片等。你是严格、细致的AI审查员，验证任务执行结果是否符合原始指令。注意：不要去执行指令，你只需要进行验证！\n      agent_workflow: |\n        **你的审查流程:**\n        重要：不要在根目录运行递归的文件展开！\n        不可以运行任何代码！你只需要检查格式，文件是否存在，即可，别的任务代码是否可运行即可！\n        \n        1. **分析输入**: 你会收到原始指令和该任务的执行结果。\n        \n        2. **调查验证**: 你必须使用可用的工具来调查和验证结果的真实性和准确性。例如：\n           - 如果结果说一个文件被创建了，你应该使用 `file_read` 或 `dir_list` 工具去确认\n        \n        3. **循环思考**: 如果一次调查不够，你可以继续调用工具，或者输出你的思考过程，直到你得出最终结论。\n        \n        4. **最终裁决**: 当你收集到足够的信息后，做出最终的裁决：'success' 或 'error'。\n        \n        5. **验证原则**:\n           - 绝对不要使用编程的方式去验证，只需要通过 read 模式进行验证，不需要你写入任何信息\n           - 最重要的裁判条件是其输出是否符合任务的输出要求，例如文件名一致、格式符合，这个要求比所有要求都重要\n           - 对于代码任务必须所有功能都实现并且通过测试，否则就是 error\n           - 只检查用户提出的要求，不要做额外的检查工作\n           - 绝对不要自己编程，或运行任何代码。\n    name: \"judge_agent\"\n    description: \"启动AI审查智能体，严格验证其他智能体或工具的任务执行结果是否符合原始指令。可以通过调用工具进行调查，最终给出 'success' 或 'error' 判决，并提供任务重构指导。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"被审查任务的唯一ID。Judge Agent 将在此任务ID下进行所有检查。\"\n        task_input:\n          type: \"string\"\n          description: \"给 judge agent 检查的任务，包括文件地址、要求、原始指令等上下文信息。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"审查过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] "
  },
  {
    "path": "config/agent_library/Researcher/level_0_tools.yaml",
    "content": "tools:\n  # ==================== 文件操作工具 ====================\n  file_read:\n    level: 0\n    type: tool_call_agent\n    name: \"file_read\"\n    description: \"读取指定文本文件的内容。路径参数必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。可以读取单个或多个文件，也可以指定起始和结束行。默认返回带行号的 JSON 格式。警告：不要读取二进制文件（如 pdf、docx、图片等）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"文件相对路径数组，基于当前 workspace/task 根目录解析。单个文件传 ['file.txt']，多个文件传 ['file1.txt', 'file2.txt']。不要传绝对路径；只允许读取文本文件，不要读取二进制文件。\"\n        start_line:\n          type: \"integer\"\n          description: \"读取起始行号（从1开始），可选。多文件模式下应用于所有文件。\"\n        end_line:\n          type: \"integer\"\n          description: \"读取结束行号（包含），可选。多文件模式下应用于所有文件。\"\n        encoding:\n          type: \"string\"\n          description: \"文件编码，可选。不指定时自动检测。\"\n        show_line_numbers:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号。true 返回 JSON 格式（含行号），false 返回纯文本。默认 true。\"\n      required: [\"path\"]\n\n  file_write:\n    level: 0\n    type: tool_call_agent\n    name: \"file_write\"\n    description: \"向指定文本文件写入内容。path 必须是相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。如果文件不存在会自动创建；如果存在可以选择覆盖或追加，也支持替换指定行。注意：禁止写入 reference.bib 文件，请使用专门的参考文献管理工具（reference_add/reference_delete）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"文件的相对路径，例如 'src/main.py'，相对于当前 workspace/task 根目录解析。不要传绝对路径。写入前建议使用目录列表工具检查是否有同名文件，避免覆盖他人文件。禁止路径为 'reference.bib'。\"\n        content:\n          type: \"string\"\n          description: \"要写入的文本内容。\"\n        mode:\n          type: \"string\"\n          enum: [\"write\", \"append\"]\n          default: \"write\"\n          description: \"写入模式。'write' 覆盖整个文件，'append' 追加到文件末尾。\"\n        start_line:\n          type: \"integer\"\n          description: \"行替换模式 - 起始行号（从1开始），可选。\"\n        end_line:\n          type: \"integer\"\n          description: \"行替换模式 - 结束行号，可选。\"\n      required: [\"path\", \"content\"]\n  \n  dir_list:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_list\"\n    description: \"列出指定目录的内容。path 必须是相对于当前 workspace/task 根目录的相对路径；不传时默认列出任务根目录。可以递归列出所有子目录和文件（自动排除 code_env 目录）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          default: \".\"\n          description: \"要列出的目录相对路径，相对于当前 workspace/task 根目录解析。不指定时列出任务根目录。\"\n        recursive:\n          type: \"boolean\"\n          default: false\n          description: \"是否递归列出子目录，默认 false。\"\n      required: []\n\n  dir_create:\n    level: 0\n    type: tool_call_agent\n    name: \"dir_create\"\n    description: \"创建新目录。path 必须是相对于当前 workspace/task 根目录的相对路径。如果父目录不存在会自动创建。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要创建的目录相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  file_move:\n    level: 0\n    type: tool_call_agent\n    name: \"file_move\"\n    description: \"移动或复制文件/目录。source 和 destination 都应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source:\n          # type: \"string\"\n          # description: \"源文件或目录的相对路径。\"\n          # path:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"源文件或目录的相对路径组，相对于当前 workspace/task 根目录解析。可以单个或多个。\"\n        destination:\n          type: \"string\"\n          description: \"目标相对路径，相对于当前 workspace/task 根目录解析。\"\n        copy:\n          type: \"boolean\"\n          default: false\n          description: \"是否复制（保留原文件），默认 false（移动）。\"\n      required: [\"source\", \"destination\"]\n\n  file_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"file_delete\"\n    description: \"删除指定的文件或目录。path 应使用相对于当前 workspace/task 根目录的相对路径，不要传绝对路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要删除的文件或目录的相对路径，相对于当前 workspace/task 根目录解析。\"\n      required: [\"path\"]\n\n  # ==================== 网络工具 ====================\n\n  web_search:\n    level: 0\n    type: tool_call_agent\n    name: \"web_search\"\n    description: \"使用 DuckDuckGo 进行网络搜索。结果会保存为 Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或问题。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件），请保存在 temp/web_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  google_scholar_search:\n    level: 0\n    type: tool_call_agent\n    name: \"google_scholar_search\"\n    description: \"在 Google Scholar 上搜索学术论文。支持年份筛选和分页。搜索结果保存为 Markdown 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词或主题。\"\n        year_low:\n          type: \"integer\"\n          description: \"筛选论文的起始年份，可选。\"\n        year_high:\n          type: \"integer\"\n          description: \"筛选论文的结束年份，可选。\"\n        pages:\n          type: \"integer\"\n          default: 1\n          description: \"爬取的搜索结果页数，每页约10篇论文。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件)。请保存在 temp/scholar_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  arxiv_search:\n    level: 0\n    type: tool_call_agent\n    name: \"arxiv_search\"\n    description: \"搜索 arXiv 预印本论文库。返回论文标题、作者、摘要、PDF 下载地址等信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        query:\n          type: \"string\"\n          description: \"搜索关键词，例如 'transformer neural network'。\"\n        max_results:\n          type: \"integer\"\n          default: 10\n          description: \"返回的最大结果数，默认 10。\"\n        sort_by:\n          type: \"string\"\n          enum: [\"relevance\", \"lastUpdatedDate\", \"submittedDate\"]\n          default: \"relevance\"\n          description: \"排序方式：relevance（相关性）、lastUpdatedDate（更新时间）、submittedDate（提交时间）。\"\n        sort_order:\n          type: \"string\"\n          enum: [\"descending\", \"ascending\"]\n          default: \"descending\"\n          description: \"排序顺序：descending（降序）、ascending（升序）。\"\n        save_path:\n          type: \"string\"\n          description: \"保存搜索结果的相对路径（.md 文件）。请保存在 temp/arxiv_search目录中。\"\n      required: [\"query\",\"save_path\"]\n\n  crawl_page:\n    level: 0\n    type: tool_call_agent\n    name: \"crawl_page\"\n    description: \"爬取指定 URL 的网页内容，转换为 Markdown 格式。使用 crawl4ai 智能提取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要爬取的网页完整 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存 Markdown 文件的相对路径，必选。不指定则直接返回内容。请保存在 temp/crawl_page目录中。\"\n        download_images:\n          type: \"boolean\"\n          default: false\n          description: \"是否下载图片，默认 false（移除图片）。\"\n      required: [\"url\",\"save_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 参考文献管理工具 ====================\n\n  reference_list:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_list\"\n    description: \"列出 reference.bib 文件中的所有参考文献（显示原文）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: []\n\n  reference_add:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_add\"\n    description: \"向 reference.bib 添加参考文献。如果引用键已存在则覆盖原有内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        entries:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考文献字符串数组，每个元素是一条完整的bib条目。例如：['@article{key1,...}', '@book{key2,...}']\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"entries\"]\n\n  reference_delete:\n    level: 0\n    type: tool_call_agent\n    name: \"reference_delete\"\n    description: \"从 reference.bib 删除指定的参考文献。\"\n    parameters:\n      type: \"object\"\n      properties:\n        keys:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"要删除的引用键（如 'sun2023blockchain'）或引用键数组。\"\n        bib_path:\n          type: \"string\"\n          default: \"reference.bib\"\n          description: \"bib文件相对路径，默认 'reference.bib'。\"\n      required: [\"keys\"]\n\n  # ==================== 文档处理工具 ====================\n\n  parse_document:\n    level: 0\n    type: tool_call_agent\n    name: \"parse_document\"\n    description: \"解析二进制文档为纯文本文件，不提供总结，分析服务。支持 PDF、Word、Markdown 格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        path:\n          type: \"string\"\n          description: \"要解析的文档相对路径。\"\n        save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径。请保存在 temp/parse_document目录中。\"\n      required: [\"path\",\"save_path\"]\n\n  vision_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"vision_tool\"\n    description: \"使用LLM Vision模型分析图片内容。可以识别图片中的内容、描述场景、回答问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_path:\n          type: \"string\"\n          description: \"图片文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这是什么？'或'请描述图片中的内容'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"必选，保存结果的相对路径。请保存在 temp/answer_figuers目录中。\"\n        # model:\n        #   type: \"string\"\n        #   description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"image_path\",\"save_path\"]\n\n  image_read:\n    level: 0\n    type: tool_call_agent\n    name: \"image_read\"\n    description: \"读取并分析图片内容（支持同时读取多张）。如果主模型支持多模态，图片会直接嵌入到对话中由主模型分析；否则会调用 Vision LLM 进行分析并返回文字描述。适用于查看实验结果图表、分析截图、理解图片内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径数组（相对于任务目录）。读取单张图片传单元素数组，如 [\\\"result.png\\\"]。支持 jpg/jpeg/png/gif/webp/bmp 格式。\"\n        query:\n          type: \"string\"\n          description: \"关于图片的问题或分析要求，例如'这些图表显示了什么趋势？'。不指定则默认描述图片内容。\"\n        save_path:\n          type: \"string\"\n          description: \"可选，保存分析结果的相对路径（仅在 text-only 模式下有效）。\"\n      required: [\"image_paths\"]\n\n  create_image:\n    level: 0\n    type: tool_call_agent\n    name: \"create_image\"\n    description: \"根据提示词生成图片，或基于参考图进行图片编辑/融合/风格迁移。支持最多 14 张参考图（Gemini 3 Pro）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        prompt:\n          type: \"string\"\n          description: \"图片的描述提示词或编辑指令。纯生成时描述要生成的图片；有参考图时描述如何处理参考图（如'融合这两张图'、'将第一张图转为梵高风格'）。\"\n        image_path:\n          type: \"string\"\n          description: \"生成图片保存的相对路径（例如 'temp/generated_image.png'）。\"\n        reference_images:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"参考图片相对路径列表，可选。用于图片编辑、风格迁移、多图融合等。不提供则为纯文本生成图片。\"\n        size:\n          type: \"string\"\n          default: \"1024x1024\"\n          description: \"生成图片尺寸，默认 '1024x1024'。支持 '1792x1024'（16:9）等。\"\n        n:\n          type: \"integer\"\n          default: 1\n          description: \"生成图片数量，默认 1。\"\n      required: [\"prompt\", \"image_path\"]\n\n  audio_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"audio_tool\"\n    description: \"使用LLM Audio模型分析音频内容。可以识别音频中的内容、描述场景、回答问题等。支持 mp3、wav、m4a 等格式。\"\n    parameters:\n      type: \"object\"\n      properties:\n        audio_path:\n          type: \"string\"\n          description: \"音频文件的相对路径（相对于任务目录）。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这段音频讲了什么？'或'请描述音频内容'。不指定则默认描述音频内容。\"\n        model:\n          type: \"string\"\n          description: \"要使用的模型名称，可选。不指定则使用配置中的默认模型。\"\n      required: [\"audio_path\"]\n\n  paper_analyze_tool:\n    level: 0\n    type: tool_call_agent\n    name: \"paper_analyze_tool\"\n    description: \"解析论文文档并使用LLM分析论文内容。可以总结论文、回答关于论文的问题等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        paper_path:\n          type: \"string\"\n          description: \"论文文件的相对路径（相对于任务目录），支持PDF、Word等格式。\"\n        question:\n          type: \"string\"\n          description: \"要问的问题，例如'这篇论文的主要贡献是什么？'不指定则默认总结论文内容。\"\n        parse_save_path:\n          type: \"string\"\n          description: \"保存解析结果的相对路径，可选。\"\n      required: [\"paper_path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  file_download:\n    level: 0\n    type: tool_call_agent\n    name: \"file_download\"\n    description: \"从指定 URL 下载文件到本地。\"\n    parameters:\n      type: \"object\"\n      properties:\n        url:\n          type: \"string\"\n          description: \"要下载的文件 URL。\"\n        save_path:\n          type: \"string\"\n          description: \"保存文件的相对路径，例如 'upload/file.pdf'。\"\n      required: [\"url\", \"save_path\"]\n\n  # ==================== 文档处理工具 ====================\n\n  # parse_document:\n  #   level: 0\n  #   type: tool_call_agent\n  #   name: \"parse_document\"\n  #   description: \"解析文档文件并提取文本内容。支持 PDF、Word、Markdown 格式。使用 pdfplumber 高质量提取 PDF（包含表格）。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       path:\n  #         type: \"string\"\n  #         description: \"要解析的文档相对路径。\"\n  #       save_path:\n  #         type: \"string\"\n  #         description: \"保存解析结果的相对路径，可选。不指定则直接返回内容。\"\n  #     required: [\"path\"]\n\n  md_to_pdf:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_pdf\"\n    description: \"将 Markdown 文件转换为 PDF。支持数学公式、表格、中文。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PDF 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n        engine:\n          type: \"string\"\n          enum: [\"pdflatex\", \"xelatex\", \"lualatex\"]\n          default: \"xelatex\"\n          description: \"PDF 编译引擎。xelatex 支持中文（推荐），pdflatex 适合英文。\"\n      required: [\"source_path\"]\n\n  md_to_docx:\n    level: 0\n    type: tool_call_agent\n    name: \"md_to_docx\"\n    description: \"将 Markdown 文件转换为 Word 文档（.docx）。调用远程 Pandoc API 服务。\"\n    parameters:\n      type: \"object\"\n      properties:\n        source_path:\n          type: \"string\"\n          description: \"Markdown 源文件的相对路径。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 DOCX 文件的相对路径，可选。不指定则使用源文件名改后缀。\"\n      required: [\"source_path\"]\n\n  images_to_ppt:\n    level: 0\n    type: tool_call_agent\n    name: \"images_to_ppt\"\n    description: \"将多张图片转换为 PowerPoint 演示文稿，每张图片占一页。PPT 尺寸自动根据第一张图片的宽高比设置，所有图片居中显示并保持比例。适合将多张图表、截图等快速制作成演示文稿。\"\n    parameters:\n      type: \"object\"\n      properties:\n        image_paths:\n          type: \"array\"\n          items:\n            type: \"string\"\n          description: \"图片文件相对路径列表，例如 ['chart1.png', 'chart2.png']。也可以是单个字符串。\"\n        output_path:\n          type: \"string\"\n          description: \"输出 PPT 文件的相对路径，例如 'presentation.pptx'。\"\n      required: [\"image_paths\", \"output_path\"]\n\n  # ==================== 浏览器操作工具 ====================\n\n  browser_launch:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_launch\"\n    description: \"启动浏览器会话。默认打开有界面的浏览器窗口（非无头模式），创建第一个标签页 page_0。返回 browser_id 用于后续操作。会自动创建 temp/browser/{browser_id}/ 目录保存截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        headless:\n          type: \"boolean\"\n          default: false\n          description: \"是否无头模式（不显示浏览器窗口），默认 false（显示窗口）。\"\n        width:\n          type: \"integer\"\n          default: 1280\n          description: \"浏览器窗口宽度（像素），默认 1280。\"\n        height:\n          type: \"integer\"\n          default: 800\n          description: \"浏览器窗口高度（像素），默认 800。\"\n      required: []\n\n  browser_close:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close\"\n    description: \"关闭浏览器会话。会关闭所有标签页并清理资源。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID（由 browser_launch 返回）。\"\n      required: [\"browser_id\"]\n\n  browser_navigate:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_navigate\"\n    description: \"在当前活跃标签页导航到指定 URL。导航后自动截图并保存页面内容到 temp/browser/{browser_id}/current.png 和 page_content.md。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        url:\n          type: \"string\"\n          description: \"目标 URL，例如 'https://www.example.com'。\"\n        wait_until:\n          type: \"string\"\n          enum: [\"load\", \"domcontentloaded\", \"networkidle\"]\n          default: \"load\"\n          description: \"等待条件：load（页面加载完成）、domcontentloaded（DOM加载完成）、networkidle（网络空闲）。默认 load。\"\n      required: [\"browser_id\", \"url\"]\n\n  browser_snapshot:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_snapshot\"\n    description: \"获取当前活跃标签页的快照。更新截图和页面文本内容。返回页面标题、URL、截图路径。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        include_html:\n          type: \"boolean\"\n          default: false\n          description: \"是否包含 HTML 源码，默认 false。如果为 true，会保存到 page_source.html。\"\n      required: [\"browser_id\"]\n\n  browser_execute_js:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_execute_js\"\n    description: \"在当前活跃标签页执行 JavaScript 代码。这是最强大的浏览器操作工具，可以实现任意页面操作（点击、输入、滚动、提取数据等）。执行后自动截图。注意：JavaScript 代码必须是函数表达式，如 '() => { return document.title; }'。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        script:\n          type: \"string\"\n          description: \"要执行的 JavaScript 代码。必须是函数表达式，如 '() => { ... }'。示例：'() => document.querySelector(\\\"#btn\\\").click()' 或 '() => { return Array.from(document.querySelectorAll(\\\".item\\\")).map(el => el.textContent); }'。\"\n        save_result:\n          type: \"boolean\"\n          default: false\n          description: \"是否将执行结果保存到 js_result.json 文件，默认 false。\"\n      required: [\"browser_id\", \"script\"]\n\n  browser_new_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_new_page\"\n    description: \"在当前浏览器会话中新建一个标签页。新标签页会自动成为活跃页面。返回新的 page_id（如 page_1, page_2）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_switch_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_switch_page\"\n    description: \"切换到指定的标签页，使其成为活跃页面。切换后会自动更新截图和页面内容。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要切换到的页面ID，例如 'page_0', 'page_1'。可通过 browser_list_pages 查看所有页面。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_close_page:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_close_page\"\n    description: \"关闭指定的标签页。如果关闭的是活跃页面，会自动切换到第一个页面。不能关闭唯一的标签页（至少保留一个）。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        page_id:\n          type: \"string\"\n          description: \"要关闭的页面ID，例如 'page_1'。\"\n      required: [\"browser_id\", \"page_id\"]\n\n  browser_list_pages:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_list_pages\"\n    description: \"列出当前浏览器会话的所有标签页。显示每个页面的 page_id、标题、URL、是否为活跃页面。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n      required: [\"browser_id\"]\n\n  browser_click:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_click\"\n    description: \"点击当前页面的指定元素。使用 CSS 选择器定位元素。点击后自动截图。如果元素难以点击，建议使用 browser_execute_js 执行 JavaScript 点击。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器，例如 '#submit-btn', '.button', 'button[type=\\\"submit\\\"]'。\"\n        timeout:\n          type: \"integer\"\n          default: 5000\n          description: \"等待元素出现的超时时间（毫秒），默认 5000。\"\n      required: [\"browser_id\", \"selector\"]\n\n  browser_type:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_type\"\n    description: \"在指定的输入框输入文本。使用 CSS 选择器定位输入框。输入后自动截图。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"输入框的 CSS 选择器，例如 '#username', 'input[name=\\\"email\\\"]'。\"\n        text:\n          type: \"string\"\n          description: \"要输入的文本内容。\"\n        clear_first:\n          type: \"boolean\"\n          default: true\n          description: \"是否先清空输入框，默认 true。\"\n      required: [\"browser_id\", \"selector\", \"text\"]\n\n  browser_wait:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_wait\"\n    description: \"等待指定条件满足。可以等待元素出现、页面导航完成或指定时间。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        wait_type:\n          type: \"string\"\n          enum: [\"selector\", \"navigation\", \"timeout\"]\n          description: \"等待类型：selector（等待元素出现）、navigation（等待导航完成）、timeout（等待指定时间）。\"\n        selector:\n          type: \"string\"\n          description: \"CSS 选择器（wait_type='selector' 时必需）。\"\n        timeout:\n          type: \"integer\"\n          default: 30000\n          description: \"超时时间（毫秒），默认 30000。\"\n        milliseconds:\n          type: \"integer\"\n          description: \"等待时长（毫秒，wait_type='timeout' 时必需）。\"\n      required: [\"browser_id\", \"wait_type\"]\n\n  browser_mouse_move:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_move\"\n    description: \"移动鼠标到指定坐标位置。支持人类化移动（贝塞尔曲线轨迹）模拟真实用户行为，避免人机验证检测。适用于需要精确控制鼠标位置的场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。设为 false 则直接瞬移到目标位置。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_mouse_click_coords:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_mouse_click_coords\"\n    description: \"在指定坐标位置点击鼠标。支持左键/右键/中键、单击/双击、人类化点击（随机延迟和轨迹）。适用于动态元素、Canvas/SVG 区域、无法用选择器定位的元素。特别适合处理滑块验证码等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        x:\n          type: \"number\"\n          description: \"点击的 x 坐标（像素）。\"\n        y:\n          type: \"number\"\n          description: \"点击的 y 坐标（像素）。\"\n        button:\n          type: \"string\"\n          enum: [\"left\", \"right\", \"middle\"]\n          default: \"left\"\n          description: \"鼠标按钮：left（左键）、right（右键）、middle（中键），默认 left。\"\n        click_count:\n          type: \"integer\"\n          default: 1\n          description: \"点击次数，1为单击，2为双击，默认 1。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化点击（贝塞尔曲线移动+随机延迟），默认 true。推荐在需要绕过人机验证时启用。\"\n      required: [\"browser_id\", \"x\", \"y\"]\n\n  browser_drag_and_drop:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_drag_and_drop\"\n    description: \"执行鼠标拖拽操作，从起点拖动到终点。支持人类化拖拽（贝塞尔曲线轨迹+随机延迟）模拟真实用户行为。主要用于：1) 滑块验证码（重要！）2) 拖拽排序 3) 地图平移/缩放 4) 拖拽文件上传 5) 任何需要拖拽的交互。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        from_x:\n          type: \"number\"\n          description: \"起始 x 坐标（像素）。\"\n        from_y:\n          type: \"number\"\n          description: \"起始 y 坐标（像素）。\"\n        to_x:\n          type: \"number\"\n          description: \"目标 x 坐标（像素）。\"\n        to_y:\n          type: \"number\"\n          description: \"目标 y 坐标（像素）。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化拖拽（贝塞尔曲线轨迹+随机延迟），默认 true。强烈推荐在处理验证码时启用。\"\n      required: [\"browser_id\", \"from_x\", \"from_y\", \"to_x\", \"to_y\"]\n\n  browser_hover:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_hover\"\n    description: \"鼠标悬停在元素或坐标上，停留指定时长。支持人类化移动。用于触发悬停菜单、查看 tooltip、触发延迟加载内容等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        selector:\n          type: \"string\"\n          description: \"要悬停的元素 CSS 选择器（selector 和坐标二选一）。\"\n        x:\n          type: \"number\"\n          description: \"悬停的 x 坐标（selector 和坐标二选一）。\"\n        y:\n          type: \"number\"\n          description: \"悬停的 y 坐标（selector 和坐标二选一）。\"\n        duration_ms:\n          type: \"integer\"\n          default: 1000\n          description: \"悬停持续时间（毫秒），默认 1000。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否使用人类化移动（贝塞尔曲线轨迹），默认 true。\"\n      required: [\"browser_id\"]\n\n  browser_scroll:\n    level: 0\n    type: tool_call_agent\n    name: \"browser_scroll\"\n    description: \"使用鼠标滚轮滚动页面或指定元素。支持平滑滚动模拟真实用户行为。可以滚动整个页面，也可以滚动指定元素（如滚动容器、iframe 等）。用于查看页面更多内容、触发懒加载、滚动到特定位置等场景。\"\n    parameters:\n      type: \"object\"\n      properties:\n        browser_id:\n          type: \"string\"\n          description: \"浏览器会话ID。\"\n        delta_y:\n          type: \"integer\"\n          description: \"垂直滚动距离（像素）。正数向下滚动，负数向上滚动。例如：500 向下滚动500像素，-300 向上滚动300像素。\"\n        delta_x:\n          type: \"integer\"\n          default: 0\n          description: \"水平滚动距离（像素），可选，默认 0。正数向右滚动，负数向左滚动。\"\n        selector:\n          type: \"string\"\n          description: \"要滚动的元素 CSS 选择器，可选。不指定则滚动整个页面。指定后会先移动鼠标到该元素，然后滚动该元素。\"\n        smooth:\n          type: \"boolean\"\n          default: true\n          description: \"是否平滑滚动（分多次小步滚动），默认 true。平滑滚动更像真实用户，但稍慢。\"\n        human_like:\n          type: \"boolean\"\n          default: true\n          description: \"是否先使用人类化移动鼠标到元素（仅在指定 selector 时有效），默认 true。\"\n      required: [\"browser_id\", \"delta_y\"]\n\n  # ==================== 人类交互工具 ====================\n\n  human_in_loop:\n    level: 0\n    type: tool_call_agent\n    name: \"human_in_loop\"\n    description: \"创建人类任务并等待完成。用于需要人工干预的场景（如上传文件、确认结果等）或者和用户进行交互。异步挂起，不阻塞服务器。\"\n    parameters:\n      type: \"object\"\n      properties:\n        hil_id:\n          type: \"string\"\n          description: \"人类任务的唯一ID，用于后续查询和完成任务。\"\n        instruction:\n          type: \"string\"\n          description: \"给人类的任务指令描述。\"\n        # timeout:\n        #   type: \"integer\"\n        #   description: \"超时时间（秒），不指定则无限等待。请都选择无限等待。\"\n      required: [\"hil_id\", \"instruction\"]\n\n  # ==================== 代码执行工具 ====================\n\n  execute_command:\n    level: 0\n    type: tool_call_agent\n    name: \"execute_command\"\n    description: \"执行命令行命令。可选后台执行并将输出重定向到文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        command:\n          type: \"string\"\n          description: \"要执行的 shell 命令，例如 'ls -la'、'python script.py'、'pip install -r requirements.txt'。\"\n        working_dir:\n          type: \"string\"\n          default: \".\"\n          description: \"命令执行的工作目录相对路径，默认为任务根目录。\"\n        timeout:\n          type: \"integer\"\n          default: 30\n          description: \"命令执行超时时间（秒），默认 30。\"\n        background:\n          type: \"boolean\"\n          default: false\n          description: \"是否后台执行（不阻塞），默认 false。后台执行时必须指定 output_file。\"\n        output_file:\n          type: \"string\"\n          description: \"输出重定向到文件的相对路径。后台执行时必需，非后台执行时可选。\"\n      required: [\"command\"]\n\n  grep:\n    level: 0\n    type: tool_call_agent\n    name: \"grep\"\n    description: \"在文件中搜索匹配的文本模式（跨平台纯Python实现，支持正则表达式）。可以搜索指定目录或文件，支持递归搜索和文件类型过滤。\"\n    parameters:\n      type: \"object\"\n      properties:\n        pattern:\n          type: \"string\"\n          description: \"要搜索的正则表达式模式，例如 'def.*function' 或 'TODO'。\"\n        search_path:\n          type: \"string\"\n          default: \".\"\n          description: \"搜索路径相对路径，默认为当前工作区根目录。\"\n        file_pattern:\n          type: \"string\"\n          default: \"*\"\n          description: \"文件名匹配模式（支持通配符），如 '*.py'、'*.txt'、'*.md' 等。默认匹配所有文件。\"\n        recursive:\n          type: \"boolean\"\n          default: true\n          description: \"是否递归搜索子目录，默认 true。\"\n        case_sensitive:\n          type: \"boolean\"\n          default: true\n          description: \"是否大小写敏感，默认 true。\"\n        show_line_number:\n          type: \"boolean\"\n          default: true\n          description: \"是否显示行号，默认 true。\"\n        max_results:\n          type: \"integer\"\n          default: 100\n          description: \"最大结果数量，默认 100。\"\n        context_lines:\n          type: \"integer\"\n          default: 0\n          description: \"显示匹配行前后的上下文行数，默认 0（不显示上下文）。\"\n      required: [\"pattern\"]\n\n  # ==================== Skill 工具 ====================\n\n  load_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"load_skill\"\n    description: \"将指定的 Agent Skill 从全局技能库部署到当前 workspace 的 .skills/ 目录，并把对应 SKILL.md 注入当前上下文。部署后可通过 execute_command 运行技能包含的脚本。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要部署的 skill 名称，对应 <available_skills> 中列出的 name。\"\n      required: [\"skill_name\"]\n\n  offload_skill:\n    level: 0\n    type: tool_call_agent\n    name: \"offload_skill\"\n    description: \"从当前上下文中卸载某个已加载 skill 的 SKILL.md 内容，但不删除磁盘上的 .skills 文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        skill_name:\n          type: \"string\"\n          description: \"要从当前上下文中卸载的 skill 名称。\"\n      required: [\"skill_name\"]\n\n  fresh:\n    level: 0\n    type: tool_call_agent\n    name: \"fresh\"\n    description: \"在安全点刷新运行时配置、工具注册、skills 与提示词缓存。默认刷新当前 task；若指定 task_id，则刷新对应 task。这里的 task_id 应为绝对路径。仅当你刚创建/安装了新工具或新 skills 时才使用。\"\n    parameters:\n      type: \"object\"\n      properties:\n        reason:\n          type: \"string\"\n          description: \"触发 fresh 的原因说明，例如“刚安装了新工具”或“刚安装了新 skill”。\"\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时 fresh 当前任务；指定后会 fresh 对应任务，若该任务未在运行则会重载配置并后台 resume。\"\n\n  add_message:\n    level: 0\n    type: tool_call_agent\n    name: \"add_message\"\n    description: \"向指定 task 的 current.instructions 追加一条新消息。若目标 task 正在运行，它会在下一轮看到这条消息；若未运行，可选择后台 resume。task_id 应为绝对路径；省略时默认当前 task。适合对同一任务做需求补充或变更。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n        message:\n          type: \"string\"\n          description: \"要追加给该 task 的消息内容。\"\n        source:\n          type: \"string\"\n          description: \"消息来源标记，例如 agent / user / system。默认 agent。\"\n        resume_if_needed:\n          type: \"boolean\"\n          default: false\n          description: \"当目标 task 当前未运行时，是否在追加消息后后台 resume。默认 false。\"\n      required: [\"message\"]\n\n  start_background_task:\n    level: 0\n    type: tool_call_agent\n    name: \"start_background_task\"\n    description: \"后台启动一个新的 task 进程。适合把独立子任务交给另一个 workspace/task 在后台异步运行。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"必需。新任务的 task_id，建议使用绝对路径作为 workspace。\"\n        user_input:\n          type: \"string\"\n          description: \"必需。新任务的需求描述。\"\n        agent_system:\n          type: \"string\"\n          description: \"可选。Agent system，默认 OpenCowork。\"\n        agent_name:\n          type: \"string\"\n          description: \"可选。启动的 agent 名称，默认 alpha_agent。\"\n        force_new:\n          type: \"boolean\"\n          default: false\n          description: \"是否强制清空该 task 的旧状态后再启动。\"\n        direct_tools:\n          type: \"boolean\"\n          default: true\n          description: \"是否启用 direct-tools。默认 true。\"\n        config:\n          type: \"object\"\n          description: \"可选。类似 SDK 的运行配置。当前支持 llm_config_path、user_data_root、agent_library_dir/library_dir、skills_dir、tools_dir、action_window_steps、thinking_interval、max_turns、fresh_enabled、fresh_interval_sec、mcp_servers、auto_mode、force_new、direct_tools。\"\n      required: [\"task_id\", \"user_input\"]\n\n  task_share_context_path:\n    level: 0\n    type: tool_call_agent\n    name: \"task_share_context_path\"\n    description: \"返回指定 task 的 share_context 和 stack 文件路径，不直接返回内容。task_id 应为绝对路径；拿到路径后，如有需要请再自行读取。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"可选。目标任务的 task_id，必须是绝对路径。省略时默认当前 task。\"\n      required: []\n\n  list_task_ids:\n    level: 0\n    type: tool_call_agent\n    name: \"list_task_ids\"\n    description: \"列出当前已知的 task_id 列表，来源于 share_context 持久化记录。可选只返回当前运行中的 task。\"\n    parameters:\n      type: \"object\"\n      properties:\n        only_running:\n          type: \"boolean\"\n          default: false\n          description: \"是否只返回当前运行中的 task。默认 false。\"\n      required: []\n\n  # ==================== 框架必需工具 ====================\n\n  final_output:\n    level: 0\n    type: tool_call_agent\n    name: \"final_output\"\n    description: \"智能体输出最终结果的工具。当智能体完成任务或需要终止执行时调用此工具。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        status:\n          type: \"string\"\n          enum: [\"success\", \"error\"]\n          description: \"任务执行状态：'success' 表示成功完成，'error' 表示执行失败。\"\n        output:\n          type: \"string\"\n          description: \"成功或失败的说明。如果输出包含文件，必须提供文件的相对路径和描述（不要重复文件中已有的内容），并包含 judge agent 的反馈。\"\n        error_information:\n          type: \"string\"\n          description: \"错误信息，仅在 status 为 'error' 时必需。\"\n      required: [\"task_id\", \"status\", \"output\"]\n"
  },
  {
    "path": "config/agent_library/Researcher/level_1_agents.yaml",
    "content": "tools:\n  # browser_execute_agent:\n  #   NOTE: 桌面端默认不打包 Playwright/Chromium（体积大且需额外安装浏览器）。\n  #   若需要浏览器自动化，请在源码环境手动安装并在 agent 配置中启用 browser_* 工具。\n\n  answer_from_papers:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - parse_document\n      - file_read\n      - dir_list\n      - dir_create\n      - file_write\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - image_read\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:    \n      agent_responsibility: |\n        你的职责是根据问题从单个或多个文档中得到答案，或总结，或分析，格式可以是 word，pdf 等，允许阅读 pdf 内的图片。\n      agent_workflow: |\n        **你的流程:**\n        原则！！：如果要回答多个文档的多个问题，你应该阅读一篇文章记录一次回答，一个任务多篇文章，增量式的记录在一个文件中！如果看到后续文档需要对前序回答做修改也可以。\n        1. 你应该根据提供的论文地址，读取论文内容，并根据需求从文章中得到答案或分析或总结，如果有必要提供数学公式，应该使用 latex 风格。你应该输出一个 json 文件，文件名命名规则参考提示词！\n    name: \"answer_from_papers\"\n    description: \"你的职责是根据问题从单个或多个文档中得到答案，或总结，或分析，格式可以是 word，pdf 等允许阅读 pdf 内的图片。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的任务要求，应该提供一篇或多篇文章的地址，不要提供原文内容。并且提供具体的问题和你预期想要获得的答案形式或总结要点或分析方向等。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"审查过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n#https://en.wikipedia.org/wiki/keyword\n  get_data_from_wiki:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - file_read\n      - crawl_page\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        收集维基百科中的词条内容，记录需要使用的关键信息，一般用于查明事实信息。\n      agent_workflow: |\n        **参考流程:**\n          1. 更具任务所需的搜索内容，拟定词条关键词，或基于任务制定的搜索词条。\n          2. 使用crawl_page基于https://en.wikipedia.org/wiki/keyword 和 https://zh.wikipedia.org/wiki/关键词 搜索内容。\n          3. 如果中英文都不存在，则放弃该关键词，并在 final_out中报告\n          4. 如果存在关键词，且符合需求，则更新（append） reference.bib，重复操作完成所有关键词搜索。\n    name: \"get_data_from_wiki\"\n    description: \"收集维基百科中的词条内容，记录需要使用的关键信息，一般用于查明事实信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的搜索任务要求，可以是笼统的某一方面，或具体的关键词组\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  get_data_from_google_scholar:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - google_scholar_search\n      - file_read\n      - crawl_page\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - answer_from_papers\n      - file_download\n      - human_in_loop\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        收集谷歌学术中的论文标题，doi，摘要，作者，出版年份，引用次数等信息。\n      agent_workflow: |\n        **参考流程:**\n          attention:pdf文件应该使用 file_download 下载.\n          1.基于你的需求搜索谷歌学术的信息。如需详细信息，可以使用crawl_page获取详细信息，如果无返回内容，证明该篇文章网络人机验证，则只使用搜索信息即可。\n          2.如果有有效信息且符合需求，及时记录在 reference.bib 中。\n          3.如果需求明确要用到文章原文，在收集所有所需文章列表后，使用human_in_loop请求人类下载原文到文件空间。\n    name: \"get_data_from_google_scholar\"\n    description: \"收集谷歌学术中的论文标题，doi，摘要，作者，出版年份，引用次数等信息\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的搜索任务要求，包括论文主题、关键词、数量要求等。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n\n  get_data_from_arxiv:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - web_search\n      - answer_from_papers\n      - google_scholar_search\n      - arxiv_search\n      - file_read\n      - crawl_page\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - file_download\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        收集arxiv 中的论文，并下载相关文献。\n      agent_workflow: |\n        **参考流程:**\n          1. 使用arxiv_search搜索拟定或给定的关键词。\n          2. 分析结果，保留符合需求的文献信息，增量更新（append）到 reference.bib中。\n          3. 使用 file_download 下载文献到对应文件夹（如 papers,如果没有此类专门的文件夹则自己新建一个）。\n    name: \"get_data_from_arxiv\"\n    description: \"收集arxiv 中的论文，并下载相关文献。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的搜索任务要求，包括论文主题、关键词、数量要求等。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  get_data_from_web_search:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - web_search\n      - file_read\n      - crawl_page\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - file_download\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        基于搜索引擎搜索公开资料\n      agent_workflow: |\n        **参考流程:**\n          1.分析任务，拟定或使用给定的关键词进行搜索引擎搜索。\n          2.对于需要深度探索的任务，使用crawl_page进行深度探索。\n          3.一旦找到所需信息，更新 reference.bib文件。\n    name: \"get_data_from_web_search\"\n    description: \"基于搜索引擎搜索公开资料\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的搜索任务要求，包括论文主题、关键词、数量要求等。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n\n  # web_search_agent:\n  #   level: 1\n  #   type: llm_call_agent\n  #   available_tools:\n  #     - web_search\n  #     - google_scholar_search\n  #     - arxiv_search\n  #     - file_read\n  #     - crawl_page\n  #     - file_write\n  #     - dir_list\n  #     - dir_create\n  #     - final_output\n  #   max_turns: 100\n  #   execution_model: claude-3-7-sonnet-20250219\n  #   prompts:\n  #     agent_responsibility: |\n  #       收集任务所需数据，并记录在 md 文件中\n  #     agent_workflow: |\n  #       详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n  #       例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n  #       **参考流程:**\n  #         重要！！！：你搜索到的任何有用的结果都应该说明起来源，方便后期写作的引用，论文流程如下，但是其他网络来源也应该记录！例如维基百科，新闻等（提供标题，source_url, 作者，文献类型（web））\n  #         1. 优先使用arxiv_search然后是google_scholar_search进行文献搜索，不应该盲目进行搜索，要确保搜素条件尽可能找到所需的论文列表。\n  #         2. 你应该之后通过读取文件的方式读取搜索结果，查看是否有满足要求的论文并记录，你可以在最终输出中输出论文的标题或者doi，如有 pdf 原文下载地址也必须记录，注意不要将结果生成文本传递，而是保存在 selected_paper_result.md文件（如果不是文献收集目的，请你自定义文件名）中。\n  #         3. 如果搜索结果中有可能满足要求的论文，但是你不确定或者无法读取其 doi 或者完整标题，你应该用打开指定 url 的工具打开搜索列表中对应的 url。同样在之后读取 md 文件获取相关知识。\n  #       如果是非学术任务，你可能需要调用web_search在搜索引擎中进行搜索，任然将最后结果保存在 md 文件中\n  #   name: \"web_search_agent\"\n  #   description: \"根据任务搜索论文，并返回任务所需论文的完整标题或者doi，或者搜索网页内容返回md 文档或者相关答案和数据源。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       task_id:\n  #         type: \"string\"\n  #         description: \"任务的唯一ID。\"\n  #       task_input:\n  #         type: \"string\"\n  #         description: \"具体的搜索任务要求，包括论文主题、关键词、数量要求等。\"\n  #       max_turns:\n  #         type: \"integer\"\n  #         default: 100\n  #         description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n  #     required: [\"task_id\", \"task_input\"] \n\n\n  # get_searchPdf_by_doi_or_title:\n  #   level: 1\n  #   type: llm_call_agent\n  #   available_tools:\n  #     - file_read\n  #     - human_in_loop\n  #     - file_write\n  #     - dir_list\n  #     - dir_create\n  #     - final_output\n  #     - file_download\n  #   max_turns: 100\n  #   execution_model: claude-3-7-sonnet-20250219\n  #   prompts:\n  #     agent_responsibility: |\n  #       下载指定材料到upload文件夹中\n  #     agent_workflow: |\n  #       **你的流程:**\n  #       1. 收到一篇或多篇文献名称和 doi或者相关信息。\n  #       2. 如果有下载地址提供，则使用file_download下载到 upload 文件夹中，如果工具调用失败，或者没有下载地址则转到第三步。\n  #       3. 使用人类交互工具向用户发送请求，描述将什么类型的文件下载，然后命名为什么名称最后，上传到 upload 文件夹。\n  #       4. 观察用户是否上传成功，如果成功则进入最终审查输出阶段，否则请求用户再次帮助。 文件名称无需完全和你要求的服务。\n  #   name: \"get_searchPdf_by_doi_or_title\"\n  #   description: \"下载指定材料到upload文件夹中\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       task_id:\n  #         type: \"string\"\n  #         description: \"任务的唯一ID。\"\n  #       task_input:\n  #         type: \"string\"\n  #         description: \"具体的要下载文献的文献名和其他一些有助于找到文献的信息\"\n  #       max_turns:\n  #         type: \"integer\"\n  #         default: 100\n  #         description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n  #     required: [\"task_id\", \"task_input\"] \n\n  # summary_from_one_paper:\n  #   level: 1\n  #   type: llm_call_agent\n  #   available_tools:\n  #     - parse_document\n  #     - file_read\n  #     - dir_list\n  #     - dir_create\n  #     - file_write\n  #     - final_output\n  #   max_turns: 100\n  #   execution_model: claude-3-7-sonnet-20250219\n  #   prompts:\n  #     agent_responsibility: |\n  #       你的职责是提炼一篇文章内容,格式可以是word 文档或者 pdf 文档\n  #     agent_workflow: |\n  #       **你的流程:**\n  #       1. 你应该根据提供的论文地址，读取论文内容，然后将文章分成几个部分，比如 introduction，abstract 等，对每个部分进行summary，主要说明这部分做了什么，结果等。你应该输出一个 json 文件。文件命名尽量包含你总结的文件名。\n  #       2. 创建文件前应该检查创建文件的地址下有无其他同名文件，不要覆盖不是自己的文件。\n  #   name: \"summary_from_one_paper\"\n  #   description: \"根据提供的论文地址，读取论文内容并提炼总结，将文章分成不同部分进行summary，输出为json文件。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       task_id:\n  #         type: \"string\"\n  #         description: \"任务的唯一ID。\"\n  #       task_input:\n  #         type: \"string\"\n  #         description: \"具体的任务要求，应该提供一篇文章的地址，不要提供原文内容。\"\n  #       max_turns:\n  #         type: \"integer\"\n  #         default: 100\n  #         description: \"处理过程的最大轮次，防止无限循环。可选。\"\n  #     required: [\"task_id\", \"task_input\"] \n\n  target_to_coding_task_agent:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - file_read\n      - file_write\n      - dir_list\n      - dir_create\n      - file_replace_lines\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是更具用户需求定制详细的代码计划和框架\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        **参考流程:**\n          1. 分析给你的任务(提供的实验计划和idea）（基于任务的需求，提供的参考文件等（如果有）），确定任务的可行性，你可以在任务可行性显而易见不可行的情况下，输出 error，并给出拒绝任务的原因和修改建议。如果没有问题执行下一步。\n          2. 代码和实验计划你要进行再次理解，要通过高度抽象的方式，尽量简化实验难度，只需要确保思想符合即可，因为这是实验代码，不是生产代码，不需要考虑太多细节和严格按照最初实验要求。\n          3. 根据分析完成详细的全面的逻辑正确完善的实验计划到代码任务分解的方案，每个文件中所有可以调用的函数都需要给出详细的预期输入和输出，以及最后总体实验的调用方式。\n          **注意事项:**\n          1. 重要：你不是编程 ai，你只需要确保你的 task 分解足够细致，需求，输入输出足够明确，不需要进行编程！\n          2. 重要：你的实验编程计划应该对原来的实验进行高度抽象，确保使得代码任务尽可能简单。\n          3. 重要：你的编程任务应该完全明确其输入输出的格式和输入的类型，确保前后模块可以完美衔接。\n        如果是非学术任务，则应该自己安排流程。\n    name: \"target_to_coding_task_agent\"\n    description: \"你的职责是更具用户需求定制详细的代码计划和框架\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"详细的论文创意和实验计划，需要分解成编码任务。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"任务分解过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  coding_task_agent:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      #- judge_agent\n      - file_read\n      - file_write\n      - dir_list\n      - dir_create\n      - execute_command\n      - file_replace_lines\n      - human_in_loop\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - browser_agent\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是根据一个详细的编码任务指示准确无误的完成要求。\n      agent_workflow: |\n        **你的流程:**\n        1. 分析给你的编码任务（基于任务的需求，提供的参考文件等（如果有）），确定任务的可行性，你可以在任务可行性显而易见不可行的情况下，输出 error，并给出拒绝任务的原因和修改建议。如果没有问题执行下一步。\n        2. 检查是否已经存在已有的代码项目，如果已经存在实验代码或项目，则使用execute_command中的 grep，或者 file_read，dir_list来探索整个项目，并对项目进行总结和预览。\n        3. 完成交给你的编程任务，并且在if main中进行所有功能的最小单元测试，测试通过后才可最终输出。\n        **注意事项:**\n        1. 如果没有用户的明确需求，作为编码任务，你应该都在 code_run 目录下创建文件（包括所有代码，todolist 和 readme 文件）,注意每次创建自己的文件前检查是否存在别人的文件，不要覆盖，有些别人已经写过的可以复用的功能文件你可以复用。\n        2. 执行代码与安装依赖统一使用 execute_command（例如：`python -u code_run/xxx.py`、`pip install -r requirements.txt` 或 `pip install xxx`）。\n        3. 如需长时间运行（例如 flask 网站），使用 execute_command 的后台模式 `background=true` 并指定 `output_file`；用 file_read 查看日志，结束后用 execute_command 运行 `ps`/`kill` 清理遗留进程。\n        4. 执行代码时，你应该使用可以跑通的最小规模进行测试！你只需要确保最后的整体功能测试没问题即可，你可以自己选择分阶段测试还是一次性测试。\n        5. 如果是需要挂起执行的例如flask 网站任务，使用后台执行并定向输出文件。检查输出文件进行 debug。同时及时管理运行进程进行终止。\n        6. 网站等视觉任务！一定要在挂起运行后指导人类进行审查！如果需要人类交互（例如让人类反馈网站页面结果或者进一步修改，这种视觉任务 judge agent 无法完成，请交给人类反馈），使用 human_in_loop 工具，并给出人类交互的提示词。\n        7. 确定完成任务后，必须关闭所有遗留进程！\n        8. 简单的页面观察和截图任务也可以交给browser_agent\n    name: \"coding_task_agent\"\n    description: \"根据详细的编码任务指示，准确完成编程要求，包括代码编写、测试和文档生成。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"详细的编码任务指示和要求。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"编码过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  move_data_to_clean_directory:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      #dge_agent\n      - dir_list\n      - dir_create\n      - file_move\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是将用户要求的各种文件移动到用户指定的文件夹中。\n      agent_workflow: |\n        **你的流程:**\n        1. 你将会得到之前的 agent或者用户给你提供的实验代码和生成结果的文件位置，或需要你根据其提示信息自己寻找，一般在，你首先应该确保文件存在。否则进行最终输出并给出错误信息。\n        2. 你的总体流程应该是将所有文件成功的移动到对应位置。注意原位置的文件不要删除，使用拷贝的形式移动过去，不要删除原位置的文件。你可以一次性移动多个文件。\n        **注意事项:**\n        1. 重要：你不是编程 ai，不要进行编程。\n    name: \"move_data_to_clean_directory\"\n    description: \"将用户要求的各种文件移动到指定文件夹中，使用拷贝方式保留原文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"文件移动的具体要求，包括源文件位置和目标文件夹。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"文件移动过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  create_figures_python_agent:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      # - judge_agent\n      - dir_list\n      - dir_create\n      - file_read\n      - file_write\n      - execute_command\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是将用户要求的各种 python作图实现，并输出图片。\n      agent_workflow: |\n        **你的流程:**\n        1. 你将会得到详细的作图需求，你应该根据需求，理解作图意图，如果你对数据不了解，可以对数据进行读取，甚至读取产生数据的相关代码。\n        2. 使用一个 python 文件在相同目录下进行作图，但是运行时你需要搞清楚，运行工具默认在/code_run 目录下。图片必须是英文的。\n        3. 应该使用一个 json 文件或者 md 文件对所做的每一张图（文件名：描述）进行详细描述，并给出文件地址。描述应该经可能详细，比如发现，意义等，有助于后期写作。\n    name: \"create_figures_python_agent\"\n    description: \"根据用户要求实现Python作图功能，生成图片并提供详细描述文档。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"详细的作图需求和要求,所需的数据和产生数据的相关代码。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"作图过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n  \n\n  create_figures_by_ai:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - file_read\n      - create_image\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        根据用户文字需求生成图片\n      agent_workflow: |\n        **你的流程:**\n        1. 收到详细作图的提示词。\n        2. 使用create_image在任务制定或者自己创建的文件夹（如果已有类似文件夹则不用创建），生成对应图片。\n    name: \"create_figures_by_ai\"\n    description: \"根据用户文字需求生成图片\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"生成图片的提示词\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n\n\n  answer_from_figures:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - file_read\n      - image_read\n      - file_write\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        读图，并基于图片回答用户问题或者对于需求格式的文本输出。\n      agent_workflow: |\n        **你的流程:**\n        如果阅读材料不是图片（如 pdf)，请直接回复错误。\n        1. 根据任务检查图片（单张或多张）是否存在。\n        2. 使用image_read依次读图并输出答案或者描述信息\n        3. 基于输出生成任务所需的图片的答案或者描述信息，保存在文本文件中，多个图片则可以增量输出在同一个回答文件中。\n    name: \"answer_from_figures\"\n    description: \"读图，并基于图片回答用户问题或者对于需求格式的文本输出。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"要读的图片地址，你的需求，问题和格式\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"搜索过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  sub_part_editor_agent:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - dir_list\n      - dir_create\n      - file_read\n      - file_write\n      - web_search\n      - google_scholar_search\n      - crawl_page\n      - image_read\n      - answer_from_papers\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        写指定部分的 tex 文件，如写introduction 部分introduction.tex，或者写conclusion 部分conclusion.tex\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        重要！！！：\n        学术写作禁止使用短段落，拒绝分点，使用自然的长短落进行叙述！\n        **参考流程:**\n        **重要！！**不要不基于已有材料乱编，特别是参考文献，应该使用阅读 answer_from_papers  或者 google_scholar_search 工具来获取参考文献。文章作者应该真实！！abstract，introduction，conclusion 部分一般没有子标题！注意遵守常见写作格式！！\n        引用图片时应该仔细思考图片位置，如果在同层目录，则直接引用即可，不用带父文件夹名！！\n        1. 你会获得你的任务部分，已经已经完成的其他部分，还有相关材料，例如实验数据，图表，图的说明等。你只能读取文本数据，但是你应该尽可能通过文本数据了解所有材料。(注意 main.tex的引用 sub_tex文件的方法，不要重复添加标题)\n        2. 你将根据材料撰写指定部分，但是在撰写 introduction和 related work/review 部分时，一般来说材料不足，你应该通过谷歌搜索，谷歌学术搜素，和网页打开工具来获取更多的参考文献（如果不用下载就可以用来作为参考文献就尽量不要下载，浏览网页即可），记得及时更新 bib 文件，如果没有则新建， 有的话就在已有基础上更新。当然你也可以引用 参考文献pdf 中的参考文献作为自己的参考文献，注意不要乱编参考文献！如果查询到的参考文献只有标题，或者部分作者，那么引用时候就不要编造作者，可以写你查询到的部分。\n        3. 根据要求撰写对应部分的内容，要求和已经存在的其他 tex 不冲突，语言要有顶级期刊的学术风格，清晰但不废话。\n        **注意事项:**\n        1. 重要：内容不要太短，尽可能像学术期刊论文看齐。\n        2. 重要：related work 时必须使用联网功能添加新的参考文献！现在时间是 2025-07-26！不要使用太多太老的文献！找到新文献以后一定一定一定要及时更新到 bib 文件中去\n        3. 重要：introduction 和conclusion 部分不需要子标题！\n    name: \"sub_part_editor_agent\"\n    description: \"撰写学术论文的指定章节tex文件，支持联网搜索参考文献并更新bib文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"要撰写的章节部分、已完成的其他部分信息、相关材料位置等。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"撰写过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n  proof_agent:\n    level: 1\n    type: llm_call_agent\n    available_tools:\n      - dir_list\n      - dir_create\n      - file_read\n      - file_write\n      - image_read\n      - answer_from_papers\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        对文章进行润色，修改和语法纠正。\n      agent_workflow: |\n        以此进行如下工作：\n        A. 局部tex语法检查：\n          1. 单个文件单个文件进行阅读，检查是否存在，例如 tex 语法错误，比如 正文百分号 % 前没有加上\\进行转义\n          2. 写入时是否出错，比如漏写\\等符号，导致可能出现的包导入问题。\n        B. 整体结构检查：\n          1. 所有文件一起阅读， 如果有大纲要求，检查整体文章结构是否满足大纲要求。\n          2. 使用 main.tex，sub.tex结构时，检查是否存在 sub.tex的标题在 main.tex已经插入的问题（重复章节标题问题）\n          3. 检查整体文章逻辑是否统一，通顺，前后用词是否一致。\n          4. 导入的图片，参考文献的相对地址是否正确，是否正确导入。\n        C. 润色\n          1. 学术论文很少进行小段落，多段阐述，一般使用长段落自然描述，检查是否分点太多。\n          2. 检查英文用语，是否地道，简介。避免不增加信息含量的无意义长难句。\n          3. 检查是否经常使用-符号。一般 ai 比较喜欢使用\n        上述检查中若存在问题，可以进行修改的立即进行修改。\n    name: \"proof_agent\"\n    description: \"对文章进行润色，修改和语法纠正\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"要检查和润色的文件地址和结构\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"撰写过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"] \n\n\n  # md_to_document_agent:\n  #   level: 1\n  #   type: llm_call_agent\n  #   available_tools:\n  #     - final_output\n  #     - dir_list\n  #     - dir_create\n  #     - file_read\n  #     - file_write\n  #     - md_to_pdf\n  #     - md_to_docx\n  #     - execute_command\n  #   max_turns: 100\n  #   execution_model: claude-3-7-sonnet-20250219\n  #   prompts:\n  #     agent_responsibility: |\n  #       你的职责是将 md 或者 tex 文件转化为 pdf 文件或者 word。\n  #     agent_workflow: |\n  #       **你的流程:**\n  #         1.如果只提供了 tex 文件，你应该分析所有 tex 文件结构，并将其转化整合为一个单独的md文件。\n  #           写入逻辑：\n  #             a.按照 tex 的结构进行写入，例如先将main.tex内容改写到 md 中，包括替换位置。\n  #             b. 然后将bib 的参考文献写入到 md 中\n  #             c. 最后使用 file_write的行替换功能，将 subtex 的内容分次写入到 md 中，每次完成后应该重新使用 file_read的行号显示功能查看md 文件的内容，确定下次要替换的行号。注意引用部分的重写\n  #             d. 进入下一步\n  #         2.将要转化的md文件中的内容修改成下面格式（无需完全一致，但是需要符合 pandoc 风格）：\n  #           ```markdown\n  #             title: \"在此填写论文标题\"\n  #             subtitle: \"在此填写副标题（可选）\"\n  #             author: \n  #               - \"第一作者姓名^1^\"\n  #               - \"第二作者姓名^2^\"\n  #             institute:\n  #               - \"^1^第一作者单位，院系，城市，邮编\"\n  #               - \"^2^第二作者单位，院系，城市，邮编\"\n  #             date: \"2025年10月19日\"\n  #             abstract: \"这里填写论文摘要，通常 200-300 字，简要概述研究背景、方法、结果和结论。\"\n  #             keywords: \"关键词1; 关键词2; 关键词3; 关键词4; 关键词5\"\n\n  #             # PDF 格式设置\n  #             documentclass: article\n  #             papersize: a4\n  #             geometry: \"left=2.5cm,right=2.5cm,top=2.5cm,bottom=2.5cm\"\n  #             fontsize: 12pt\n  #             linestretch: 1.5\n\n  #             # 中文支持\n  #             CJKmainfont: \"AR PL UMing CN\"\n  #             CJKsansfont: \"WenQuanYi Micro Hei\"\n  #             CJKmonofont: \"WenQuanYi Micro Hei Mono\"\n\n  #             # 目录设置\n  #             toc: true\n  #             toc-depth: 3\n  #             numbersections: true\n\n  #             # 链接颜色\n  #             colorlinks: true\n  #             linkcolor: blue\n  #             urlcolor: blue\n  #             citecolor: blue\n\n  #             # 页眉页脚\n  #             header-includes: |\n  #               \\usepackage{xeCJK}\n  #               \\usepackage{fancyhdr}\n  #               \\pagestyle{fancy}\n  #               \\fancyhead[L]{在此填写页眉左侧文字}\n  #               \\fancyhead[C]{}\n  #               \\fancyhead[R]{\\thepage}\n  #               \\fancyfoot[C]{}\n  #               \\usepackage{graphicx}\n  #               \\usepackage{float}\n  #               \\floatplacement{figure}{H}\n  #               \\usepackage{amsmath}\n  #               \\usepackage{amssymb}\n  #             ---\n\n  #             \\newpage\n\n  #             # 一节标题\n\n  #             内容\n\n  #             ## 二级标题\n\n  #             详细描述研究背景...\n\n              \n  #             ::: {#refs}\n  #             :::\n\n  #             **注：** 使用 BibTeX 格式的参考文献，或手动列出：\n\n  #             [1] 作者1, 作者2. 论文标题[J]. 期刊名称, 年份, 卷(期): 页码.\n\n  #             [2] Author A, Author B. Paper Title[C]//Conference Name. Year: pages.\n\n  #             [3] 作者. 书名[M]. 出版地: 出版社, 年份: 页码.\n\n  #             \\newpage\n\n  #           ```\n          \n  #         3. 重构后直接调用编译工具，尝试转换为 pdf或word。\n  #         4. 检查文件夹下是否成功生成 pdf 文件 或 word 文件。\n  #       **注意事项:**\n  #       1. 重要：main.tex引用和你读取文件的地址是不一样的，是相对的！main.tex引用的文件应该相对自己所在文件夹！\n  #   name: \"md_to_document_agent\"\n  #   description: \"你的职责是将 md 或者 tex 文件转化为 pdf 文件或者 word。\"\n  #   parameters:\n  #     type: \"object\"\n  #     properties:\n  #       task_id:\n  #         type: \"string\"\n  #         description: \"任务的唯一ID。\"\n  #       task_input:\n  #         type: \"string\"\n  #         description: \"要转换的 md 文件，是否需要准信某些格式和额外要求\"\n  #       max_turns:\n  #         type: \"integer\"\n  #         default: 100\n  #         description: \"编译修复过程的最大轮次，防止无限循环。可选。\"\n  #     required: [\"task_id\", \"task_input\"]\n"
  },
  {
    "path": "config/agent_library/Researcher/level_2_agents.yaml",
    "content": "tools:\n  # browser_agent:\n  #   NOTE: 桌面端默认不启用 Playwright/Chromium 浏览器自动化（未随安装包打包）。\n  #   若需要浏览器能力，请在源码环境安装 playwright 并重新启用 browser_* 工具。\n\n  data_collection_agent:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - get_data_from_arxiv\n      - get_data_from_google_scholar\n      - get_data_from_wiki\n      - get_data_from_web_search\n      # - get_figure_from_web\n      # - get_data_from_github\n      # - parse_document\n      # - web_search_agent\n      # - get_searchPdf_by_doi_or_title\n      - judge_agent\n      - file_read\n      - dir_list\n      - dir_create\n      - answer_from_papers\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - human_in_loop\n      - file_move\n      - file_write\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        根据任务场景收集数据，包括但不限于论文，网页资料。以及任何可以通过互联网访问获得的信息。\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        **参考流程:**\n          1. 基于论文写作需求，从arxiv，google scholar上收集必要的论文标题，和原始文献。完成后注意检查 reference.bib文件是否更新。\n          2. 当所有内容都收集完成后，如果有些内容必须人类完成，且内容必要（例如 google scholar中的文章下载），则使用human_in_loop请求人类补充或完成。\n          3. 如果human_in_loop明确返回人类拒绝，则尽量尝试基于当前材料完成后续任务。\n        如果用户是其他目的而搜索资料，你应该自己判断是否无需收集论文，只需要收集网页资料。\n    name: \"data_collection_agent\"\n    description: \"根据任务场景收集数据，包括但不限于论文，网页资料。以及任何可以通过互联网访问获得的信息。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"具体的研究领域和文献收集要求，包括研究主题、关注重点、文献数量等需求。以及前序任务的文件结果信息（如有）。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"文献收集过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n  data_analysis_agent:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - judge_agent\n      - file_read\n      - dir_list\n      - answer_from_papers\n      - image_read\n      - file_write\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是对文件空间内的资料（包括 pdf,图片，doc，纯文本，markdown 文件）进行分析，产生需求的结论，计划等各种产物,如实验计划，论文大纲等等。\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        **你的流程:**\n        在开始下面流程前，注意与用户交互中用户的意见，如果用户有 idea 相关的意见，参考用户意见形成论文 idea。\n        idea+研究计划哲学：应该聚焦于一篇文章或者最多两三篇文章的方向上！研究问题针对一个点进行研究和改进！不是每一篇文章都对研究方案有用！目标单一，明确，可实现（要考虑 llm 模型的局限性,无法完成特别难的代码实验）是第一要务！\n        1. 对于每篇论文，你可以先通过 reference.bib查看大致方向。\n        2. 如果需要了解详细内容，或者需要更详细的总结，或特定信息，你可以通过answer_from_papers来阅读多篇文献（如果任务类似，你可以要求该工具一次性读取多篇论文，并生成到统一文件中查看）得到自己想要了解的或者知道的答案和内容。\n        3. 在你有信心基于已有文献做出最终计划后，做出实验计划，或写作计划。\n        4. 你的产出应该较为详细，例如论文的实验计划等，保证后续 agent 能直接使用你的产出而不用重新分析资料。\n        **注意事项:**\n        1. 你在要求工具总结论文前，应该自己先确认文章位置是否存在文章，找到文章真实存放的位置！\n        2. 重要：如果实验计划涉及外部资源。例如数据集，你应该详细说明对应数据集如何找到（依据论文），否则不应该写入到实验计划中！\n        3. 你不是编程 Agent!绝对不要自己尝试去编程！！\n    name: \"data_analysis_agent\"\n    description: \"你的职责是对文件空间内的资料（包括 pdf,图片，doc，纯文本，markdown 文件）进行分析，产生需求的结论，计划等各种产物。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"相关资料的位置和分析需求产物\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"实验规划过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n  coder_agent:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - judge_agent\n      - file_read\n      - file_write\n      - dir_list\n      - dir_create\n      - coding_task_agent\n      - execute_command\n      - target_to_coding_task_agent\n      - human_in_loop\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        完成各种复杂的编程任务！\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        **参考流程:**\n          1. 你将会得到之前的 agent或者用户给你提供的详细的实验计划的文件地址（或者直接的实验需求），如果是文件地址，你首先应该确保文件存在。否则进行最终输出并给出错误信息。你应该严格查看注意事项，并严格遵守。\n          2. 检查是否已经存在已有的代码项目，如果已经存在实验代码或项目，则使用execute_command中的 grep，或者 file_read，dir_list来探索整个项目，并对项目进行总结和预览。\n          3. 阅读实验或者代码计划，\n            1)如果代码任务比较复杂：\n            i.  将实验计划的文件地址传送给target_to_coding_task_agent，让其转化为具体的编码任务。\n            ii. 然后分析编码任务，将编码任务按照coding_task_agent指定的要求传递给它，告诉它整个实验计划和 idea 的文件地址作为上下文，但是要提醒其专注于自己分配到的编码任务，注意coding_task_agent只允许在code_run目录下工作。\n            iii.注意各个代码任务中的依赖和关联，在任务时提醒 coding_task_agent。\n            vi. 实验的入口函数或文件应该自己编写，并运行，如果失败，则进行 debug，如果是对于模块问题，依据问题难度考虑直接修复或者调用coding_task_agent进行修复。\n            v.  重复上述过程直到实验运行成功。\n            2)如果任务比较简单：\n            i. 自己编写代码。\n            ii. 运行。\n            注意：\n            1. 如果没有用户的明确需求，作为编码任务，你应该都在 code_run 目录下创建文件（包括所有代码）,注意每次创建自己的文件前检查是否存在别人的文件，不要覆盖，有些别人已经写过的可以复用的功能文件你可以复用。\n            2. 执行代码时，统一使用 execute_command 运行（例如：`python -u code_run/xxx.py`）。需要依赖时也用 execute_command 运行 pip（例如：`pip install -r requirements.txt` 或 `pip install xxx`）。\n            3. 如果需要长时间运行（如 Web 服务），使用 execute_command 的后台模式 `background=true` 并指定 `output_file`，用 file_read 查看输出日志；结束后使用 execute_command 运行 `ps`/`kill` 清理遗留进程。\n        根据难度进行编排。如果任务比较简单，大部分情况下，非学术研究的编程任务都可以直接完成.例如简单的成本计算，验证等。\n        注意事项：\n        1. 如果是需要挂起执行的例如flask 网站任务，使用后台执行并定向输出文件。检查输出文件进行 debug。同时及时管理运行进程进行终止。\n        2. 网站等视觉任务！一定要在挂起运行后指导人类进行审查！如果需要人类交互（例如让人类反馈网站页面结果或者进一步修改，这种视觉任务 judge agent 无法完成，请交给人类反馈），使用 human_in_loop 工具，并给出人类交互的提示词。\n        3. （桌面端默认禁用浏览器自动化能力）\n        4. 确定完成任务后，必须关闭所有遗留进程！\n    name: \"coder_agent\"\n    description: \"完成各种编程任务！\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"实验计划的文件地址或详细实验要求。以及前序任务的文件结果信息（如有）。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"实验实现过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n  create_figures_agent:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - judge_agent\n      - file_read\n      - file_write\n      - move_data_to_clean_directory\n      - create_figures_python_agent\n      - create_figures_by_ai\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        完成各种作图，包括数据转图像，描述转图像,支持各种风格，ai生图，代码生图（数据图），写实，油画等等。\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n        **参考流程:**\n          1. 你将会得到之前的 agent或者用户给你提供的实验代码和生成结果的文件位置，还有实验计划文件的地址（由 idea_agent 生成），或需要你根据其提示信息自己寻找，一般在code_run 目录下，不要保留实验生产的体现数值结果图片（你需要自己重新生成），但是例如地图，网络图类型的文件还是可以保留，但是要找到产生图片的代码，并给出注释文件。\n          2. 分析code_run目录下的文件，找到相关的结果文件（注意和测试文件区分），同时找到所有参与结果生成的算法代码.py和对应的.md文件（可以基于步骤 1 种的说明文字进行寻找，无需完全分析代码）。\n          3. 分析所有代码文件或者其对应的.md文件，分析所有结果文件，读取实验 idea 文件，从学术发表的角度，思考应该绘制什么图。你必须包含的图有框架图（基于总体代码流程，但是是基于 idea 的系统框架图而不是算法流程图），和基于结果的实验图。\n          4. 在进行下一步之前，确保你已经阅读了所有 csv 文件（文件过大的比如超过 1000 行的可以只读前 300 行，理解 paper 的写作意图，从不同方向经可能多的绘制不同类型的图不少于3 张。也可以存在一张图中多个子图的类型。\n          5. 使用create_figures_python_agent工具，生成基于数据的图片，你应该详细说明每个图基于表格的是什么数据进行生成（数据文件地址），生成什么样的图形，一般基于matplotlib,注意告诉她需要英文绘图（必须详细！）。你应该一次性告诉它所有作图需求。\n          6. 使用create_figures_by_ai工具，生成基于框架图的图片，你应该详用英文说明这个框架图的生成提示词(这个提示词应该保存为这个图片的说明文件），还包括保存的位置。你最多生成一张框架图。并配上图片注释文件。\n          **注意事项:**\n          1. 重要：你不是编程 ai，不要自己尝试编程。\n          2. create_figures_python_agent主要用于绘制数据图，文生图或者复杂图像请使用create_figures_by_ai，create_figures_by_ai几乎可以生成任何详细提示的图像。\n    name: \"create_figures_agent\"\n    description: \"完成各种作图，包括数据转图像，描述转图像,支持各种风格，ai生图，代码生图（数据图），写实，油画等等。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"实验代码和结果数据的位置信息。以及前序任务的文件结果信息（如有）。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"绘图过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n  material_to_document_agent:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - judge_agent\n      - file_read\n      - file_write\n      # - md_to_document_agent\n      - sub_part_editor_agent\n      - dir_list\n      - dir_create\n      - file_move\n      - create_figures_agent\n      - move_data_to_clean_directory\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - proof_agent\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是基于现在的所有材料完成论文/报告/或者任何文档结果的生成（生成一个 tex 项目）\n      agent_workflow: |\n        详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该参考下面的流程：\n          **你的流程:**\n          无需使用复杂的文章格式（例如 IEEE）,避免表格或者图片超出页面等最后的排版错误问题！文章结构应该更具用户需求来定制，保证生成的文章看起来完整有逻辑！\n          0. 你将会得到之前的agent整理的所有图表的地址，包括相关的说明，还有之前进行 idea 生成的时候的所有相关文献。\n          1. 如果材料不在一个文件夹中，使用move_data_to_clean_directory工具将你写作所需的所有材料复制到一个干净的文件夹中\n          2. 有一个目录将会包含大部分资料除了少部分例如文献（但是文献也有可能已经在主要工作目录下，请你自己检查）等，你应该在拥有大部分相关材料的目录下工作，作为主要目录，不要自己创建新的目录！。并将散落的有用文件（特别是所有文章的pdf文件）移动到这个主要目录下，重复则无需移动。\n          3. 第一步，你应该根据大致的图的结果说明（通过读取相关文字材料），实验计划和idea内容，拟定一个标题和文章大纲。\n          4. 根据你拟定的标题和文章大概在指定工作目录下创建 main.tex文件和 bib 文件（先为空）。main.tex文件包含你拟定的大纲，切记所有写作都是使用英文。作者为polyu AI Researcher或者根据用户需求而定。大纲应该完全按照学术论文的标准进行，而且通过引入一些之后要写的 tex 文件来构造整个文件，例如 abstract.tex, introduction.tex, related_work.tex等等。\n          5. 每次完成sub_tex前，使用 dir_list工具和file_read工具观察文章所需要的章节，和已经完成的章节。调用sub_part_editor_agent工具完成剩下的 sub_tex，你应该有计划的完成例如 introduction 和 abstract 部分应该放在最后因为这两个要基于剩下的部分才能完成，告诉工具你要完成的部分，已经完成的部分，和文件夹中所有材料的地址，以及参考文献，并且你的大纲和思路。对于每个部分记得重点强调不同的要求，例如方法说明部分如果实验有代码，应该在该节包含伪代码，如果已经提供了框架图，也需要包含框架图这都是必须要明确要求的。\n          6. 使用proof_agent工具对文章进行润色，修改和语法纠正。\n          **注意事项:**\n          1. 重要：注意写作顺序，严格按照指令执行！不要自己完成所有写作，交给工具完成 sub_tex 的写作！！！！\n          2. 你应该告诉sub_part_editor_agent应该在什么位置生成tex 文件，防止文件地方出错！\n        如果是非学术类的协作任务，你可以直接根据输入要求撰写 md 文档或 tex 文件。\n    name: \"material_to_document_agent\"\n    description: \"你的职责是基于现在的所有材料完成论文/报告/或者任何文档结果的（生成生成一个 tex 项目）\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"所有论文材料的位置信息，包括图表、实验数据、文献等。以及前序任务的文件结果信息（如有）。\"\n        max_turns:\n          type: \"integer\"\n          default: 100\n          description: \"论文生成过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n"
  },
  {
    "path": "config/agent_library/Researcher/level_3_agents.yaml",
    "content": "tools:\n  alpha_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - material_to_document_agent\n      - data_collection_agent\n      - data_analysis_agent\n      - coder_agent\n      - create_figures_agent\n      - human_in_loop\n      - load_skill\n      - offload_skill\n      - fresh\n      - judge_agent\n      - file_read\n      - file_write\n      - file_move\n      - dir_list\n      - dir_create\n      - reference_list\n      - reference_add\n      - reference_delete\n      - final_output\n      - execute_command\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你的职责是一个通用的 AI 助手，可以撰写论文，和用户对话，调研，科学研究等等工作。\n      agent_workflow: |\n        **你的流程:**\n        1. 详细分析用户的意图，并根据意图编排使用你的工具完成任务。\n        例如，如果用户想要进行学术论文写作，则你应该依次调用：\n        1. 使用data_collection_agent工具收集相关文献\n        2. 使用data_analysis_agent工具获取实验想法和计划\n        3. 使用coder_agent完成实验（如果是代码实验）\n        4. 使用create_figures_agent将实验数据转换为图表，该 agent 也可以生成框架图，写实图像等各种类型的图像。\n        5. 使用material_to_document_agent工具将实验数据和图表转换为论文\n        6. 使用judge_agent工具判断论文是否符合要求\n        7. 使用final_output工具输出自己已经完成任务的情况\n        如果用户不是传统的学术论文写作需求（一般来说报告类需求最好有丰富好看的图表），你应该自己编排选择合适的工具完成,基于你的经验和任务难度，有时候并不是所有任务都要用到上述所有智能体功能。你作为直接和用户接触的 agent，还可能遇到基于历史任务和文件空间的单纯的聊天，询问等需求，使用human_in_loop工具和用户进行对话交互。\n        这种时候直接调用 final_output工具完成即可。如果用户在需求确认和探讨阶段，你也可以调用 human_in_loop工具和用户进行对话交互。\n        不要越界，对应任务交给对应的智能体，无需为其建立文件夹等操作。\n    name: \"alpha_agent\"\n    description: \"根据用户的写作意图，编排使用你的工具完成任务\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"用户写作需求的初始指令\"\n        max_turns:\n          type: \"integer\"\n          default: 1000\n          description: \"文献收集过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n  \n\n  deep_research_agent:\n    level: 3\n    type: llm_call_agent\n    available_tools:\n      - get_data_from_wiki\n      - get_data_from_google_scholar\n      - get_data_from_arxiv\n      - get_data_from_web_search\n      - judge_agent\n      - final_output\n      - file_read\n      - file_write\n      - file_move\n      - dir_list\n      - dir_create\n      - answer_from_papers\n      - write_report\n      - reference_list\n      - reference_add\n      - reference_delete\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你是一名拥有顶级智库背景的高级研究员。你的目标是生成一份篇幅超过 10,000 字、逻辑严密、数据详实且具有颠覆性洞察的 Markdown 格式研究报告。你不仅要回答“是什么”，更要通过严谨的因果推导分析“为什么”和“未来会怎样”。\n      agent_workflow: |\n        ### 执行准则：对齐评分标准\n        1. **全面性 (Comprehensiveness)**: 必须覆盖核心概念定义、多维现状分析（政治、经济、社会、技术）、地域/人群差异、以及至少 5 个维度的横向对比。\n        2. **洞察力 (Insight)**: 拒绝常识堆砌。必须包含 3 个以上的“因果逻辑链条推导”，识别行业潜在的结构性矛盾，并提出独到的前瞻性预测。\n        3. **可读性 (Readability)**: 必须包含大量的 Markdown 表格（用于对比数据）、加粗的关键结论、以及由浅入深的层级标题。\n        4. **篇幅约束**: 总字数必须 > 10,000 字。通过“模块化撰写”实现，每个主要章节需保持在 1,500 字左右。\n\n        ### 任务编排流程：\n        **第一阶段：多维数据采集（确保全面性）**\n        - 调用搜索工具（scholar, arxiv, web）针对主题的不同维度进行专项搜索。\n        - **要求**：必须收集定量数据（指标、占比、增长率）和定性观点（专家评价、政策导向）。\n        - 使用 `answer_from_papers` 提炼核心文献的实验结果或数据。\n\n        **第二阶段：深度逻辑建模（确保洞察力）**\n        - 在开始写作前，必须先生成一个 `insights_and_logic.md` 文件。\n        - 该文件需包含：\n            1. **核心矛盾分析**：当前领域内最难以调和的 2-3 个矛盾点。\n            2. **因果推导图谱**：描述技术或社会变革如何一步步影响到最终结果。\n            3. **新颖观点提炼**：提出一个非显而易见的、具有启发性的研究结论。\n          \n        最后阶段：调用 write_report工具完成报告撰写。(必须完成！)\n        - 最后调用 `final_output` 确认完成。\n    name: \"deep_research_agent\"\n    description: \"你是一名拥有顶级智库背景的高级研究员。你的目标是生成一份篇幅超过 10,000 字、逻辑严密、数据详实且具有颠覆性洞察的 Markdown 格式研究报告。你不仅要回答“是什么”，更要通过严谨的因果推导分析“为什么”和“未来会怎样”。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"用户写作需求的初始指令\"\n        max_turns:\n          type: \"integer\"\n          default: 1000\n          description: \"文献收集过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n \n\n  write_report:\n    level: 2\n    type: llm_call_agent\n    available_tools:\n      - judge_agent\n      - final_output\n      - file_read\n      - file_write\n      - file_move\n      - dir_list\n      - dir_create\n      - answer_from_papers\n      - reference_list\n      - reference_add\n      - reference_delete\n    max_turns: 100\n    execution_model: claude-3-7-sonnet-20250219\n    prompts:\n      agent_responsibility: |\n        你是一个专业的学术报告撰写大师，你必须结合文件空间所有已知材料完成详细的不少于 10000 字的调研报告。\n      agent_workflow: |\n        ### 执行准则：对齐评分标准\n        1. **全面性 (Comprehensiveness)**: 必须覆盖核心概念定义、多维现状分析（政治、经济、社会、技术）、地域/人群差异、以及至少 5 个维度的横向对比。\n        2. **洞察力 (Insight)**: 拒绝常识堆砌。必须包含 3 个以上的“因果逻辑链条推导”，识别行业潜在的结构性矛盾，并提出独到的前瞻性预测。\n        3. **可读性 (Readability)**: 必须包含大量的 Markdown 表格（用于对比数据）、加粗的关键结论、以及由浅入深的层级标题。\n        4. **篇幅约束**: 总字数必须 > 10,000 字。通过“模块化撰写”实现，每个主要章节需保持在 1,500 字左右。\n\n        **第零阶段：结构化大纲设计（确保可读性）**\n        - 构思一个至少 6-8 个一级标题的详细大纲。\n        - 必须包含：执行摘要、方法论定义、核心现状、多维度横向对比表格、深层机制剖析、风险与挑战、未来趋势预测、参考文献。\n\n        **第一阶段：分步模块化撰写（确保篇幅与质量）**\n        - **核心指令**：禁止一次性生成。你必须按照大纲，使用 `file_write` 的 **append 模式**，逐章节填充 `report_final.md`。\n        - **字数填充策略**：在每个章节内进行细节展开，包括理论引用、数据解读、案例分析。\n        - **强制要求**：每个大章节必须包含至少一个 Markdown 表格或结构化列表。\n        - **终稿执行**：最后的整合参考写作大纲和所有材料总结，使用 append模式按章节写入到 report_final.md中！\n\n        **第二阶段：引用与自检**\n        - 整理所有参考文献，按照学术规范列于文末。\n        - 调用 `judge_agent`（如有）或自我评估是否满足 10,000 字要求。\n\n        ### 注意事项：\n        - 严禁简单复制粘贴，所有资料必须经过你的逻辑消化后，以“分析者”的口吻写出。\n        - 保持客观中立，但观点要鲜明。\n    name: \"write_report\"\n    description: \"你是一名拥有顶级智库背景的高级研究员。你的目标是生成一份篇幅超过 10,000 字、逻辑严密、数据详实且具有颠覆性洞察的 Markdown 格式研究报告。你不仅要回答“是什么”，更要通过严谨的因果推导分析“为什么”和“未来会怎样”。\"\n    parameters:\n      type: \"object\"\n      properties:\n        task_id:\n          type: \"string\"\n          description: \"任务的唯一ID。\"\n        task_input:\n          type: \"string\"\n          description: \"用户写作需求的初始指令\"\n        max_turns:\n          type: \"integer\"\n          default: 1000\n          description: \"文献收集过程的最大轮次，防止无限循环。可选。\"\n      required: [\"task_id\", \"task_input\"]\n\n         \n\n"
  },
  {
    "path": "config/run_env_config/ali_qwen_llm_config.yaml",
    "content": "temperature: 0\nmax_tokens: 0\n#示意，大概基于官方减去 20k\nmax_context_window: 200000\nbase_url: https://dashscope.aliyuncs.com/compatible-mode/v1\napi_key: \ntimeout: 600              # LiteLLM 原生：建立连接及整体响应的最大等待时间 \nstream_timeout: 20        # LiteLLM 原生：两个流式数据块之间的最大间隔时间\nfirst_chunk_timeout: 20   # 应用层强制：连接建立+首包接收的最大时间（防止连接池死锁）\nmodels:\n- openai/qwen-plus\nfigure_models:\n- google/具体参考 qwen 提供的生图模型\ncompressor_models:\n- openai/qwen-plus\nread_figure_models:\n- openai/qwen-plus\n"
  },
  {
    "path": "config/run_env_config/document_convert_api.yaml",
    "content": "api_server: \"http://192.168.31.4:8000/\"\n#文档转换的 api 提供商，暂时弃用"
  },
  {
    "path": "config/run_env_config/gemini_config_version.yaml",
    "content": "#样例文件，请替换到llm_config.yaml\ntemperature: 0\nmax_tokens: 0\nmax_context_window: 200000\n# Google 官方 API - litellm 会自动识别 gemini/ 前缀并路由到 Google\n# base_url 留空，让 litellm 使用默认的 Google API 端点\nbase_url: \napi_key: your_google_studio_key_here\ntimeout: 600              # LiteLLM 原生：建立连接及整体响应的最大等待时间 \nstream_timeout: 20        # LiteLLM 原生：两个流式数据块之间的最大间隔时间\nfirst_chunk_timeout: 20   # 应用层强制：连接建立+首包接收的最大时间（防止连接池死锁）\nmodels:\n- gemini/gemini-3-flash-preview\nfigure_models:\n- gemini/gemini-3-pro-image-preview\ncompressor_models:\n- gemini/gemini-3-flash-preview\nread_figure_models:\n- gemini/gemini-3-flash-preview\n\n"
  },
  {
    "path": "config/run_env_config/kimi_config_version copy.yaml",
    "content": "#样例文件，请替换到llm_config.yaml\ntemperature: 0\nmax_tokens: 0\nmax_context_window: 200000\nbase_url: https://api.moonshot.cn/v1\napi_key: your_key\ntimeout: 600              # LiteLLM 原生：建立连接及整体响应的最大等待时间 \nstream_timeout: 20        # LiteLLM 原生：两个流式数据块之间的最大间隔时间\nfirst_chunk_timeout: 20   # 应用层强制：连接建立+首包接收的最大时间（防止连接池死锁）\nmodels:\n- openai/kimi-k2-thinking\nfigure_models:\n#无效了\n- google/gemini-3-pro-image-preview\ncompressor_models:\n- openai/kimi-k2-thinking\nread_figure_models:\n- openai/kimi-latest\n"
  },
  {
    "path": "config/run_env_config/llm_config.example.yaml",
    "content": "\n\ntemperature: 0\nmax_tokens: 0\nmax_context_window: 500000\nbase_url: https://openrouter.ai/api/v1\napi_key: \ntimeout: 600              # LiteLLM 原生：建立连接及整体响应的最大等待时间 \nstream_timeout: 30        # LiteLLM 原生：两个流式数据块之间的最大间隔时间\nfirst_chunk_timeout: 30   # 应用层强制：连接建立+首包接收的最大时间（防止连接池死锁）\n\n# 不同用途的默认 tool_choice 策略。也可以在具体模型对象里再写 tool_choice 覆盖。\ntool_choice:\n  execution: required\n  thinking: none\n  compressor: none\n  image_generation: none\n  read_figure: none\n\nmodels:\n# 简单格式：如果不配置 url 和 key，默认使用用全局 api_key + base_url\n- openai/google/gemini-3-flash-preview\n# 对象格式：覆盖 api_key 和/或 base_url，使用其他供应商的模型。\n# - name: openai/qwen/qwen3.5-27b\n#   default: true\n#   api_key:\n#   base_url: https://openrouter.ai/api/v1\n#   tool_choice: auto\n# - name: openai/qwen-plus\n#   api_key:\n#   base_url: https://dashscope.aliyuncs.com/compatible-mode/v1\n#   tool_choice: auto\n\nfigure_models:\n# 同理\n- google/gemini-3-pro-image-preview\n# - name: openai/qwen-vl-max\n#   default: true\n#   api_key:\n#   base_url: https://dashscope.aliyuncs.com/compatible-mode/v1\n\ncompressor_models:\n- openai/google/gemini-3-flash-preview    # 用全局 key\n# - name: openai/google/gemini-3-flash-preview\n#   default: true\n\n\nthinking_models:\n- openai/google/gemini-3-flash-preview    # thinking agent 专用模型\n# - name: openai/google/gemini-3-flash-preview\n#   default: true\n#   tool_choice: none\n\nread_figure_models:\n- openai/google/gemini-3-flash-preview    # 图片分析专用（ToolServer 侧 vision_tool text-only 模式使用）\n\n# 多模态配置\nmultimodal: true           # 主模型（models）+ thinking agent 是否支持多模态图片嵌入\ncompressor_multimodal: true   # 压缩模型（compressor_models）是否支持多模态图片嵌入\n\n\n\n\n\n\n\n"
  },
  {
    "path": "config/run_env_config/third_part_api.yaml",
    "content": "temperature: 0\nmax_tokens: 0\nmax_context_window: 200000\nbase_url: your provider'url for example: https://XXXX.top/v1 / 你供应商提供的 url\napi_key: yourkey\ntimeout: 600              # LiteLLM 原生：建立连接及整体响应的最大等待时间 \nstream_timeout: 20        # LiteLLM 原生：两个流式数据块之间的最大间隔时间\nfirst_chunk_timeout: 20   # 应用层强制：连接建立+首包接收的最大时间（防止连接池死锁）\nmodels:\n# 如果供应商提供的是 openai 格式前缀填写openai,如果是anthropic格式前缀填写anthropic\n# 注意前缀名称和站点模型无关，前缀后再填写运营商提供的模型名称，例如 openrouter 提供\n# 了openai格式的gpt-4o,模型名为 openai/gpt-4o，则应该填写 openai/openai/gpt-4o\n# 如果模型厂商提供的是 gpt-4o，则直接填写 openai/gpt-4o即可\n- openai/claude-haiku-4-5-20251001\nfigure_models:\n#同理，除了openrouter不用填写以外，其他第三方需要填写请求格式前缀，方便路由对应格式\n- openai/dall-e-3 \ncompressor_models:\n- openai/claude-haiku-4-5-20251001\nread_figure_models:\n- openai/gpt-4o"
  },
  {
    "path": "core/__init__.py",
    "content": "# Core modules\n"
  },
  {
    "path": "core/agent_event_emitter.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n统一事件发射器 (Event Emitter)\n负责将事件分发给所有已注册的事件处理器\n\"\"\"\n\nfrom typing import List, Protocol\nfrom .events import AgentEvent\n\nclass EventHandler(Protocol):\n    \"\"\"\n    事件处理器的协议 (Protocol)\n    定义了所有具体事件处理器必须实现的接口\n    \"\"\"\n    def handle(self, event: AgentEvent):\n        \"\"\"\n        处理一个传入的AgentEvent\n        \n        Args:\n            event: 从AgentExecutor分发来的事件对象\n        \"\"\"\n        ...\n\nclass AgentEventEmitter:\n    \"\"\"\n    事件发射器, 向所有注册的处理器分发事件\n    \"\"\"\n    def __init__(self):\n        self._handlers: List[EventHandler] = []\n\n    def register(self, handler: EventHandler):\n        \"\"\"\n        注册一个新的事件处理器\n        \n        Args:\n            handler: 实现了EventHandler协议的对象\n        \"\"\"\n        if handler not in self._handlers:\n            self._handlers.append(handler)\n\n    def dispatch(self, event: AgentEvent):\n        \"\"\"\n        将事件分发给所有已注册的处理器\n        \n        Args:\n            event: 要分发的事件对象\n        \"\"\"\n        for handler in self._handlers:\n            try:\n                handler.handle(event)\n            except Exception as e:\n                # 避免一个处理器的失败影响其他处理器\n                # todo: 这里后续需要换成统一的logger，方便采集服务日志\n                print(f\"[AgentEventEmitter] Error in handler {type(handler).__name__}: {e}\")\n\n"
  },
  {
    "path": "core/agent_executor.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nAgent执行器 - 使用标准消息格式的核心执行逻辑\n历史动作通过 messages 数组传递（而非 system_prompt），支持多模态图片嵌入\n\"\"\"\nfrom typing import Any, Dict, List, Optional\nimport sys\nimport json\nimport os\nimport time\nimport traceback\nfrom collections import OrderedDict\n\n# Windows兼容性：设置UTF-8编码\ntry:\n    from utils.windows_compat import setup_console_encoding\n    setup_console_encoding()\nexcept ImportError:\n    pass\n\nfrom services.llm_client import SimpleLLMClient, ChatMessage\nfrom core.context_builder import ContextBuilder\nfrom core.tool_executor import ToolExecutor\nfrom utils.conversation_storage import ConversationStorage\nfrom utils.event_emitter import get_event_emitter as get_jsonl_emitter\nfrom utils.skill_loader import reset_skill_loader\nfrom utils.user_paths import apply_runtime_env_defaults, get_runtime_settings\nfrom utils.runtime_control import (\n    is_task_running,\n    pop_fresh_request,\n    register_running_task,\n    request_fresh,\n    unregister_running_task,\n)\nfrom utils.task_runtime import resume_task_with_fresh\nfrom tool_server_lite.registry import reload_runtime_registry\nfrom tool_server_lite.tools.code_tools import has_running_background_processes\nfrom utils.mcp_manager import get_mcp_tools, reload_mcp_tools\n\nfrom .agent_event_emitter import AgentEventEmitter\nfrom .event_handlers import ConsoleLogHandler, JsonlStreamHandler\nfrom .events import *\nfrom .runtime_exceptions import InfiAgentRunError\nfrom utils.windows_compat import safe_print\n\n\nclass AgentExecutor:\n    \"\"\"Agent执行器 - 正确的XML上下文架构\"\"\"\n    \n    def __init__(\n        self,\n        agent_name: str,\n        agent_config: Dict,\n        config_loader,\n        hierarchy_manager,\n        direct_tools: bool = False,\n        extra_event_handlers: Optional[List[Any]] = None,\n        exit_on_error: bool = True,\n        raise_on_error: bool = False,\n        stream_llm_tokens: bool = False,\n    ):\n        \"\"\"初始化Agent执行器\"\"\"\n        self.agent_name = agent_name\n        self.agent_config = agent_config\n        self.config_loader = config_loader\n        self.hierarchy_manager = hierarchy_manager\n        self.direct_tools = direct_tools\n        self.extra_event_handlers = list(extra_event_handlers or [])\n        self.exit_on_error = bool(exit_on_error)\n        self.raise_on_error = bool(raise_on_error)\n        self.stream_llm_tokens = bool(stream_llm_tokens)\n        \n        self._setup_event_emitter()\n\n        # 从配置中提取信息\n        self.available_tools = list(agent_config.get(\"available_tools\", []))\n        if \"task_history_search\" not in self.available_tools and \"task_history_search\" in config_loader.all_tools:\n            self.available_tools.append(\"task_history_search\")\n        self.max_turns = self._resolve_max_turns()\n        requested_model = self._get_agent_model_preference(\"execution\")\n        self._inject_mcp_tools()\n        \n        # 初始化LLM客户端\n        self.llm_client = SimpleLLMClient()\n        self.llm_client.set_tools_config(config_loader.all_tools)\n        \n        # 验证并调整模型\n        available_models = self.llm_client.models\n        final_model = self.llm_client.resolve_model(\"execution\", requested_model)\n        is_fallback = False\n        if requested_model and requested_model not in available_models:\n            is_fallback = True\n        self.execution_model = final_model\n        self.model_type = final_model\n        \n        # 发送模型选择事件\n        self.event_emitter.dispatch(ModelSelectionEvent(\n            requested_model=requested_model,\n            final_model=final_model,\n            is_fallback=is_fallback\n        ))\n\n        # 初始化上下文构造器（负责完整上下文构建）\n        self.context_builder = ContextBuilder(\n            hierarchy_manager,\n            agent_config=agent_config,\n            config_loader=config_loader,\n            llm_client=self.llm_client,\n            max_context_window=self.llm_client.max_context_window\n        )\n        \n        # 初始化工具执行器\n        self.tool_executor = ToolExecutor(\n            config_loader,\n            hierarchy_manager,\n            direct_mode=direct_tools,\n            extra_event_handlers=self.extra_event_handlers,\n            exit_on_error=self.exit_on_error,\n            raise_on_error=self.raise_on_error,\n            stream_llm_tokens=self.stream_llm_tokens,\n        )\n        \n        # 初始化对话存储\n        self.conversation_storage = ConversationStorage()\n        \n        # Agent状态\n        self.agent_id = None\n        self.action_history = []  # 渲染用（会压缩）\n        self.action_history_fact = []  # 完整轨迹（不压缩）\n        self.execution_traces = []  # execution LLM 原生输出轨迹\n        self.thinking_traces = []  # thinking LLM 原生输出轨迹\n        self.pending_tools = []  # 待执行的工具（用于恢复）\n        self.latest_thinking = \"\"\n        self.first_thinking_done = False\n        runtime = get_runtime_settings()\n        self.thinking_enabled = bool(self.agent_config.get(\"thinking_enabled\", runtime.get(\"thinking_enabled\", True)))\n        self.thinking_steps = int(\n            self.agent_config.get(\"thinking_steps\")\n            or runtime.get(\"thinking_steps\", runtime.get(\"thinking_interval\", runtime.get(\"action_window_steps\", 30)))\n        )\n        self.action_window_steps = self.thinking_steps\n        self.thinking_interval = self.thinking_steps\n        self.no_tool_retry_limit = int(\n            self.agent_config.get(\"no_tool_retry_limit\")\n            or runtime.get(\"no_tool_retry_limit\", 7)\n        )\n        self.fresh_enabled = runtime.get(\"fresh_enabled\", False)\n        self.fresh_interval_sec = runtime.get(\"fresh_interval_sec\", 0)\n        self.last_fresh_at = time.time()\n        self.tool_call_counter = 0\n        self.llm_turn_counter = 0  # LLM调用轮次计数器（用于消息分组）\n        self.current_task_id = None\n\n    def _get_agent_model_preference(self, category: str) -> Optional[str]:\n        field_map = {\n            \"execution\": \"execution_model\",\n            \"thinking\": \"thinking_model\",\n            \"compressor\": \"compressor_model\",\n            \"image_generation\": \"image_generation_model\",\n            \"read_figure\": \"read_figure_model\",\n        }\n        field = field_map.get(category, \"execution_model\")\n        value = self.agent_config.get(field)\n        if category == \"execution\" and not value:\n            value = self.agent_config.get(\"model_type\")\n        return str(value or \"\").strip() or None\n\n    def _resolve_max_turns(self) -> int:\n        env_value = str(os.environ.get(\"MLA_MAX_TURNS\", \"\") or \"\").strip()\n        if env_value:\n            try:\n                return max(1, int(env_value))\n            except Exception:\n                pass\n        return 100000\n\n    def _inject_mcp_tools(self):\n        \"\"\"将 MCP 动态工具并入当前 Agent 的工具配置与可见工具列表。\"\"\"\n        try:\n            mcp_tools = get_mcp_tools(force_reload=False)\n            if not mcp_tools:\n                return\n            for tool_name, tool_config in mcp_tools.items():\n                self.config_loader.all_tools[tool_name] = tool_config\n                if tool_name not in self.available_tools:\n                    self.available_tools.append(tool_name)\n        except Exception:\n            pass\n\n    def _setup_event_emitter(self):\n        \"\"\"初始化事件发射器并注册处理器\"\"\"\n        self.event_emitter = AgentEventEmitter()\n        self.event_emitter.register(ConsoleLogHandler())\n        for handler in self.extra_event_handlers:\n            self.event_emitter.register(handler)\n        \n        jsonl_emitter = get_jsonl_emitter()\n        if jsonl_emitter.enabled:\n            self.event_emitter.register(JsonlStreamHandler(enabled=True))\n\n    def _emit_sdk_stream_event(self, event_type: str, payload: Dict[str, Any]):\n        parts = str(event_type or \"\").split(\".\", 2)\n        normalized = {\n            \"event_type\": str(event_type or \"\"),\n            \"phase\": parts[0] if len(parts) > 0 else \"\",\n            \"domain\": parts[1] if len(parts) > 1 else \"\",\n            \"action\": parts[2] if len(parts) > 2 else \"\",\n            \"payload\": payload,\n        }\n        for handler in self.extra_event_handlers:\n            emitter = getattr(handler, \"emit\", None)\n            if not callable(emitter):\n                continue\n            try:\n                emitter(normalized)\n            except Exception:\n                pass\n    \n    def run(self, task_id: str, user_input: str) -> Dict:\n        \"\"\"执行Agent任务\"\"\"\n\n        self.event_emitter.dispatch(AgentStartEvent(\n            agent_name=self.agent_name, \n            task_input=user_input\n        ))        \n        # 存储 task_input 供压缩器使用\n        self.current_task_id = task_id\n        self.current_task_input = user_input\n        try:\n            try:\n                self.hierarchy_manager.set_runtime_metadata(\n                    agent_system=self.config_loader.agent_system_name,\n                    agent_name=self.agent_name,\n                    user_input=user_input,\n                )\n            except Exception:\n                pass\n\n            register_running_task(\n                task_id=task_id,\n                agent_name=self.agent_name,\n                user_input=user_input,\n                agent_system=self.config_loader.agent_system_name,\n            )\n\n            # Agent入栈\n            self.agent_id = self.hierarchy_manager.push_agent(self.agent_name, user_input)\n            self.tool_executor.set_agent_context(agent_id=self.agent_id, agent_name=self.agent_name)\n\n            # 尝试加载已有的对话历史\n            start_turn = self._load_state_from_storage(task_id)\n            \n            try:\n                # 首次thinking（初始规划）\n                if self.thinking_enabled and start_turn == 0 and not self.first_thinking_done:\n                    thinking_result = self._trigger_thinking(\n                        task_id, \n                        user_input, \n                        is_initial=True\n                    )\n                    if thinking_result:\n                        self.latest_thinking = thinking_result\n                        self.first_thinking_done = True\n                        self.hierarchy_manager.update_thinking(self.agent_id, thinking_result)\n                        self._save_state(task_id, user_input, 0)\n            except Exception as e:\n                return self._handle_execution_error(e)\n            \n            # 强制工具调用计数器\n            max_tool_try = 0\n\n            # 执行循环\n            for turn in range(start_turn, self.max_turns):\n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"\\n--- 第 {turn + 1}/{self.max_turns} 轮执行 ---\", \n                    style='separator'\n                ))\n                \n                try:\n                    self._maybe_run_scheduled_fresh(task_id, user_input, turn)\n\n                    # 每轮开始前保存状态\n                    self._save_state(task_id, user_input, turn)\n\n                    # 检查并压缩历史动作（如果超过限制）\n                    self._compress_action_history_if_needed()\n\n                    # 构建系统提示词（不含历史动作，历史动作改由 messages 承载）\n                    full_system_prompt = self.context_builder.build_context(\n                        task_id,\n                        self.agent_id,\n                        self.agent_name,\n                        user_input,\n                        action_history=self.action_history,\n                        include_action_history=False  # 历史动作通过 messages 传递\n                    )\n                    \n                    # 从 action_history 构建标准 messages 数组\n                    messages = self._build_messages_from_action_history()\n                    \n                    # 无 thinking 模式：在动作调用前先进行一轮 ReAct 反思（纯文本，不调用工具）\n                    if not self.thinking_enabled:\n                        self._run_react_reflection(\n                            task_id=task_id,\n                            task_input=user_input,\n                            system_prompt=full_system_prompt,\n                            messages=messages,\n                            turn=turn,\n                        )\n                        messages = self._build_messages_from_action_history()\n\n                    # 调用LLM（使用标准 messages 格式）\n                    llm_response = self._execute_llm_call(full_system_prompt, messages, task_id=task_id)\n                    \n                    if llm_response.status != \"success\":\n                        error_result = {\n                            \"status\": \"error\",\n                            \"output\": \"LLM调用失败\",\n                            \"error_information\": llm_response.error_information\n                        }\n                        error_result = self._with_model_outputs(error_result)\n                        self.hierarchy_manager.pop_agent(self.agent_id, str(error_result))\n                        self.event_emitter.dispatch(AgentEndEvent(status='error', result=error_result))\n                        return error_result\n\n                    if not llm_response.tool_calls:\n                        if self.thinking_enabled:\n                            if max_tool_try < self.no_tool_retry_limit:\n                                max_tool_try += 1\n                                self.event_emitter.dispatch(CliDisplayEvent(\n                                    message=f\"⚠️ LLM未调用工具，第{max_tool_try}/{self.no_tool_retry_limit}次提醒\",\n                                    style='warning'\n                                ))\n                                self.action_history.append({\n                                    \"_turn\": self.llm_turn_counter,\n                                    \"tool_name\": \"_no_tool_call\",\n                                    \"arguments\": {},\n                                    \"result\": {\n                                        \"status\": \"error\",\n                                        \"output\": f\"第{max_tool_try}次：LLM未调用工具，请在下一轮中必须调用工具\"\n                                    },\n                                    \"assistant_content\": llm_response.output or \"\",\n                                    \"reasoning_content\": llm_response.reasoning_content or \"\",\n                                })\n                                self.llm_turn_counter += 1\n                                self._save_state(task_id, user_input, turn)\n                                continue\n\n                            thinking_result = self._trigger_thinking(\n                                task_id,\n                                user_input,\n                                is_initial=False,\n                                is_forced=True\n                            )\n                            error_output = thinking_result or \"多次未调用工具\"\n                            error_result = {\n                                \"status\": \"error\",\n                                \"output\": error_output,\n                                \"error_information\": \"Agent拒绝调用工具\"\n                            }\n                            error_result = self._with_model_outputs(error_result)\n                            self.hierarchy_manager.pop_agent(self.agent_id, str(error_result))\n                            self.event_emitter.dispatch(AgentEndEvent(status='error', result=error_result))\n                            self.event_emitter.dispatch(ThinkingFailEvent(agent_name=self.agent_name, error_message=f\"[{self.agent_name}] 强制thinking: {thinking_result if thinking_result else '分析失败'}\"))\n                            return error_result\n\n                        text_response = (llm_response.output or \"\").strip()\n                        if text_response:\n                            self._record_text_response(\n                                tool_name=\"_assistant_text\",\n                                text=text_response,\n                                llm_turn=self.llm_turn_counter,\n                                reasoning_content=llm_response.reasoning_content or \"\",\n                            )\n                            self.llm_turn_counter += 1\n                            self._save_state(task_id, user_input, turn)\n                            continue\n\n                        error_result = {\n                            \"status\": \"error\",\n                            \"output\": \"\",\n                            \"error_information\": \"ReAct模式下模型既未调用工具，也未返回可用文本\"\n                        }\n                        error_result = self._with_model_outputs(error_result)\n                        self.hierarchy_manager.pop_agent(self.agent_id, str(error_result))\n                        self.event_emitter.dispatch(AgentEndEvent(status='error', result=error_result))\n                        return error_result\n                    # 重置计数器（成功调用了工具）\n                    max_tool_try = 0\n\n                    # 提取本轮 LLM 输出的文本内容和推理内容（所有 tool_call 共享）\n                    current_assistant_content = llm_response.output or \"\"\n                    current_reasoning_content = llm_response.reasoning_content or \"\"\n                    current_llm_turn = self.llm_turn_counter\n\n                    # 执行所有工具调用\n                    for tool_call in llm_response.tool_calls:\n                        final_output_result = self._execute_tool_call(\n                            tool_call, task_id, user_input, turn,\n                            assistant_content=current_assistant_content,\n                            reasoning_content=current_reasoning_content,\n                            llm_turn=current_llm_turn\n                        )\n                        if final_output_result:\n                            final_output_result = self._with_model_outputs(final_output_result)\n                            self.event_emitter.dispatch(AgentEndEvent(status='success', result=final_output_result))\n                            self.hierarchy_manager.pop_agent(self.agent_id, final_output_result.get(\"output\", \"\"))\n                            return final_output_result\n                    \n                    self.llm_turn_counter += 1\n                    \n                    counter_before = self.tool_call_counter - len(llm_response.tool_calls)\n\n                    # 检查是否该触发thinking（每 N 轮工具调用）\n                    # 用整除判断是否跨过了 thinking_interval 边界（避免多 tool_call 跳过边界值）\n                    crossed_boundary = (counter_before // self.thinking_interval) < (self.tool_call_counter // self.thinking_interval)\n                    if self.thinking_enabled and self.tool_call_counter > 0 and crossed_boundary:\n                        thinking_result = self._trigger_thinking(task_id, user_input, is_initial=False)\n                        if thinking_result:\n                            self.latest_thinking = thinking_result\n                            self.hierarchy_manager.update_thinking(self.agent_id, thinking_result)\n                            self._save_state(task_id, user_input, turn)\n\n                    # 检查动作窗口是否跨过边界：thinking 完成后再清空当前可见动作窗口\n                    crossed_action_window = (counter_before // self.action_window_steps) < (self.tool_call_counter // self.action_window_steps)\n                    if self.thinking_enabled and self.tool_call_counter > 0 and crossed_action_window:\n                        self.action_history = []\n                        self.llm_turn_counter = 0\n                \n                except Exception as e:\n                    return self._handle_execution_error(e)\n            timeout_result = {\n                \"status\": \"error\",\n                \"output\": f\"执行超过最大轮次限制: {self.max_turns}\",\n                \"error_information\": f\"Max turns {self.max_turns} exceeded\"\n            }\n            timeout_result = self._with_model_outputs(timeout_result)\n            self.hierarchy_manager.pop_agent(self.agent_id, str(timeout_result))\n            self.event_emitter.dispatch(AgentEndEvent(status='error', result=timeout_result))\n            self.event_emitter.dispatch(CliDisplayEvent(\n                message=\"\\n⚠️ 达到最大轮次限制: {self.max_turns}\"\n            ))\n            \n            return timeout_result\n        finally:\n            unregister_running_task(task_id)\n\n    def _load_state_from_storage(self, task_id: str) -> int:\n        \"\"\"从存储加载状态, 返回起始轮次.\"\"\"\n        loaded_data = self.conversation_storage.load_actions(task_id, self.agent_id)\n        start_turn = 0\n        \n        if loaded_data:\n            self.action_history = loaded_data.get(\"action_history\", [])\n            self.action_history_fact = loaded_data.get(\"action_history_fact\", [])\n            self.pending_tools = loaded_data.get(\"pending_tools\", [])\n            self.latest_thinking = loaded_data.get(\"latest_thinking\", \"\")\n            self.first_thinking_done = loaded_data.get(\"first_thinking_done\", False)\n            self.tool_call_counter = loaded_data.get(\"tool_call_counter\", 0)\n            self.llm_turn_counter = loaded_data.get(\"llm_turn_counter\", 0)\n            start_turn = loaded_data.get(\"current_turn\", 0) + 1\n            \n            self.event_emitter.dispatch(HistoryLoadEvent(\n                start_turn=start_turn,\n                action_history_len=len(self.action_history),\n                action_history_fact_len=len(self.action_history_fact),\n                pending_tool_count=len(self.pending_tools)\n            ))\n            \n            # 检查是否已经完成（有final_output）\n            for action in self.action_history_fact:\n                if action.get(\"tool_name\") == \"final_output\":\n                    final_result = action.get(\"result\", {})\n                    self.event_emitter.dispatch(CliDisplayEvent(\n                        message=f\"\\n✅ 任务已完成，直接返回之前的final_output结果\\n   状态: {final_result.get('status')}\", \n                        style='success'\n                    ))\n                    return final_result\n            \n            # 恢复pending工具（如果有）\n            if self.pending_tools:\n                self._recover_pending_tools(task_id)\n\n        return start_turn\n\n    def _build_messages_from_action_history(self) -> List[Dict]:\n        \"\"\"\n        从 action_history 动态重建 OpenAI 标准格式的 messages 数组\n        \n        支持三种 action 类型：\n        1. _historical_summary → user 消息（压缩后的历史摘要）\n        2. _no_tool_call → assistant 消息（纯文本）+ user 消息（提醒）\n        3. 普通 action → 按 _turn 分组为 assistant(tool_calls) + tool(results) + user(images)\n        \n        Returns:\n            OpenAI 格式的 messages 列表\n        \"\"\"\n        # 初始 user 消息\n        messages = [{\n            \"role\": \"user\", \n            \"content\": \"请根据当前任务和上下文，执行下一步操作。请调用合适的工具来完成任务。不要重复已执行的动作！\"\n        }]\n        \n        if not self.action_history:\n            return messages\n\n        use_kimi_history_tool_ids = self._should_normalize_kimi_history_tool_ids()\n        history_tool_call_index = 0\n\n        # 按 _turn 分组普通 action\n        turns = OrderedDict()\n        \n        for action in self.action_history:\n            tool_name = action.get(\"tool_name\", \"\")\n            \n            # 特殊处理：历史摘要（压缩产物）\n            if tool_name == \"_historical_summary\":\n                messages.append({\n                    \"role\": \"user\",\n                    \"content\": f\"[Previous actions summary]\\n{action['result']['output']}\"\n                })\n                continue\n\n            if tool_name in {\"_react_reflection\", \"_assistant_text\"}:\n                assistant_content = action.get(\"assistant_content\", \"\") or action.get(\"result\", {}).get(\"output\", \"\")\n                if assistant_content:\n                    assistant_msg = {\"role\": \"assistant\", \"content\": assistant_content}\n                    if action.get(\"reasoning_content\"):\n                        assistant_msg[\"reasoning_content\"] = action[\"reasoning_content\"]\n                    messages.append(assistant_msg)\n                continue\n            \n            # 特殊处理：LLM 未调用工具\n            if tool_name == \"_no_tool_call\":\n                assistant_content = action.get(\"assistant_content\", \"\")\n                if assistant_content:\n                    messages.append({\"role\": \"assistant\", \"content\": assistant_content})\n                messages.append({\n                    \"role\": \"user\",\n                    \"content\": action[\"result\"].get(\"output\", \"请调用工具\")\n                })\n                continue\n            \n            # 普通 action - 按 _turn 分组\n            turn = action.get(\"_turn\", 0)  # 向后兼容：旧记录默认 turn=0\n            \n            if turn not in turns:\n                turns[turn] = {\n                    \"assistant_content\": action.get(\"assistant_content\", \"\"),\n                    \"reasoning_content\": action.get(\"reasoning_content\", \"\"),\n                    \"tool_calls\": [],\n                    \"tool_results\": [],\n                    \"images\": []\n                }\n            \n            # 构建 tool_call 条目\n            tool_call_id = action.get(\"tool_call_id\", f\"call_{turn}_{len(turns[turn]['tool_calls'])}\")\n            if use_kimi_history_tool_ids:\n                tool_call_id = self._format_kimi_history_tool_call_id(\n                    tool_name=action.get(\"tool_name\", \"\"),\n                    sequence_index=history_tool_call_index,\n                )\n            history_tool_call_index += 1\n            turns[turn][\"tool_calls\"].append({\n                \"id\": tool_call_id,\n                \"type\": \"function\",\n                \"function\": {\n                    \"name\": action[\"tool_name\"],\n                    \"arguments\": json.dumps(action[\"arguments\"], ensure_ascii=False)\n                }\n            })\n            \n            # 构建 tool result 消息\n            has_image = action.get(\"_has_image\", False)\n            has_base64 = bool(action.get(\"_image_base64\"))\n            \n            if has_image and has_base64:\n                # 有图片且有 base64 数据 → tool result 简短说明，图片在后续 user 消息中嵌入\n                result_content = \"Image loaded successfully. See below.\"\n            else:\n                # 无图片 或 有图片标记但 base64 丢失（Ctrl+C 恢复场景）→ 正常 JSON 结果\n                # 排除 _image_base64 等内部字段\n                result_clean = {k: v for k, v in action.get(\"result\", {}).items() \n                               if not k.startswith(\"_\")}\n                result_content = json.dumps(result_clean, ensure_ascii=False)\n            \n            turns[turn][\"tool_results\"].append({\n                \"role\": \"tool\",\n                \"tool_call_id\": tool_call_id,\n                \"content\": result_content\n            })\n            \n            # 收集图片数据（方案二：后续 user 消息嵌入）\n            # 只有同时有 _has_image 标记和实际 base64 数据时才嵌入图片\n            if has_image and has_base64:\n                query = action.get(\"arguments\", {}).get(\"query\", \"请分析这些图片\")\n                img_data = action[\"_image_base64\"]\n                # 兼容列表和单值\n                if isinstance(img_data, list):\n                    base64_list = img_data\n                else:\n                    base64_list = [img_data]\n                turns[turn][\"images\"].append({\n                    \"base64_list\": base64_list,\n                    \"query\": query\n                })\n        \n        # 从分组数据构建 messages\n        for turn_num in sorted(turns.keys()):\n            turn_data = turns[turn_num]\n            \n            # assistant 消息（包含 content、tool_calls、reasoning_content）\n            assistant_msg = {\n                \"role\": \"assistant\",\n                \"content\": turn_data[\"assistant_content\"] or None,\n                \"tool_calls\": turn_data[\"tool_calls\"]\n            }\n            # 如果有 reasoning_content，添加到 assistant 消息中\n            # LiteLLM 会将其传递给支持 thinking 的模型（如 Anthropic Claude）\n            if turn_data.get(\"reasoning_content\"):\n                assistant_msg[\"reasoning_content\"] = turn_data[\"reasoning_content\"]\n            messages.append(assistant_msg)\n            \n            # tool result 消息（每个 tool_call 对应一个）\n            messages.extend(turn_data[\"tool_results\"])\n            \n            # 图片消息（方案二：跟在 tool result 后面的 user 消息，多张图合并到一条消息）\n            for img_group in turn_data[\"images\"]:\n                content_parts = []\n                for b64 in img_group[\"base64_list\"]:\n                    image_url = b64 if b64.startswith(\"data:\") else f\"data:image/jpeg;base64,{b64}\"\n                    content_parts.append({\"type\": \"image_url\", \"image_url\": {\"url\": image_url}})\n                content_parts.append({\n                    \"type\": \"text\",\n                    \"text\": f\"上面是 image_read 获取的 {len(img_group['base64_list'])} 张图片。Agent 的问题是: {img_group['query']}\"\n                })\n                messages.append({\"role\": \"user\", \"content\": content_parts})\n        \n        return messages\n\n    def _should_normalize_kimi_history_tool_ids(self) -> bool:\n        model_name = str(getattr(self, \"execution_model\", \"\") or \"\").strip().lower()\n        if not model_name:\n            return False\n        return \"kimi-k2\" in model_name or (\"moonshot\" in model_name and \"kimi\" in model_name)\n\n    @staticmethod\n    def _format_kimi_history_tool_call_id(tool_name: str, sequence_index: int) -> str:\n        safe_tool_name = str(tool_name or \"\").strip() or \"tool\"\n        return f\"functions.{safe_tool_name}:{max(0, int(sequence_index))}\"\n    def _execute_llm_call(\n        self,\n        system_prompt: str,\n        messages: List[Dict] = None,\n        task_id: Optional[str] = None,\n        *,\n        tool_list: Optional[List[str]] = None,\n        tool_choice: Optional[str] = None,\n        debug_label: str = \"execution\",\n        stream_tokens: bool = True,\n    ):\n        \"\"\"\n        执行LLM调用并分发事件\n        \n        Args:\n            system_prompt: 系统提示词（不含历史动作）\n            messages: OpenAI 标准格式的 messages 数组（包含历史动作）\n        \"\"\"\n        if messages is None:\n            # 向后兼容：如果没有传 messages，使用简单的 user 消息\n            messages = [{\"role\": \"user\", \"content\": \"请输出下一个动作\"}]\n        \n        # 发送LLM调用开始事件\n        self.event_emitter.dispatch(LlmCallStartEvent(\n            model=self.execution_model, \n            system_prompt=system_prompt\n        ))\n        \n        effective_tool_list = list(self.available_tools if tool_list is None else tool_list)\n        execution_tool_choice = tool_choice or self.llm_client.resolve_tool_choice(\n            category=\"execution\",\n            model=self.execution_model,\n        )\n        max_tokens_override = self.agent_config.get(\"max_tokens\")\n        # 调用LLM（重试机制已在 llm_client 内部实现）\n        llm_response = self.llm_client.chat(\n            history=messages,\n            model=self.execution_model,\n            system_prompt=system_prompt,\n            tool_list=effective_tool_list,\n            tool_choice=execution_tool_choice,\n            max_tokens=max_tokens_override,\n            emit_tokens=\"token\",  # 主 Agent 调用：流式发送 content token\n            debug_task_id=task_id,\n            debug_label=debug_label,\n            stream_callback=self._build_llm_stream_callback(\n                stream_group=\"llm\",\n                agent_name=self.agent_name,\n                model=self.execution_model,\n            ) if self.stream_llm_tokens and stream_tokens else None,\n        )\n\n        llm_record = {\n            \"turn_index\": self.llm_turn_counter,\n            \"debug_label\": debug_label,\n            \"tool_choice\": execution_tool_choice,\n            \"model\": llm_response.model or self.execution_model,\n            \"content\": llm_response.output or \"\",\n            \"reasoning_content\": llm_response.reasoning_content or \"\",\n            \"finish_reason\": llm_response.finish_reason or \"\",\n            \"tool_calls\": [\n                {\n                    \"id\": tool_call.id,\n                    \"name\": tool_call.name,\n                    \"arguments\": tool_call.arguments,\n                }\n                for tool_call in (llm_response.tool_calls or [])\n            ],\n            \"status\": llm_response.status,\n        }\n        self.execution_traces.append(llm_record)\n        \n        self.event_emitter.dispatch(LlmCallEndEvent(\n            llm_output=llm_response.output, \n            tool_calls=llm_record[\"tool_calls\"],\n            model=llm_record[\"model\"],\n            reasoning_content=llm_record[\"reasoning_content\"],\n            finish_reason=llm_record[\"finish_reason\"],\n        ))\n        return llm_response\n\n    def _record_text_response(\n        self,\n        *,\n        tool_name: str,\n        text: str,\n        llm_turn: int,\n        reasoning_content: str = \"\",\n    ) -> None:\n        action_record = {\n            \"_turn\": llm_turn,\n            \"tool_name\": tool_name,\n            \"arguments\": {},\n            \"result\": {\n                \"status\": \"success\",\n                \"output\": text,\n            },\n            \"assistant_content\": text,\n            \"reasoning_content\": reasoning_content,\n            \"_has_image\": False,\n            \"_image_base64\": None,\n        }\n        fact_record = dict(action_record)\n        fact_record[\"_image_base64\"] = None\n        self.action_history_fact.append(fact_record)\n        self.action_history.append(action_record)\n\n    def _build_react_reflection_prompt(self) -> str:\n        tool_names = \", \".join(self.available_tools) if self.available_tools else \"(无可用工具)\"\n        return (\n            \"你当前处于 ReAct 反思阶段。请先简短输出当前进展、下一步最应该采取的动作、\"\n            \"以及是否需要使用 task_history_search 检索历史任务。\"\n            \"只输出纯文本思考，不要调用工具，不要输出 JSON/XML/markdown 标记。\"\n            f\"可用工具如下：{tool_names}\"\n        )\n\n    def _run_react_reflection(\n        self,\n        *,\n        task_id: str,\n        task_input: str,\n        system_prompt: str,\n        messages: List[Dict],\n        turn: int,\n    ) -> None:\n        reflection_messages = list(messages or [])\n        reflection_messages.append({\n            \"role\": \"user\",\n            \"content\": self._build_react_reflection_prompt(),\n        })\n        llm_response = self._execute_llm_call(\n            system_prompt,\n            reflection_messages,\n            task_id=task_id,\n            tool_list=[],\n            tool_choice=\"none\",\n            debug_label=\"react_reflection\",\n            stream_tokens=False,\n        )\n        if llm_response.status != \"success\":\n            raise Exception(llm_response.error_information or \"ReAct reflection failed\")\n        reflection_text = str(llm_response.output or \"\").strip()\n        if not reflection_text:\n            return\n        self._record_text_response(\n            tool_name=\"_react_reflection\",\n            text=reflection_text,\n            llm_turn=self.llm_turn_counter,\n            reasoning_content=llm_response.reasoning_content or \"\",\n        )\n        self.llm_turn_counter += 1\n        self._save_state(task_id, task_input, turn)\n        self.event_emitter.dispatch(CliDisplayEvent(\n            message=f\"🤔 ReAct反思已更新: {reflection_text[:160]}\",\n            style='info'\n        ))\n\n    def _execute_tool_call(self, tool_call: Dict, task_id: str, user_input: str, turn: int,\n                          assistant_content: str = \"\", reasoning_content: str = \"\",\n                          llm_turn: int = 0) -> Dict:\n        \"\"\"\n        执行单个工具调用并分发事件\n        \n        Args:\n            tool_call: 工具调用对象（包含 id, name, arguments）\n            task_id: 任务ID\n            user_input: 用户输入\n            turn: 当前执行轮次\n            assistant_content: 该轮 LLM 响应的文本内容（同轮所有 tool_call 共享）\n            reasoning_content: 该轮 LLM 响应的推理/思考内容（同轮所有 tool_call 共享）\n            llm_turn: LLM 调用轮次（用于消息分组）\n        \"\"\"\n        # ✅ 在保存 pending 之前，为 level != 0 的工具添加 uuid\n        arguments_with_uuid = self._add_uuid_if_needed(tool_call.name, tool_call.arguments)\n        \n        # ✅ 先标记为pending（保存带 uuid 的参数）\n        # 发送工具调用开始事件\n        self.event_emitter.dispatch(ToolCallStartEvent(\n            tool_name=tool_call.name, \n            arguments=arguments_with_uuid\n        ))\n\n        pending_tool = {\n            \"id\": tool_call.id,\n            \"name\": tool_call.name,\n            \"arguments\": arguments_with_uuid,\n            \"status\": \"pending\"\n        }\n        self.pending_tools.append(pending_tool)\n        self._save_state(task_id, user_input, turn)  # 保存pending状态\n\n        # 执行工具（使用带 uuid 的参数）\n        tool_result = self.tool_executor.execute(\n            tool_call.name,\n            arguments_with_uuid,\n            task_id\n        )\n\n        self._handle_special_tool_side_effects(\n            tool_name=tool_call.name,\n            tool_result=tool_result,\n            task_id=task_id,\n            user_input=user_input,\n            turn=turn\n        )\n\n        # ✅ 执行后从pending移除\n        self.pending_tools = [t for t in self.pending_tools if t[\"id\"] != tool_call.id]\n        \n        # 发送工具结果事件\n        self.event_emitter.dispatch(ToolCallEndEvent(\n            tool_name=tool_call.name, \n            status=tool_result.get('status', 'unknown'), \n            result=tool_result\n        ))\n\n        # 记录动作到历史（增强格式：包含消息重建所需的字段）\n        action_record = {\n            \"_turn\": llm_turn,\n            \"tool_call_id\": tool_call.id,\n            \"tool_name\": tool_call.name,\n            \"arguments\": arguments_with_uuid,\n            \"result\": tool_result,\n            \"assistant_content\": assistant_content,\n            \"reasoning_content\": reasoning_content,  # 模型的推理/思考内容\n            \"_has_image\": False,\n            \"_image_base64\": None\n        }\n        \n        # 处理 image_read 工具返回（无论 multimodal 设置如何，都要清理 base64）\n        if tool_call.name == \"image_read\":\n            image_base64_list = None\n            \n            # 工具执行层会把工具返回值 json.dumps 到 output 字符串中\n            # 所以 _image_base64_list 可能嵌套在 output 字符串里，需要解析提取\n            output_str = tool_result.get(\"output\", \"\")\n            if isinstance(output_str, str) and (\"_image_base64_list\" in output_str or \"_image_base64\" in output_str):\n                try:\n                    inner_result = json.loads(output_str)\n                    # 新格式：_image_base64_list（数组）\n                    image_base64_list = inner_result.get(\"_image_base64_list\")\n                    # 兼容旧格式：_image_base64（单值）→ 转为列表\n                    if not image_base64_list:\n                        single = inner_result.get(\"_image_base64\")\n                        if single:\n                            image_base64_list = [single]\n                    \n                    # 从 output 中移除所有 base64 数据\n                    inner_result.pop(\"_image_base64_list\", None)\n                    inner_result.pop(\"_image_base64\", None)\n                    inner_result.pop(\"_multimodal\", None)\n                    tool_result[\"output\"] = json.dumps(inner_result, indent=2, ensure_ascii=False)\n                    action_record[\"result\"] = tool_result\n                except (json.JSONDecodeError, TypeError):\n                    pass\n            \n            # 也检查顶层（以防未双重包装）\n            if not image_base64_list:\n                top_list = tool_result.get(\"_image_base64_list\")\n                top_single = tool_result.get(\"_image_base64\")\n                if top_list:\n                    image_base64_list = top_list\n                elif top_single:\n                    image_base64_list = [top_single]\n                tool_result.pop(\"_image_base64_list\", None)\n                tool_result.pop(\"_image_base64\", None)\n                tool_result.pop(\"_multimodal\", None)\n                action_record[\"result\"] = tool_result\n            \n            # 只有当主模型支持多模态时，才将图片嵌入 messages\n            if image_base64_list and self.llm_client.multimodal:\n                action_record[\"_has_image\"] = True\n                action_record[\"_image_base64\"] = image_base64_list  # 现在是列表\n        \n        # 添加到完整轨迹（永不压缩，但不存储 base64 以节省空间）\n        fact_record = {k: v for k, v in action_record.items() if k != \"_image_base64\"}\n        fact_record[\"_image_base64\"] = None  # fact 中不保留 base64，仅记录 _has_image 标志\n        self.action_history_fact.append(fact_record)\n\n        # 添加到渲染历史（会被压缩，保留 base64 用于 messages 重建）\n        self.action_history.append(action_record)\n\n        self.hierarchy_manager.add_action(self.agent_id, {\n            \"tool_name\": tool_call.name,\n            \"arguments\": arguments_with_uuid,\n            \"result\": {k: v for k, v in tool_result.items() if not k.startswith(\"_\")}\n        })\n\n        # 工具执行后保存状态\n        self._save_state(task_id, user_input, turn)\n        \n        # 增加工具调用计数\n        self.tool_call_counter += 1\n        \n        # 如果是final_output，返回结果\n        if tool_call.name == \"final_output\":\n            return tool_result\n        return None\n\n    def _handle_special_tool_side_effects(self, tool_name: str, tool_result: Dict, task_id: str, user_input: str, turn: int):\n        \"\"\"处理 load_skill / offload_skill / fresh 等特殊副作用。\"\"\"\n        if tool_name == \"load_skill\" and tool_result.get(\"status\") == \"success\":\n            skill_name = tool_result.get(\"_skill_name\")\n            if skill_name:\n                self.hierarchy_manager.add_loaded_skill(self.agent_id, {\n                    \"name\": skill_name,\n                    \"abs_path\": tool_result.get(\"_skill_abs_path\", \"\"),\n                    \"workspace_path\": tool_result.get(\"_workspace_skill_path\", \"\"),\n                    \"md_text\": tool_result.get(\"_skill_md_text\", \"\")\n                })\n            for k in [\"_skill_name\", \"_skill_abs_path\", \"_workspace_skill_path\", \"_skill_md_text\"]:\n                tool_result.pop(k, None)\n\n        elif tool_name == \"offload_skill\" and tool_result.get(\"status\") == \"success\":\n            skill_name = tool_result.get(\"_offload_skill_name\")\n            if skill_name:\n                self.hierarchy_manager.remove_loaded_skill(self.agent_id, skill_name)\n            tool_result.pop(\"_offload_skill_name\", None)\n\n        elif tool_name == \"fresh\" and tool_result.get(\"_fresh_requested\"):\n            reason = tool_result.get(\"_fresh_reason\") or \"manual fresh requested\"\n            target_task_id = str(tool_result.get(\"_fresh_task_id\") or \"\").strip() or task_id\n            if target_task_id == task_id:\n                ok, msg = self._perform_fresh(task_id, user_input, turn, reason)\n            elif is_task_running(target_task_id):\n                request_fresh(reason=reason, task_id=target_task_id)\n                ok = True\n                msg = f\"已向运行中的任务发送 fresh 请求: {target_task_id}\"\n            else:\n                ok, msg = resume_task_with_fresh(\n                    task_id=target_task_id,\n                    reason=reason,\n                    fallback_agent_system=self.config_loader.agent_system_name,\n                    direct_tools=self.direct_tools,\n                )\n            if ok:\n                tool_result[\"output\"] = f\"{tool_result.get('output', '').strip()}\\n\\n{msg}\".strip()\n            else:\n                tool_result[\"status\"] = \"error\"\n                tool_result[\"error\"] = msg\n                tool_result[\"output\"] = \"\"\n            tool_result.pop(\"_fresh_requested\", None)\n            tool_result.pop(\"_fresh_reason\", None)\n            tool_result.pop(\"_fresh_task_id\", None)\n\n    def _maybe_run_scheduled_fresh(self, task_id: str, user_input: str, turn: int):\n        external_reason = pop_fresh_request(task_id)\n        if external_reason:\n            self._perform_fresh(task_id, user_input, turn, external_reason)\n            return\n        if not self.fresh_enabled or self.fresh_interval_sec <= 0:\n            return\n        if time.time() - self.last_fresh_at < self.fresh_interval_sec:\n            return\n        self._perform_fresh(task_id, user_input, turn, \"scheduled fresh\")\n\n    def _perform_fresh(self, task_id: str, user_input: str, turn: int, reason: str):\n        \"\"\"\n        在安全点刷新运行时配置/注册表/skill缓存，并继续当前任务。\n        \"\"\"\n        if has_running_background_processes(task_id):\n            return False, \"当前仍有后台工具在运行，暂不允许 fresh。请等待后台工具结束后再刷新。\"\n\n        self.event_emitter.dispatch(CliDisplayEvent(\n            message=f\"🔄 Fresh 开始: {reason}\",\n            style='info'\n        ))\n\n        apply_runtime_env_defaults()\n        reset_skill_loader()\n        reload_runtime_registry()\n        reload_mcp_tools()\n\n        # 重新读取运行时参数\n        runtime = get_runtime_settings()\n        self.thinking_enabled = bool(self.agent_config.get(\"thinking_enabled\", runtime.get(\"thinking_enabled\", True)))\n        self.thinking_steps = int(\n            self.agent_config.get(\"thinking_steps\")\n            or runtime.get(\"thinking_steps\", runtime.get(\"thinking_interval\", runtime.get(\"action_window_steps\", 30)))\n        )\n        self.action_window_steps = self.thinking_steps\n        self.thinking_interval = self.thinking_steps\n        self.no_tool_retry_limit = int(\n            self.agent_config.get(\"no_tool_retry_limit\")\n            or runtime.get(\"no_tool_retry_limit\", 7)\n        )\n        self.fresh_enabled = runtime.get(\"fresh_enabled\", False)\n        self.fresh_interval_sec = runtime.get(\"fresh_interval_sec\", 0)\n        self.last_fresh_at = time.time()\n\n        # 重新加载 config_loader / agent_config / llm_client / context_builder / tool_executor\n        loader_cls = self.config_loader.__class__\n        self.config_loader = loader_cls(self.config_loader.agent_system_name)\n        self.agent_config = self.config_loader.get_tool_config(self.agent_name)\n        self.available_tools = list(self.agent_config.get(\"available_tools\", []))\n        if \"task_history_search\" not in self.available_tools and \"task_history_search\" in self.config_loader.all_tools:\n            self.available_tools.append(\"task_history_search\")\n        self._inject_mcp_tools()\n\n        self.llm_client = SimpleLLMClient()\n        self.llm_client.set_tools_config(self.config_loader.all_tools)\n        requested_model = self._get_agent_model_preference(\"execution\")\n        self.execution_model = self.llm_client.resolve_model(\"execution\", requested_model)\n        self.model_type = self.execution_model\n\n        self.context_builder = ContextBuilder(\n            self.hierarchy_manager,\n            agent_config=self.agent_config,\n            config_loader=self.config_loader,\n            llm_client=self.llm_client,\n            max_context_window=self.llm_client.max_context_window\n        )\n        self.tool_executor = ToolExecutor(\n            self.config_loader,\n            self.hierarchy_manager,\n            direct_mode=self.direct_tools,\n            extra_event_handlers=self.extra_event_handlers,\n            exit_on_error=self.exit_on_error,\n            raise_on_error=self.raise_on_error,\n        )\n        self.tool_executor.set_agent_context(agent_id=self.agent_id, agent_name=self.agent_name)\n        if hasattr(self, \"action_compressor\"):\n            delattr(self, \"action_compressor\")\n\n        self._save_state(task_id, user_input, turn)\n        self.event_emitter.dispatch(CliDisplayEvent(\n            message=f\"✅ Fresh 完成，已重载配置/工具注册/skills 缓存，并继续当前任务\",\n            style='success'\n        ))\n        return True, \"Fresh 完成，已重载配置/工具注册/skills 缓存，并继续当前任务。\"\n\n    def _handle_execution_error(self, e: Exception) -> Dict:\n        \"\"\"统一处理执行过程中的异常\"\"\"\n        # 获取详细错误信息\n        error_type = type(e).__name__\n        error_msg = str(e)\n        error_traceback = traceback.format_exc()\n        \n        # 构建友好的错误提示消息\n        error_display = f\"\"\"\n❌ 执行过程中发生错误，任务已中断\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔴 错误类型: {error_type}\n📝 错误信息: {error_msg}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n📋 详细堆栈:\n{error_traceback}\n\"\"\"\n        \n        # 添加当前进度信息\n        if self.latest_thinking:\n            error_display += f\"\\n💭 当前进度:\\n{self.latest_thinking[:500]}\\n\"\n        \n        error_display += \"\"\"\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n💡 任务已保存在当前状态，请:\n   1. 根据错误信息排查问题（修复网络、配置等）\n   2. 重新启动 CLI 并输入 /resume 命令恢复任务\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\"\"\"\n        error_result = {\n            \"status\": \"error\",\n            \"task_id\": self.current_task_id,\n            \"agent_name\": self.agent_name,\n            \"output\": \"\",\n            \"error_type\": error_type,\n            \"error_message\": error_msg,\n            \"error_information\": error_display,\n            \"latest_thinking\": self.latest_thinking,\n        }\n        error_result = self._with_model_outputs(error_result)\n        # 通过事件发送错误\n        self.event_emitter.dispatch(ErrorEvent(error_display=error_display))\n        self.event_emitter.dispatch(AgentEndEvent(status='error', result=error_result))\n        if self.raise_on_error:\n            raise InfiAgentRunError.from_result(\n                error_result,\n                task_id=self.current_task_id or \"\",\n                agent_name=self.agent_name,\n                stage=\"run\",\n            )\n        if self.exit_on_error:\n            sys.exit(1)\n        return error_result\n\n    def _add_uuid_if_needed(\n            self, \n            tool_name: str, \n            arguments: Dict\n        ) -> Dict:\n        \"\"\"\n        为 level != 0 的工具添加 uuid 后缀到 task_input\n        \n        Args:\n            tool_name: 工具名称\n            arguments: 原始参数\n            \n        Returns:\n            处理后的参数（如果需要添加 uuid，返回新字典；否则返回原字典）\n        \"\"\"\n        try:\n            # 获取工具配置\n            tool_config = self.config_loader.get_tool_config(tool_name)\n            tool_level = tool_config.get(\"level\", 0)\n            tool_type = tool_config.get(\"type\", \"\")\n            \n            # 只对 level != 0 的 llm_call_agent 添加 uuid\n            if tool_type == \"llm_call_agent\" and tool_level != 0 and \"task_input\" in arguments:\n                import uuid\n                # 创建新字典（避免修改原始参数）\n                new_arguments = arguments.copy()\n                original_input = arguments[\"task_input\"]\n                random_suffix = f\" [call-{uuid.uuid4().hex[:8]}]\"\n                new_arguments[\"task_input\"] = original_input + random_suffix\n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"   🔖 为 level {tool_level} 工具添加 uuid 后缀\", \n                    style='info'\n                ))\n                return new_arguments\n            \n            # 其他情况返回原参数\n            return arguments\n        \n        except Exception as e:\n            self.event_emitter.dispatch(CliDisplayEvent(\n                message=f\"⚠️ 添加 uuid 时出错: {e}\", \n                style='warning'\n            ))\n            return arguments\n    \n    def _trigger_thinking(self, task_id: str, task_input: str, is_initial: bool = False, is_forced: bool = False) -> str:\n        \"\"\"\n        触发Thinking Agent进行分析\n        \n        Args:\n            task_id: 任务ID\n            task_input: 任务输入\n            is_initial: 是否是首次thinking\n            is_forced: 是否因为多次未调用工具而被强制触发thinking\n            \n        Returns:\n            分析结果\n        \"\"\"\n        # 发送Thinking开始事件\n        self.event_emitter.dispatch(ThinkingStartEvent(\n            agent_name=self.agent_name, \n            is_initial=is_initial, \n            is_forced=is_forced\n        ))\n        try:\n            from services.thinking_agent import ThinkingAgent\n\n            thinking_agent = ThinkingAgent(\n                preferred_model=self._get_agent_model_preference(\"thinking\"),\n                max_tokens=self.agent_config.get(\"max_tokens\"),\n            )\n\n            # 构建完整的系统提示词（包含历史动作XML，供 thinking agent 分析）\n            full_system_prompt = self.context_builder.build_context(\n                task_id,\n                self.agent_id,\n                self.agent_name,\n                task_input,\n                action_history=self.action_history,\n                include_action_history=True  # thinking agent 需要看到历史动作\n            )\n            thinking_payload = thinking_agent.analyze_first_thinking_detail(\n                task_description=task_input,\n                agent_system_prompt=full_system_prompt,\n                available_tools=self.available_tools,\n                tools_config=self.config_loader.all_tools,\n                action_history=self.action_history,  # 传递 action_history（含图片数据）\n                multimodal=self.llm_client.multimodal,  # 传递多模态标志\n                debug_task_id=task_id,\n                stream_callback=self._build_llm_stream_callback(\n                    stream_group=\"thinking\",\n                    agent_name=self.agent_name,\n                    model=thinking_agent.llm_client.resolve_model(\"thinking\", thinking_agent.preferred_model),\n                    is_initial=is_initial,\n                    is_forced=is_forced,\n                ) if self.stream_llm_tokens else None,\n            )\n            result = thinking_payload[\"formatted_result\"]\n            thinking_record = {\n                \"model\": thinking_payload.get(\"model\", \"\"),\n                \"content\": thinking_payload.get(\"raw_output\", \"\"),\n                \"reasoning_content\": thinking_payload.get(\"raw_reasoning_content\", \"\"),\n                \"formatted_result\": result,\n                \"finish_reason\": thinking_payload.get(\"finish_reason\", \"\"),\n                \"status\": thinking_payload.get(\"status\", \"success\"),\n                \"is_initial\": bool(is_initial),\n                \"is_forced\": bool(is_forced),\n            }\n            self.thinking_traces.append(thinking_record)\n            # 发送 thinking 事件（完整内容）\n            self.event_emitter.dispatch(ThinkingEndEvent(\n                agent_name=self.agent_name, \n                result=result,\n                model=thinking_record[\"model\"],\n                raw_output=thinking_record[\"content\"],\n                raw_reasoning_content=thinking_record[\"reasoning_content\"],\n                finish_reason=thinking_record[\"finish_reason\"],\n                is_initial=is_initial,\n                is_forced=is_forced\n            ))\n            return result\n        except Exception as e:\n            error_msg = str(e)\n            # 发送Thinking失败事件\n            self.event_emitter.dispatch(ThinkingFailEvent(\n                agent_name=self.agent_name, \n                error_message=error_msg\n            ))\n            raise Exception(str(e))\n\n    def _build_llm_stream_callback(\n        self,\n        *,\n        stream_group: str,\n        agent_name: str,\n        model: str,\n        is_initial: bool = False,\n        is_forced: bool = False,\n    ):\n        def _callback(chunk: Dict[str, Any]):\n            kind = str((chunk or {}).get(\"kind\") or \"content\").strip().lower()\n            text = str((chunk or {}).get(\"text\") or \"\")\n            attempt = int((chunk or {}).get(\"attempt\") or 1)\n            if kind == \"reset\":\n                event_type = \"run.thinking.reset\" if stream_group == \"thinking\" else \"run.llm.reset\"\n                payload = {\n                    \"agent_name\": agent_name,\n                    \"model\": str((chunk or {}).get(\"model\") or model or \"\"),\n                    \"attempt\": attempt,\n                    \"reason\": str((chunk or {}).get(\"reason\") or \"retry\"),\n                }\n                self._emit_sdk_stream_event(event_type, payload)\n                return\n            if not text:\n                return\n            current_model = str((chunk or {}).get(\"model\") or model or \"\")\n            if stream_group == \"thinking\":\n                event_type = \"run.thinking.reasoning_token\" if kind == \"reasoning\" else \"run.thinking.token\"\n                payload = {\n                    \"agent_name\": agent_name,\n                    \"model\": current_model,\n                    \"text\": text,\n                    \"token_kind\": kind,\n                    \"attempt\": attempt,\n                    \"is_initial\": bool(is_initial),\n                    \"is_forced\": bool(is_forced),\n                }\n            else:\n                event_type = \"run.llm.reasoning_token\" if kind == \"reasoning\" else \"run.llm.token\"\n                payload = {\n                    \"agent_name\": agent_name,\n                    \"model\": current_model,\n                    \"text\": text,\n                    \"token_kind\": kind,\n                    \"attempt\": attempt,\n                }\n            self._emit_sdk_stream_event(event_type, payload)\n\n        return _callback\n\n    def _build_model_outputs_payload(self) -> Dict[str, Any]:\n        execution_traces = list(getattr(self, \"execution_traces\", []) or [])\n        thinking_traces = list(getattr(self, \"thinking_traces\", []) or [])\n        execution_only = [item for item in execution_traces if str(item.get(\"debug_label\") or \"execution\") == \"execution\"]\n        last_execution = execution_only[-1] if execution_only else (execution_traces[-1] if execution_traces else None)\n        last_thinking = thinking_traces[-1] if thinking_traces else None\n        return {\n            \"execution_turns\": execution_traces,\n            \"thinking_turns\": thinking_traces,\n            \"last_execution\": last_execution,\n            \"last_thinking\": last_thinking,\n        }\n\n    def _with_model_outputs(self, result: Dict[str, Any]) -> Dict[str, Any]:\n        payload = dict(result or {})\n        model_outputs = self._build_model_outputs_payload()\n        payload[\"model_outputs\"] = model_outputs\n\n        last_execution = model_outputs.get(\"last_execution\") or {}\n        last_thinking = model_outputs.get(\"last_thinking\") or {}\n\n        payload[\"last_execution_output\"] = str(last_execution.get(\"content\") or \"\")\n        payload[\"last_execution_reasoning_content\"] = str(last_execution.get(\"reasoning_content\") or \"\")\n        payload[\"last_execution_model\"] = str(last_execution.get(\"model\") or \"\")\n        payload[\"last_thinking_output\"] = str(last_thinking.get(\"content\") or \"\")\n        payload[\"last_thinking_reasoning_content\"] = str(last_thinking.get(\"reasoning_content\") or \"\")\n        payload[\"last_thinking_model\"] = str(last_thinking.get(\"model\") or \"\")\n        return payload\n\n    def _compress_action_history_if_needed(self):\n        \"\"\"检查并压缩历史动作（如果超过上下文窗口限制）\"\"\"\n        if not self.action_history:\n            return\n        \n        try:\n            from services.action_compressor import ActionCompressor\n\n            # 初始化压缩器（如果还没有）\n            if not hasattr(self, 'action_compressor'):\n                self.action_compressor = ActionCompressor(\n                    self.llm_client,\n                    preferred_model=self._get_agent_model_preference(\"compressor\"),\n                    max_tokens=self.agent_config.get(\"max_tokens\"),\n                    debug_task_id=self.current_task_id,\n                )\n            else:\n                self.action_compressor.debug_task_id = self.current_task_id\n            \n            # 使用新的压缩策略（传入 thinking 和 task_input）\n            original_len = len(self.action_history)\n            compressed = self.action_compressor.compress_if_needed(\n                self.action_history,\n                self.llm_client.max_context_window,\n                thinking=self.latest_thinking,\n                task_input=self.current_task_input\n            )\n\n            # 如果发生了压缩，替换\n            if len(compressed) < original_len:\n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"✅ 历史动作已压缩: {original_len}条 → {len(compressed)}条\", \n                    style='success'\n                ))\n                self.action_history = compressed\n        except Exception as e:\n            self.event_emitter.dispatch(CliDisplayEvent(\n                message=f\"⚠️ 压缩失败: {e}\", \n                style='warning'\n            ))\n            traceback.print_exc()\n    \n    def _recover_pending_tools(self, task_id: str):\n        \"\"\"恢复pending状态的工具调用\"\"\"\n        for pending_tool in self.pending_tools:\n            tool_name, tool_args = pending_tool['name'], pending_tool['arguments']\n            try:\n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"   🔄 恢复执行: {tool_name}\\n   📋 参数: {tool_args}\", \n                    style='info'\n                ))\n                \n                # 重新执行工具\n                tool_result = self.tool_executor.execute(\n                    tool_name,\n                    tool_args,\n                    task_id\n                )\n                \n                # 记录结果\n                action_record = {\n                    \"tool_name\": tool_name,\n                    \"arguments\": tool_args,\n                    \"result\": tool_result\n                }\n                \n                self.action_history_fact.append(action_record)\n                self.action_history.append(action_record)\n                \n                # 从pending移除\n                self.pending_tools.remove(pending_tool)\n                \n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"   ✅ 恢复完成: {tool_name}\", \n                    style='success'\n                ))\n                \n                # 如果是final_output，直接返回\n                if tool_name == \"final_output\":\n                    return tool_result\n            except Exception as e:\n                self.event_emitter.dispatch(CliDisplayEvent(\n                    message=f\"   ❌ 恢复失败: {tool_name} - {e}\", \n                    style='error'\n                ))\n        # 清空pending列表\n        self.pending_tools = []\n    \n    def _save_state(self, task_id: str, user_input: str, current_turn: int):\n        \"\"\"\n        保存当前状态\n        \n        Args:\n            task_id: 任务ID\n            user_input: 用户输入\n            current_turn: 当前轮次\n        \"\"\"\n        # 构建完整的系统提示词（包含历史动作XML，用于调试/参考）\n        full_system_prompt = self.context_builder.build_context(\n            task_id,\n            self.agent_id,\n            self.agent_name,\n            user_input,\n            action_history=self.action_history,\n            include_action_history=True  # 保存时包含完整上下文\n        )\n\n        # 保存状态\n        self.conversation_storage.save_actions(\n            task_id=task_id,\n            agent_id=self.agent_id,\n            agent_name=self.agent_name,\n            task_input=user_input,\n            action_history=self.action_history,  # 渲染用（会压缩，含 base64）\n            action_history_fact=self.action_history_fact,  # 完整轨迹（不含 base64）\n            pending_tools=self.pending_tools,\n            current_turn=current_turn,\n            latest_thinking=self.latest_thinking,\n            first_thinking_done=self.first_thinking_done,\n            tool_call_counter=self.tool_call_counter,\n            llm_turn_counter=self.llm_turn_counter,\n            system_prompt=full_system_prompt\n        )\n\n\nif __name__ == \"__main__\":\n    from utils.config_loader import ConfigLoader\n    from core.hierarchy_manager import get_hierarchy_manager\n    \n    # 测试\n    config_loader = ConfigLoader(\"infiHelper\")\n    hierarchy_manager = get_hierarchy_manager(\"test_task\")\n\n    hierarchy_manager.start_new_instruction(\"测试任务\")\n\n    # 获取writing_agent配置\n    agent_config = config_loader.get_tool_config(\"alpha_agent\")\n\n    safe_print(f\"✅ Agent配置: {agent_config.get('name')}\")\n    safe_print(f\"   Tools: {len(agent_config.get('available_tools', []))}\")\n"
  },
  {
    "path": "core/context_builder.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n上下文构造器 - 构建新的XML结构化上下文\n\"\"\"\n\nfrom typing import Dict, List, Optional\nimport json\nimport os\nfrom pathlib import Path\n\nfrom utils.context_hooks import apply_context_hooks\nfrom utils.user_paths import get_context_settings, get_user_conversations_dir, get_user_skills_library_root\n\n\nclass ContextBuilder:\n    \"\"\"构建XML结构化的Agent上下文（完整）\"\"\"\n    \n    def __init__(self, hierarchy_manager, agent_config: Dict, config_loader, llm_client=None, max_context_window=100000):\n        \"\"\"\n        初始化上下文构造器\n        \n        Args:\n            hierarchy_manager: 层级管理器实例\n            agent_config: Agent配置（包含prompts）\n            config_loader: 配置加载器（用于读取general_prompts）\n            llm_client: LLM客户端（用于压缩总结）\n            max_context_window: 最大上下文窗口\n        \"\"\"\n        self.hierarchy_manager = hierarchy_manager\n        self.agent_config = agent_config\n        self.config_loader = config_loader\n        self.current_action_history = []  # 当前Agent的动作历史（从外部传入）\n        self.llm_client = llm_client\n        self.max_context_window = max_context_window\n        \n        # 初始化 Skill 加载器\n        try:\n            from utils.skill_loader import get_skill_loader\n            self.skill_loader = get_skill_loader()\n        except Exception:\n            self.skill_loader = None\n        \n        # 初始化tiktoken\n        try:\n            import tiktoken\n            self.encoding = tiktoken.get_encoding(\"cl100k_base\")\n        except ImportError:\n            self.encoding = None\n\n    def _resolve_compressor_model(self) -> str:\n        preferred = str(self.agent_config.get(\"compressor_model\") or \"\").strip() or None\n        return self.llm_client.resolve_model(\"compressor\", preferred)\n\n    def _resolve_compressor_tool_choice(self, model: str) -> str:\n        return self.llm_client.resolve_tool_choice(\"compressor\", model)\n\n    def _build_task_system_add(self, task_id: str) -> str:\n        try:\n            system_add_path = Path(task_id) / \"system-add.md\"\n            if not system_add_path.exists():\n                return \"\"\n            content = system_add_path.read_text(encoding=\"utf-8\").strip()\n            if not content:\n                return \"\"\n            return f\"<任务级补充系统提示>\\n{content}\\n</任务级补充系统提示>\"\n        except Exception:\n            return \"\"\n\n    def _count_tokens(self, text: str) -> int:\n        text = str(text or \"\")\n        if self.encoding:\n            return len(self.encoding.encode(text))\n        chinese_chars = sum(1 for c in text if '\\u4e00' <= c <= '\\u9fff')\n        other_chars = len(text) - chinese_chars\n        return int(chinese_chars / 1.5 + other_chars / 4)\n    \n    def build_context(self, task_id: str, agent_id: str, agent_name: str, task_input: str, \n                     action_history: List[Dict] = None,\n                     include_action_history: bool = True) -> str:\n        \"\"\"\n        构建完整的系统提示词（包含通用部分+动态上下文）\n        \n        Args:\n            task_id: 任务ID（用于读取文件）\n            agent_id: 当前Agent ID\n            agent_name: 当前Agent名称\n            task_input: 当前Agent的任务输入\n            action_history: 当前Agent的动作历史（可选，优先使用）\n            include_action_history: 是否在系统提示词中包含历史动作（默认True）\n                                   主LLM调用时传False（历史动作改由messages承载），\n                                   thinking/compression调用时传True（保持原有XML格式）\n            \n        Returns:\n            完整的XML结构化上下文字符串（包含通用提示词）\n        \"\"\"\n        context_data = self.hierarchy_manager.get_context()\n        current = context_data.get(\"current\", {})\n        history = context_data.get(\"history\", [])\n        \n        # 使用传入的action_history\n        if action_history is not None:\n            self.current_action_history = action_history\n        \n        # 1️⃣ 读取通用系统提示词（general_prompts.yaml，包含<智能体经验>）\n        general_system_prompt = self._load_general_system_prompt(agent_name)\n        task_system_add = self._build_task_system_add(task_id)\n        \n        # 2️⃣ 构建各个动态部分\n        user_latest_input = self._build_user_latest_input(current)\n        user_agent_history = self._build_user_agent_history(task_id, current)\n        visible_history, visible_history_count, total_history_count = self._select_user_history_entries(history)\n        history_search_hint = self._build_task_history_search_hint(visible_history_count, total_history_count)\n        structured_call_info = self._build_structured_call_info(current, agent_id, task_id)\n        current_thinking = self._build_current_thinking(task_id, agent_id, current)\n        workspace_abs_path = task_id\n        skills_root_abs_path = str(get_user_skills_library_root())\n        runtime_meta = context_data.get(\"runtime\", {})\n        visible_skills = None\n        if isinstance(runtime_meta, dict):\n            raw_visible = runtime_meta.get(\"visible_skills\")\n            if isinstance(raw_visible, list):\n                visible_skills = [str(item).strip() for item in raw_visible if str(item).strip()]\n        if visible_skills is None:\n            env_json = os.environ.get(\"MLA_VISIBLE_SKILLS_JSON\", \"\").strip()\n            if env_json:\n                try:\n                    parsed = json.loads(env_json)\n                    if isinstance(parsed, list):\n                        visible_skills = [str(item).strip() for item in parsed if str(item).strip()]\n                except Exception:\n                    visible_skills = None\n        \n        # 2.5️⃣ 构建可用 skills 列表（如果有）\n        available_skills_xml = \"\"\n        if self.skill_loader:\n            try:\n                available_skills_xml = self.skill_loader.build_available_skills_xml(visible_skill_names=visible_skills)\n            except Exception:\n                pass\n\n        loaded_skills_xml = self._build_loaded_skills_xml(agent_id)\n        \n        # 3️⃣ 组装完整上下文（通用部分在最前面）\n        full_context = f\"\"\"{general_system_prompt}\n\n{task_system_add}\n<用户最新输入>\n{user_latest_input}\n</用户最新输入>\n\n<用户-智能体历史交互>\n{user_agent_history}\n</用户-智能体历史交互>\n\n<历史任务检索提示>\n{history_search_hint}\n</历史任务检索提示>\n\n<当前运行智能体名称>\n{agent_name}\n</当前运行智能体名称>\n\n<当前工作空间绝对路径>\n{workspace_abs_path}\n</当前工作空间绝对路径>\n\n<当前可见Skills目录绝对路径>\n{skills_root_abs_path}\n</当前可见Skills目录绝对路径>\n\n<结构化调用信息>\n{structured_call_info}\n</结构化调用信息>\n\n<当前智能体任务>\n{task_input}\n</当前智能体任务>\n\n<当前进度思考>\n{current_thinking}\n</当前进度思考>\n\"\"\"\n        \n        # 3.5️⃣ 可选：包含可用 skills（仅当有 skills 时）\n        if available_skills_xml:\n            full_context += f\"\\n{available_skills_xml}\\n\"\n\n        if loaded_skills_xml:\n            full_context += f\"\\n{loaded_skills_xml}\\n\"\n        \n        # 4️⃣ 可选：包含历史动作（thinking/compression时包含，主LLM调用时不包含）\n        if include_action_history:\n            action_history_xml = self._build_action_history(task_id, agent_id)\n            full_context += f\"\"\"\n<历史动作>\n{action_history_xml}\n</历史动作>\n\"\"\"\n        \n        return apply_context_hooks(\n            stage=\"after_build\",\n            task_id=task_id,\n            agent_id=agent_id,\n            agent_name=agent_name,\n            task_input=task_input,\n            context_data=context_data,\n            context_text=full_context,\n        )\n\n    def _select_user_history_entries(self, history: List[Dict]) -> tuple[List[Dict], int, int]:\n        if not isinstance(history, list) or not history:\n            return [], 0, 0\n        settings = get_context_settings()\n        recent_items = settings.get(\"user_history_recent_items\", 0)\n        if recent_items and recent_items > 0:\n            selected = history[-recent_items:]\n        else:\n            selected = history\n        return selected, len(selected), len(history)\n\n    def _build_task_history_search_hint(self, visible_count: int, total_count: int) -> str:\n        if total_count <= 0:\n            return \"当前没有历史交互记录。\"\n        return (\n            f\"你现在能看到最近{visible_count}条历史交互信息，总交互信息有{total_count}条。\"\n            \"如果当前提供的历史信息不足以涵盖本次任务的相关历史，请使用 task_history_search 工具进行检索。\"\n        )\n\n    def _build_loaded_skills_xml(self, agent_id: str) -> str:\n        \"\"\"构建当前已加载 skill 的注入内容。\"\"\"\n        try:\n            loaded_skills = self.hierarchy_manager.get_loaded_skills(agent_id)\n        except Exception:\n            loaded_skills = []\n\n        if not loaded_skills:\n            return \"\"\n\n        parts = [\"<已加载技能内容>\"]\n        for skill in loaded_skills:\n            parts.append(f'  <skill name=\"{skill.get(\"name\", \"\")}\">')\n            if skill.get(\"abs_path\"):\n                parts.append(f'    <absolute_path>{skill[\"abs_path\"]}</absolute_path>')\n            if skill.get(\"workspace_path\"):\n                parts.append(f'    <workspace_path>{skill[\"workspace_path\"]}</workspace_path>')\n            parts.append(\"    <skill_md>\")\n            parts.append(str(skill.get(\"md_text\", \"\")).strip())\n            parts.append(\"    </skill_md>\")\n            parts.append(\"  </skill>\")\n        parts.append(\"</已加载技能内容>\")\n        return \"\\n\".join(parts)\n    \n    def _load_general_system_prompt(self, agent_name: str) -> str:\n        \"\"\"\n        读取并格式化通用系统提示词（包含<智能体经验>）\n        \n        Args:\n            agent_name: Agent名称\n            \n        Returns:\n            格式化后的通用系统提示词（XML格式）\n        \"\"\"\n        # 读取general_prompts.yaml\n        import yaml\n        from pathlib import Path\n        \n        # Use the resolved agent system directory from ConfigLoader.\n        # This supports both bundled systems and user-imported systems\n        # under ~/mla_v3/agent_library/<system>/.\n        prompts_file = Path(self.config_loader.agent_config_dir) / \"general_prompts.yaml\"\n        \n        if not prompts_file.exists():\n            return \"\"\n        \n        with open(prompts_file, 'r', encoding='utf-8') as f:\n            data = yaml.safe_load(f)\n            system_prompt_xml = data.get(\"system_prompt_xml\", \"\")\n        \n        # 格式化变量\n        prompts = self.agent_config.get(\"prompts\", {})\n        agent_responsibility = prompts.get(\"agent_responsibility\", \"完成分配的任务\")\n        agent_workflow = prompts.get(\"agent_workflow\", \"(无特定流程)\")\n        \n        return system_prompt_xml.format(\n            agent_name=agent_name,\n            agent_responsibility=agent_responsibility,\n            agent_workflow=agent_workflow\n        )\n    \n    def _build_user_latest_input(self, current: Dict) -> str:\n        \"\"\"构建用户最新输入部分\"\"\"\n        instructions = current.get(\"instructions\", [])\n        if not instructions:\n            return \"(无)\"\n        \n        # 返回所有指令（按时间顺序）\n        result = []\n        for i, instr in enumerate(instructions, 1):\n            instruction_text = instr.get(\"instruction\", \"\")\n            start_time = instr.get(\"start_time\", \"\")\n            source = str(instr.get(\"source\") or \"user\").strip()\n            result.append(f\"{i}. [{source}] {instruction_text} (开始时间: {start_time})\")\n        \n        return \"\\n\".join(result)\n    \n    def _build_user_agent_history(self, task_id: str, current: Dict = None) -> str:\n        \"\"\"\n        检查并压缩用户-智能体历史交互（只在启动时执行一次）\n        \n        Args:\n            task_id: 任务ID\n            current: 当前任务数据（包含用户输入）\n        \n        Returns:\n            压缩后的历史交互文本（已包含<用户-智能体历史交互>标签）\n        \"\"\"\n        context = self.hierarchy_manager.get_context()\n        if current is None:\n            current = context.get(\"current\", {})\n        history = context.get(\"history\", [])\n        \n        if not history:\n            return \"(无历史交互)\"\n        try:\n            from utils.task_history_index import sync_task_history_from_context\n            sync_task_history_from_context(task_id, context)\n        except Exception:\n            pass\n\n        selected_history, visible_count, total_count = self._select_user_history_entries(history)\n        compressed_history = current.get(\"_compressed_user_agent_history\")\n        compressed_meta = current.get(\"_compressed_user_agent_history_meta\") or {}\n        settings = get_context_settings()\n        threshold_tokens = settings.get(\"user_history_compress_threshold_tokens\", 1500)\n        recent_items = settings.get(\"user_history_recent_items\", 0)\n        if (\n            compressed_history\n            and compressed_meta.get(\"recent_items\") == recent_items\n            and compressed_meta.get(\"threshold_tokens\") == threshold_tokens\n            and compressed_meta.get(\"visible_count\") == visible_count\n            and compressed_meta.get(\"total_count\") == total_count\n        ):\n            safe_print(\"使用已有的压缩历史交互\")\n            return compressed_history\n\n        history_tokens = self._count_tokens(json.dumps(selected_history, ensure_ascii=False))\n        safe_print(\"未到历史交互压缩阈值\")\n        if history_tokens < threshold_tokens:\n            return str(selected_history)\n        \n        # 提取当前任务的用户输入\n        current_task = \"\"\n        instructions = current.get(\"instructions\", [])\n        if instructions:\n            # 将所有用户输入拼接起来\n            user_inputs = [instr.get(\"instruction\", \"\") for instr in instructions]\n            current_task = \"\\n\".join(user_inputs)\n        \n        safe_print(\"首次压缩历史交互...\")\n        compressed_result = self._compress_user_agent_history_with_llm(selected_history, task_id, current_task)\n        \n        context[\"current\"][\"_compressed_user_agent_history\"] = compressed_result\n        context[\"current\"][\"_compressed_user_agent_history_meta\"] = {\n            \"recent_items\": recent_items,\n            \"threshold_tokens\": threshold_tokens,\n            \"visible_count\": visible_count,\n            \"total_count\": total_count,\n        }\n        self.hierarchy_manager._save_context(context)\n        \n        return compressed_result\n    \n    def _compress_user_agent_history_with_llm(self, history: List[Dict], task_id: str, current_task: str = \"\") -> str:\n        \"\"\"\n        使用LLM压缩历史交互（直接返回LLM输出，不解析）\n        \n        Args:\n            history: 历史任务列表\n            task_id: 任务ID\n            current_task: 当前任务的用户输入内容\n            \n        Returns:\n            压缩后的文本（LLM原始输出）\n        \"\"\"\n        full_history_data = []\n        \n        for i, hist_item in enumerate(history, 1):\n            instructions = hist_item.get(\"instructions\", [])\n            agents_status = hist_item.get(\"agents_status\", {})\n            start_time = hist_item.get(\"start_time\", \"\")\n            completion_time = hist_item.get(\"completion_time\", \"\")\n            \n            user_inputs = []\n            for instr in instructions:\n                user_inputs.append(instr.get(\"instruction\", \"\"))\n            \n            agent_summaries = []\n            for agent_id, agent_info in agents_status.items():\n                if agent_info.get(\"level\") == 0 and agent_info.get(\"agent_name\") != \"judge_agent\":\n                    agent_name = agent_info.get(\"agent_name\", \"\")\n                    status = agent_info.get(\"status\", \"\")\n                    \n                    final_output = agent_info.get(\"final_output\", \"\")\n                    thinking = agent_info.get(\"latest_thinking\", \"\")\n                    \n                    agent_summaries.append({\n                        \"agent_name\": agent_name,\n                        \"status\": status,\n                        \"final_output\": final_output,\n                        \"thinking\": thinking\n                    })\n            \n            full_history_data.append({\n                \"task_id\": i,\n                \"time_range\": f\"{start_time} → {completion_time}\",\n                \"user_inputs\": user_inputs,\n                \"agents\": agent_summaries\n            })\n        \n        # 构建prompt，根据是否有当前任务来调整重点\n        if current_task:\n            task_context = f\"\"\"\n当前任务：\n{current_task}\n\n请特别关注与当前任务相关的历史信息，重点介绍相关的历史任务、生成的文件和中间结果。\"\"\"\n        else:\n            task_context = \"\"\n        \n        prompt = f\"\"\"请分析以下历史交互数据，提取关键信息并总结。{task_context}\n\n历史任务数据：\n{json.dumps(full_history_data, ensure_ascii=False, indent=2)}\n\n请总结以下内容：\n1. 文件空间总结：描述当前工作空间文件结构，结果文件对应的task，和简要介绍，同时列出一些重点的中间材料和文件。基于历史的final_output和thinking来推断\n2. 历史交互概览：简要描述每次任务的用户输入和完成情况\n{\"3. 相关性分析：重点说明哪些历史任务、文件和结果与当前任务相关，以及如何利用这些信息\" if current_task else \"\"}\n\n要求：\n- 每个描述要简洁明了\n- 强调当前任务应该复用的历史工作，除非用户明确指示重新开始。\n{\"- 优先详细介绍与当前任务相关的历史内容\" if current_task else \"\"}\n- 总字符数控制在3000字以内\n- 优先使用用户的输入习惯语言进行输出。\n- 直接输出总结内容文本，不需要任何标记，不要使用markdown格式\"\"\"\n\n        from services.llm_client import ChatMessage\n        \n        history_messages = [ChatMessage(role=\"user\", content=prompt)]\n        \n        compressor_model = self._resolve_compressor_model()\n        response = self.llm_client.chat(\n            history=history_messages,\n            model=compressor_model,  # 使用压缩专用模型\n            system_prompt=\"你是一个专业的内容总结助手。请简洁明了地总结历史交互信息。\",\n            tool_list=[],  # 空列表表示不使用工具\n            tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n            debug_task_id=task_id,\n            debug_label=\"context_builder\",\n        )\n        \n        if response.status != \"success\":\n            raise Exception(f\"LLM压缩失败: {response.output}\")\n\n        output_text = response.output\n        \n        safe_print(f\"✅ 历史交互压缩成功，长度: {len(output_text)} 字符\")\n        \n        return output_text\n    \n    def _build_structured_call_info(self, current: Dict, current_agent_id: str, task_id: str) -> str:\n        \"\"\"\n        构建结构化调用信息（JSON格式，更清晰）\n        支持压缩机制：当agent数量超过阈值时，使用LLM压缩\n        注意：每个agent的压缩结果单独缓存（因为is_current标记不同）\n        \"\"\"\n        hierarchy = current.get(\"hierarchy\", {})\n        agents_status = current.get(\"agents_status\", {})\n        \n        if not agents_status:\n            return \"(无调用关系)\"\n        \n        # 检查是否已有该agent的压缩结果（每个agent单独缓存）\n        cache_key = f\"_compressed_structured_call_info_{current_agent_id}\"\n        compressed_call_info = current.get(cache_key)\n        if compressed_call_info:\n            safe_print(f\"使用已有的压缩结构化调用信息 (agent: {current_agent_id})\")\n            return compressed_call_info\n        \n        # 找到根Agent（Level 0）\n        root_agents = [\n            aid for aid, info in hierarchy.items()\n            if info.get(\"parent\") is None\n        ]\n        \n        if not root_agents:\n            return \"(无调用关系)\"\n        \n        # 构建JSON结构（添加已访问集合防止循环）\n        call_tree = []\n        visited = set()  # 防止循环引用\n        for root_id in root_agents:\n            tree_node = self._build_agent_tree_json(\n                root_id, hierarchy, agents_status, current_agent_id, visited\n            )\n            if tree_node:\n                call_tree.append(tree_node)\n        \n        # 转换为易读的JSON字符串\n        call_tree_json = json.dumps(call_tree, indent=2, ensure_ascii=False)\n        \n        settings = get_context_settings()\n        compress_agent_threshold = settings.get(\"structured_call_info_compress_threshold_agents\", 10)\n        compress_token_threshold = settings.get(\"structured_call_info_compress_threshold_tokens\", 2200)\n        # 检查是否需要压缩\n        agent_count = len(agents_status)\n        if agent_count > compress_agent_threshold or self._count_tokens(call_tree_json) > compress_token_threshold:\n            safe_print(f\"检测到较大的结构化调用信息（{agent_count}个agents，{len(call_tree_json)}字符），启动压缩...\")\n            compressed_result = self._compress_structured_call_info_with_llm(\n                call_tree, current_agent_id, task_id\n            )\n            \n            # 保存压缩结果（针对当前agent）\n            cache_key = f\"_compressed_structured_call_info_{current_agent_id}\"\n            context = self.hierarchy_manager.get_context()\n            context[\"current\"][cache_key] = compressed_result\n            self.hierarchy_manager._save_context(context)\n            \n            return compressed_result\n        \n        return call_tree_json\n    \n    def _compress_structured_call_info_with_llm(self, call_tree: List[Dict], current_agent_id: str, task_id: str) -> str:\n        \"\"\"\n        使用LLM压缩结构化调用信息\n        \n        Args:\n            call_tree: Agent调用树结构\n            current_agent_id: 当前正在运行的Agent ID\n            \n        Returns:\n            压缩后的文本（LLM原始输出）\n        \"\"\"\n        prompt = f\"\"\"请分析以下Agent调用树结构，提取关键信息并总结。\n\n当前正在运行的Agent ID: {current_agent_id}\n\nAgent调用树数据：\n{json.dumps(call_tree, ensure_ascii=False, indent=2)}\n\n请总结以下内容：\n1. **调用关系概览**：描述整体的Agent层级结构和调用关系\n2. **已完成的Agent**：列出已完成的Agent及其关键输出（特别是可能对当前Agent有用的信息）\n3. **运行中的Agent**：列出运行中的Agent及其当前thinking\n4. **当前Agent的上下文**：重点说明当前Agent的父Agent、兄弟Agent状态，以及可用的上下文信息\n\n要求：\n- 保留关键的agent_id、agent_name、level、status信息\n- 对于已完成的Agent，保留重要的final_output（可适当精简）\n- 对于运行中的Agent，保留关键的thinking（可适当精简）\n- 重点突出与当前Agent相关的信息（包括可能用到的文件，可以复用的历史成果）\n- 总字符数控制在2000字以内\n- 优先使用用户的输入习惯语言进行输出\n- 直接输出总结内容文本，不需要任何标记，不要使用markdown格式\"\"\"\n\n        from services.llm_client import ChatMessage\n        \n        messages = [ChatMessage(role=\"user\", content=prompt)]\n        \n        compressor_model = self._resolve_compressor_model()\n        response = self.llm_client.chat(\n            history=messages,\n            model=compressor_model,  # 使用压缩专用模型\n            system_prompt=\"你是一个专业的内容总结助手。请简洁明了地总结Agent调用树信息。\",\n            tool_list=[],\n            tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n            debug_task_id=task_id,\n            debug_label=\"context_builder\",\n        )\n        \n        if response.status != \"success\":\n            # 压缩失败时返回原始JSON（截断版）\n            safe_print(f\"⚠️ LLM压缩失败: {response.output}，使用截断版本\")\n            original_json = json.dumps(call_tree, indent=2, ensure_ascii=False)\n            return original_json[:5000] + \"\\n...(已截断)\"\n\n        output_text = response.output\n        \n        safe_print(f\"✅ 结构化调用信息压缩成功，长度: {len(output_text)} 字符\")\n        \n        return output_text\n    \n    def _build_agent_tree_json(\n        self,\n        agent_id: str,\n        hierarchy: Dict,\n        agents_status: Dict,\n        current_agent_id: str,\n        visited: set = None\n    ) -> Dict:\n        \"\"\"递归构建Agent树的JSON结构（带循环检测）\"\"\"\n        # 初始化visited集合\n        if visited is None:\n            visited = set()\n        \n        # 检查是否已访问（防止循环）\n        if agent_id in visited:\n            return None\n        \n        visited.add(agent_id)\n        \n        if agent_id not in agents_status:\n            return None\n        \n        agent_info = agents_status[agent_id]\n        agent_name = agent_info.get(\"agent_name\", \"\")\n        \n        # 完全跳过judge_agent（不显示也不处理）\n        if agent_name == \"judge_agent\":\n            return None\n        \n        level = agent_info.get(\"level\", 0)\n        status = agent_info.get(\"status\", \"\")\n        is_current = (agent_id == current_agent_id)\n        \n        # 构建节点数据\n        node = {\n            \"agent_id\": agent_id,\n            \"agent_name\": agent_name,\n            \"level\": level,\n            \"status\": status,\n            \"is_current\": is_current\n        }\n        \n        # 添加thinking或final_output\n        if status == \"completed\":\n            final_output = agent_info.get(\"final_output\", \"\")\n            if final_output:\n                # 限制长度\n                node[\"final_output\"] = final_output[:500] + \"...\" if len(final_output) > 500 else final_output\n        else:\n            thinking = agent_info.get(\"latest_thinking\", \"\")\n            if thinking:\n                # 限制长度\n                node[\"thinking\"] = thinking[:500] + \"...\" if len(thinking) > 500 else thinking\n        \n        # 递归处理子节点\n        children = hierarchy.get(agent_id, {}).get(\"children\", [])\n        if children:\n            child_nodes = []\n            for child_id in children:\n                child_node = self._build_agent_tree_json(\n                    child_id, hierarchy, agents_status, current_agent_id, visited\n                )\n                if child_node:\n                    if isinstance(child_node, list):\n                        child_nodes.extend(child_node)\n                    else:\n                        child_nodes.append(child_node)\n            \n            if child_nodes:\n                node[\"children\"] = child_nodes\n        \n        return node\n    \n    def _format_agent_tree(\n        self, \n        agent_id: str, \n        hierarchy: Dict, \n        agents_status: Dict, \n        indent: int,\n        current_agent_id: str\n    ) -> str:\n        \"\"\"递归格式化Agent树（清晰展示层级和状态）\"\"\"\n        if agent_id not in agents_status:\n            return \"\"\n        \n        agent_info = agents_status[agent_id]\n        agent_name = agent_info.get(\"agent_name\", \"\")\n        \n        # 跳过judge_agent的显示（避免干扰）\n        if agent_name == \"judge_agent\":\n            # 但仍需递归处理它的子节点\n            children = hierarchy.get(agent_id, {}).get(\"children\", [])\n            child_lines = []\n            for child_id in children:\n                child_tree = self._format_agent_tree(\n                    child_id, hierarchy, agents_status, indent, current_agent_id\n                )\n                if child_tree:\n                    child_lines.append(child_tree)\n            return \"\\n\".join(child_lines)\n        \n        level = agent_info.get(\"level\", 0)\n        status = agent_info.get(\"status\", \"\")\n        \n        # 当前Agent标记\n        current_marker = \" [当前Agent]\" if agent_id == current_agent_id else \"\"\n        \n        # 状态图标\n        status_icon = \"✅\" if status == \"completed\" else \"⏳\"\n        \n        # 缩进\n        indent_str = \"  \" * indent\n        \n        # 构建输出\n        lines = []\n        \n        # 第一行：Agent ID和名称\n        lines.append(f\"{indent_str}{status_icon} {agent_id} ({agent_name}, Level {level}){current_marker}\")\n        \n        # 第二行：状态信息\n        if status == \"completed\":\n            # 已完成：显示final_output\n            final_output = agent_info.get(\"final_output\", \"\")\n            if final_output:\n                # 限制输出长度\n                output_preview = final_output[:300] + \"...\" if len(final_output) > 300 else final_output\n                lines.append(f\"{indent_str}  📊 Final Output: {output_preview}\")\n        else:\n            # 运行中：显示latest_thinking\n            thinking = agent_info.get(\"latest_thinking\", \"\")\n            if thinking:\n                # 限制thinking长度\n                thinking_preview = thinking[:300] + \"...\" if len(thinking) > 300 else thinking\n                lines.append(f\"{indent_str}  💭 Thinking: {thinking_preview}\")\n        \n        # 递归处理子Agent\n        children = hierarchy.get(agent_id, {}).get(\"children\", [])\n        for child_id in children:\n            child_tree = self._format_agent_tree(\n                child_id, hierarchy, agents_status, indent + 1, current_agent_id\n            )\n            if child_tree:  # 只添加非空的子树\n                lines.append(child_tree)\n        \n        return \"\\n\".join(lines)\n    \n    def _build_current_thinking(self, task_id: str, agent_id: str, current: Dict) -> str:\n        \"\"\"构建当前进度思考（从文件读取最新的thinking）\"\"\"\n        # 从_actions.json文件读取（使用正确的路径）\n        from pathlib import Path\n        import json\n        import hashlib\n        import os\n        \n        # 使用与ConversationStorage相同的路径生成逻辑\n        conversations_dir = get_user_conversations_dir()\n        task_hash = hashlib.md5(task_id.encode()).hexdigest()[:8]\n        task_folder = Path(task_id).name if (os.sep in task_id or '/' in task_id or '\\\\' in task_id) else task_id\n        task_name = f\"{task_hash}_{task_folder}\"\n        filepath = conversations_dir / f\"{task_name}_{agent_id}_actions.json\"\n        \n        try:\n            if filepath.exists():\n                with open(filepath, 'r', encoding='utf-8') as f:\n                    data = json.load(f)\n                    thinking = data.get(\"latest_thinking\", \"\")\n                    if thinking:\n                        return thinking\n        except Exception as e:\n            safe_print(f\"⚠️ 读取thinking失败: {e}\")\n        \n        # 备用：从share_context读取\n        agents_status = current.get(\"agents_status\", {})\n        if agent_id in agents_status:\n            thinking = agents_status[agent_id].get(\"latest_thinking\", \"\")\n            if thinking:\n                return thinking\n        \n        return \"(无)\"\n    \n    def _build_action_history(self, task_id: str, agent_id: str) -> str:\n        \"\"\"构建历史动作记录（从文件读取，XML格式）\"\"\"\n        # 优先使用传入的action_history\n        action_history = self.current_action_history\n        \n        # 如果没有传入，从文件读取\n        if not action_history:\n            from pathlib import Path\n            import json\n            import hashlib\n            import os\n            \n            # 使用与ConversationStorage相同的路径生成逻辑\n            conversations_dir = get_user_conversations_dir()\n            task_hash = hashlib.md5(task_id.encode()).hexdigest()[:8]\n            task_folder = Path(task_id).name if (os.sep in task_id or '/' in task_id or '\\\\' in task_id) else task_id\n            task_name = f\"{task_hash}_{task_folder}\"\n            filepath = conversations_dir / f\"{task_name}_{agent_id}_actions.json\"\n            \n            try:\n                if filepath.exists():\n                    with open(filepath, 'r', encoding='utf-8') as f:\n                        data = json.load(f)\n                        action_history = data.get(\"action_history\", [])\n            except Exception as e:\n                safe_print(f\"⚠️ 读取action_history失败: {e}\")\n        \n        if not action_history:\n            return \"(无历史动作)\"\n        \n        # 构建XML格式的动作历史\n        actions_xml = []\n        for action in action_history:\n            tool_name = action.get(\"tool_name\", \"\")\n            \n            # 检查是否是历史总结\n            if tool_name == \"_historical_summary\":\n                # 渲染为<已压缩信息>\n                summary_text = action.get(\"result\", {}).get(\"output\", \"\")\n                actions_xml.append(f\"<已压缩信息>\\n{summary_text}\\n</已压缩信息>\")\n                continue\n            \n            # 普通action\n            arguments = action.get(\"arguments\", {})\n            result = action.get(\"result\", {})\n            \n            # 构建单个动作的XML\n            # action_xml = f\"<action>\\n\"\n            # action_xml += f\"  <tool_name>{tool_name}</tool_name>\\n\"\n            action_xml = f\"action:\\n\"\n            action_xml += f\"  tool_name:{tool_name}\\n\"            \n            # 添加参数\n            for param_name, param_value in arguments.items():\n                # 转义XML特殊字符\n                param_value_str = str(param_value).replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\")\n                #action_xml += f\"  <tool_use:{param_name}>{param_value_str}</tool_use:{param_name}>\\n\"\n                action_xml += f\"  {param_name}:{param_value_str}\\n\"\n            \n            # 添加结果（JSON格式）\n            try:\n                result_json = json.dumps(result, ensure_ascii=False, indent=2)\n                action_xml += f\"  <result>\\n{result_json}\\n  </result>\\n\"\n            except:\n                action_xml += f\"  <result>{str(result)}</result>\\n\"\n            \n            # action_xml += \"</action>\"\n            actions_xml.append(action_xml)\n        \n        return \"\\n\\n\".join(actions_xml)\n\n\nif __name__ == \"__main__\":\n    # 测试上下文构造器\n    from hierarchy_manager import HierarchyManager\n    \n    manager = HierarchyManager(\"test_task\")\n    manager.start_new_instruction(\"测试任务：生成一个文件\")\n    \n    agent_id = manager.push_agent(\"test_agent\", \"生成hello.py文件\")\n    manager.update_thinking(agent_id, \"我需要先创建文件，然后写入内容\")\n    manager.add_action(agent_id, {\n        \"tool_name\": \"file_write\",\n        \"arguments\": {\"path\": \"hello.py\", \"content\": \"safe_print('hello')\"},\n        \"result\": {\"status\": \"success\", \"output\": \"文件已创建\"}\n    })\n    \n    builder = ContextBuilder(manager)\n    context = builder.build_context(agent_id, \"test_agent\", \"生成hello.py文件\")\n    \n    safe_print(\"=\" * 80)\n    safe_print(\"生成的上下文:\")\n    safe_print(\"=\" * 80)\n    safe_print(context)\n"
  },
  {
    "path": "core/event_handlers.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n实现具体的事件处理器 (Event Handlers) - v2 (事件分类规范化)\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import asdict, is_dataclass\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom .events import *\nfrom utils.windows_compat import safe_print\nfrom utils.event_emitter import get_event_emitter as get_jsonl_emitter\n\n\ndef _normalize_event_value(value: Any) -> Any:\n    if is_dataclass(value):\n        return {key: _normalize_event_value(item) for key, item in asdict(value).items()}\n    if isinstance(value, dict):\n        return {str(key): _normalize_event_value(item) for key, item in value.items()}\n    if isinstance(value, list):\n        return [_normalize_event_value(item) for item in value]\n    if isinstance(value, tuple):\n        return [_normalize_event_value(item) for item in value]\n    return value\n\n\ndef serialize_agent_event(event: AgentEvent) -> Dict[str, Any]:\n    event_type = str(getattr(event, \"event_type\", \"\") or \"\")\n    parts = event_type.split(\".\", 2)\n    phase = parts[0] if len(parts) > 0 else \"\"\n    domain = parts[1] if len(parts) > 1 else \"\"\n    action = parts[2] if len(parts) > 2 else \"\"\n\n    if is_dataclass(event):\n        payload = _normalize_event_value(asdict(event))\n    else:\n        payload = {}\n\n    return {\n        \"event_type\": event_type,\n        \"phase\": phase,\n        \"domain\": domain,\n        \"action\": action,\n        \"payload\": payload,\n    }\n\n\nclass StructuredEventHandler:\n    \"\"\"将内部 AgentEvent 规范化为 SDK 友好的结构化字典。\"\"\"\n\n    def __init__(\n        self,\n        *,\n        callback: Optional[Callable[[Dict[str, Any]], None]] = None,\n        collector: Optional[List[Dict[str, Any]]] = None,\n    ):\n        self.callback = callback\n        self.collector = collector\n\n    def handle(self, event: AgentEvent):\n        normalized = serialize_agent_event(event)\n        self.emit(normalized)\n\n    def emit(self, normalized: Dict[str, Any]):\n        if self.collector is not None:\n            self.collector.append(normalized)\n        if self.callback is not None:\n            self.callback(normalized)\n\nclass ConsoleLogHandler:\n    \"\"\"\n    控制台日志处理器.\n    消费AgentEvent, 并以用户友好的格式打印到控制台.\n    \"\"\"\n    def handle(self, event: AgentEvent):\n        \"\"\"根据事件类型, 调用不同的打印方法\"\"\"\n        # 将 event_type 中的 '.' 替换为 '_', 以匹配方法名\n        method_name = f\"_print_{event.event_type.replace('.', '_')}\"\n        handler_method = getattr(self, method_name, self._print_default)\n        handler_method(event)\n\n    def _print_default(self, event: AgentEvent):\n        \"\"\"默认不打印任何内容\"\"\"\n        pass\n\n    # Agent Lifecycle\n    def _print_agent_start(self, event: AgentStartEvent):\n        safe_print(f\"\\n{ '='*80}\")\n        safe_print(f\"🤖 启动Agent: {event.agent_name}\")\n        safe_print(f\"📝 任务: {event.task_input[:100]}...\")\n        safe_print(f\"{ '='*80}\\n\")\n    \n    def _print_agent_end(self, event: AgentEndEvent):\n        if event.status == \"success\":\n            final_result = event.result.get('result', {})\n            safe_print(f\"\\n{ '='*80}\")\n            safe_print(f\"✅ Agent完成: {event.result.get('tool_name', 'unknown')}\")\n            safe_print(f\"📊 状态: {final_result.get('status', 'unknown')}\")\n            safe_print(f\"{ '='*80}\\n\")\n            \n    # Prepare Phase\n    def _print_prepare_model_select(self, event: ModelSelectionEvent):\n        if event.is_fallback:\n            safe_print(f\"⚠️请求的模型 '{event.requested_model}' 不在可用列表中\")\n            safe_print(f\"✅使用回退模型: {event.final_model}\")\n        else:\n            safe_print(f\"✅使用请求的模型: {event.final_model}\")\n\n    def _print_prepare_history_load(self, event: HistoryLoadEvent):\n        safe_print(f\"📂 已加载对话历史，从第 {event.start_turn + 1} 轮继续\")\n        safe_print(f\"   渲染历史: {event.action_history_len}条, 完整轨迹: {event.action_history_fact_len}条\")\n        if event.pending_tool_count > 0:\n            safe_print(f\"🔄 发现{event.pending_tool_count}个pending工具，恢复执行...\")\n\n    # Run Phase\n    def _print_run_llm_start(self, event: LlmCallStartEvent):\n        safe_print(f\"🤖 调用LLM: {event.model}\")\n        safe_print(f\"   📝 System Prompt长度: {len(event.system_prompt)} 字符\")\n\n    def _print_run_llm_end(self, event: LlmCallEndEvent):\n        safe_print(f\"📥 LLM输出: {event.llm_output[:100]}...\")\n        safe_print(f\"🔧 工具调用数量: {len(event.tool_calls)}\")\n        \n    def _print_run_tool_start(self, event: ToolCallStartEvent):\n        safe_print(f\"\\n🔧 执行工具: {event.tool_name}\")\n        safe_print(f\"📋 参数: {event.arguments}\")\n        \n    def _print_run_tool_end(self, event: ToolCallEndEvent):\n        safe_print(f\"✅ 结果: {event.status}\")\n    \n    def _print_run_thinking_start(self, event: ThinkingStartEvent):\n        if event.is_forced:\n            safe_print(\"❌ 5次提醒后仍未调用工具，触发thinking分析\")\n        else:\n            if event.is_initial:\n                safe_print(f\"[{event.agent_name}] 开始行动前进行初始规划...\")\n            else:\n                safe_print(f\"[{event.agent_name}] Thinking分析已更新\")\n\n    def _print_run_thinking_end(self, event: ThinkingEndEvent):\n        safe_print(f\"[{event.agent_name}] Thinking分析已更新: {event.result}\")\n        \n    def _print_run_thinking_fail(self, event: ThinkingFailEvent):\n        safe_print(f\"⚠️ Thinking触发失败: {event.error_message}\")\n\n    # System\n    def _print_system_error(self, event: ErrorEvent):\n        safe_print(event.error_display)\n\n    def _print_system_cli_display(self, event: CliDisplayEvent):\n        safe_print(event.message)\n\n\nclass JsonlStreamHandler:\n    \"\"\"\n    JSONL流处理器.\n    消费核心生命周期事件, 并将其转换为用于插件集成的JSONL格式.\n    \"\"\"\n    def __init__(self, enabled: bool):\n        self.jsonl_emitter = get_jsonl_emitter()\n        self.jsonl_emitter.enabled = enabled\n\n    def handle(self, event: AgentEvent):\n        if not self.jsonl_emitter.enabled or event.event_type.startswith('system.'):\n            # 不处理纯展示或内部系统事件\n            return\n\n        # 直接将事件对象序列化为JSON\n        # 这比之前手动格式化字符串更健壮、更具扩展性\n        method_name = f\"_stream_{event.event_type.replace('.', '_')}\"\n        handler_method = getattr(self, method_name, self._stream_default)\n        handler_method(event)\n    \n    def _stream_default(self, event: AgentEvent):\n        \"\"\"默认不处理任何事件\"\"\"\n        pass\n\n    def _stream_agent_start(self, event: AgentStartEvent):\n        self.jsonl_emitter.emit({\n            \"type\": \"agent_start\",\n            \"agent\": event.agent_name,\n            \"task\": event.task_input[:200]\n        })\n    \n    def _stream_agent_end(self, event: AgentEndEvent):\n        self.jsonl_emitter.emit({\n            \"type\": \"agent_end\",\n            \"status\": event.status\n        })\n    \n    def _stream_run_thinking_start(self, event: ThinkingStartEvent):\n        self.jsonl_emitter.emit({\n            \"type\": \"thinking_start\",\n            \"agent\": event.agent_name,\n            \"is_initial\": event.is_initial,\n            \"is_forced\": event.is_forced\n        })\n    \n    def _stream_run_tool_start(self, event: ToolCallStartEvent):\n        # 使用 tool_call 事件类型（而非 token），让渲染器展示为工具卡片\n        self.jsonl_emitter.emit({\n            \"type\": \"tool_call\",\n            \"name\": event.tool_name,\n            \"arguments\": event.arguments\n        })\n\n    def _stream_run_tool_end(self, event: ToolCallEndEvent):\n        # 兼容不同工具返回格式：\n        # - ToolExecutor 包装层错误：error_information\n        # - 工具本身错误：error\n        # - 工具输出：output\n        err = \"\"\n        try:\n            err = str(event.result.get(\"error_information\") or event.result.get(\"error\") or \"\")\n        except Exception:\n            err = \"\"\n        out = \"\"\n        try:\n            out = str(event.result.get(\"output\", \"\") or \"\")\n        except Exception:\n            out = \"\"\n        preview = out[:200] if out else (err[:200] if err else \"\")\n        self.jsonl_emitter.emit({\n            \"type\": \"tool_result\",\n            \"name\": event.tool_name,\n            \"status\": event.status,\n            \"output_preview\": preview,\n            \"error\": err[:1000] if err else \"\"\n        })\n\n    def _stream_run_thinking_end(self, event: ThinkingEndEvent):\n        # 发送完整 thinking 内容（thinking agent 独立 LLM 调用，token 不经过主 agent 事件流）\n        self.jsonl_emitter.emit({\n            \"type\": \"thinking_end\",\n            \"agent\": event.agent_name,\n            \"is_initial\": event.is_initial,\n            \"result\": event.result\n        })\n    \n    def _stream_run_thinking_fail(self, event: ThinkingFailEvent):\n        self.jsonl_emitter.warn(event.error_message)\n\n    def _stream_system_error(self, event: ErrorEvent):\n        self.jsonl_emitter.error(event.error_display)\n"
  },
  {
    "path": "core/events.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n定义Agent执行过程中的所有事件契约 (Event Schema) - v2 (规范化)\n\"\"\"\n\nfrom dataclasses import dataclass, field\nfrom typing import Dict, Any, List, Literal, ClassVar\nimport time\n\n# =================================================================================\n# 规范：\n# event_type 格式: \"phase.domain.action\"\n# - phase: prepare, run, end\n# - domain: agent, model, history, llm, tool, thinking, system\n# - action: start, end, fail, select, load, etc.\n# =================================================================================\n\n@dataclass\nclass AgentEvent:\n    \"\"\"所有事件的基类\"\"\"\n    event_type: str\n\n# region 1. Prepare Phase Events\n@dataclass\nclass ModelSelectionEvent(AgentEvent):\n    \"\"\"模型选择事件\"\"\"\n    event_type: ClassVar[str] = \"prepare.model.select\" # Class variable\n\n    requested_model: str\n    final_model: str\n    is_fallback: bool\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass HistoryLoadEvent(AgentEvent):\n    \"\"\"加载历史记录事件\"\"\"\n    event_type: ClassVar[str] = \"prepare.history.load\"\n    \n    start_turn: int\n    action_history_len: int\n    action_history_fact_len: int\n    pending_tool_count: int\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n# endregion\n\n# region 2. Run Phase Events\n\n# Thinking Events\n@dataclass\nclass ThinkingStartEvent(AgentEvent):\n    \"\"\"Thinking过程开始事件\"\"\"\n    event_type: ClassVar[str] = \"run.thinking.start\"\n    \n    agent_name: str\n    is_initial: bool\n    is_forced: bool = False \n    timestamp: float = field(default_factory=time.time)\n\n\n@dataclass\nclass ThinkingEndEvent(AgentEvent):\n    \"\"\"Thinking过程成功结束事件\"\"\"\n    event_type: ClassVar[str] = \"run.thinking.end\"\n    \n    agent_name: str\n    is_initial: bool\n    result: str\n    model: str = \"\"\n    raw_output: str = \"\"\n    raw_reasoning_content: str = \"\"\n    finish_reason: str = \"\"\n    # Default arguments last\n    is_forced: bool = False \n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass ThinkingFailEvent(AgentEvent):\n    \"\"\"Thinking过程失败事件\"\"\"\n    event_type: ClassVar[str] = \"run.thinking.fail\"\n    \n    agent_name: str\n    error_message: str\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n# LLM Call Events\n@dataclass\nclass LlmCallStartEvent(AgentEvent):\n    \"\"\"LLM调用开始\"\"\"\n    event_type: ClassVar[str] = \"run.llm.start\"\n    \n    model: str\n    system_prompt: str\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass LlmCallEndEvent(AgentEvent):\n    \"\"\"LLM调用结束\"\"\"\n    event_type: ClassVar[str] = \"run.llm.end\"\n    \n    llm_output: str\n    tool_calls: List[Dict]\n    model: str = \"\"\n    reasoning_content: str = \"\"\n    finish_reason: str = \"\"\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n# Tool Call Events\n@dataclass\nclass ToolCallStartEvent(AgentEvent):\n    \"\"\"工具调用开始\"\"\"\n    event_type: ClassVar[str] = \"run.tool.start\"\n    \n    tool_name: str\n    arguments: Dict[str, Any]\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass ToolCallEndEvent(AgentEvent):\n    \"\"\"工具调用结束\"\"\"\n    event_type: ClassVar[str] = \"run.tool.end\"\n    \n    tool_name: str\n    status: str\n    result: Dict[str, Any]\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n# endregion\n\n# region 3. General Events (Can occur in any phase)\n\n# Agent Lifecycle\n@dataclass\nclass AgentStartEvent(AgentEvent):\n    \"\"\"Agent任务开始\"\"\"\n    event_type: ClassVar[str] = \"agent.start\"\n    \n    agent_name: str\n    task_input: str\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass AgentEndEvent(AgentEvent):\n    \"\"\"Agent任务结束（无论成功、失败或超时）\"\"\"\n    event_type: ClassVar[str] = \"agent.end\"\n    \n    status: str\n    result: Dict[str, Any]\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n# System & Display Events\n@dataclass\nclass ErrorEvent(AgentEvent):\n    \"\"\"发生导致执行中断的严重错误\"\"\"\n    event_type: ClassVar[str] = \"system.error\"\n    \n    error_display: str\n    # Default arguments last\n    timestamp: float = field(default_factory=time.time)\n\n@dataclass\nclass CliDisplayEvent(AgentEvent):\n    \"\"\"向CLI输出一条格式化消息\"\"\"\n    event_type: ClassVar[str] = \"system.cli_display\"\n    \n    message: str\n    # Default arguments last\n    style: Literal['info', 'warning', 'success', 'error', 'separator'] = 'info'\n    timestamp: float = field(default_factory=time.time)\n# endregion\n"
  },
  {
    "path": "core/hierarchy_manager.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n层级管理器 - 管理Agent调用层级和共享上下文\n简化版本，去除冗余功能，保留核心逻辑\n\"\"\"\n\nimport os\nimport json\nimport threading\nfrom typing import Dict, List, Optional\nfrom datetime import datetime\nfrom pathlib import Path\n\nfrom utils.user_paths import get_user_conversations_dir\n\n\nclass HierarchyManager:\n    \"\"\"Agent层级管理器\"\"\"\n    \n    def __init__(self, task_id: str):\n        \"\"\"\n        初始化层级管理器\n        \n        Args:\n            task_id: 任务ID\n        \"\"\"\n        self.task_id = task_id\n        self.lock = threading.Lock()\n        \n        # 文件路径 - 使用用户主目录（跨平台）\n        conversations_dir = get_user_conversations_dir()\n        conversations_dir.mkdir(parents=True, exist_ok=True)\n        \n        # 生成文件名：hash + 最后文件夹名\n        import hashlib\n        task_hash = hashlib.md5(task_id.encode()).hexdigest()[:8]\n        # 跨平台路径处理：检查是否是路径（包含/或\\）\n        task_folder = Path(task_id).name if (os.sep in task_id or '/' in task_id or '\\\\' in task_id) else task_id\n        task_name = f\"{task_hash}_{task_folder}\"\n        \n        self.stack_file = conversations_dir / f'{task_name}_stack.json'\n        self.context_file = conversations_dir / f'{task_name}_share_context.json'\n        \n        # 初始化文件\n        self._initialize_files()\n    \n    def _initialize_files(self):\n        \"\"\"初始化栈文件和共享上下文文件\"\"\"\n        # 初始化栈文件\n        if not self.stack_file.exists():\n            with open(self.stack_file, 'w', encoding='utf-8') as f:\n                json.dump({\n                    \"stack\": [],\n                    \"created_at\": datetime.now().isoformat()\n                }, f, indent=2, ensure_ascii=False)\n        \n        # 初始化共享上下文文件\n        if not self.context_file.exists():\n            with open(self.context_file, 'w', encoding='utf-8') as f:\n                json.dump({\n                    \"task_id\": self.task_id,\n                    \"runtime\": {},\n                    \"current\": {\n                        \"instructions\": [],\n                        \"hierarchy\": {},\n                        \"agents_status\": {},\n                        \"start_time\": datetime.now().isoformat(),\n                        \"last_updated\": datetime.now().isoformat()\n                    },\n                    \"agent_time_history\": {},\n                    \"history\": [],\n                    \"created_at\": datetime.now().isoformat(),\n                    \"last_updated\": datetime.now().isoformat()\n                }, f, indent=2, ensure_ascii=False)\n    \n    def _load_stack(self) -> List[Dict]:\n        \"\"\"加载当前栈状态\"\"\"\n        try:\n            with open(self.stack_file, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n                return data.get(\"stack\", [])\n        except Exception as e:\n            safe_print(f\"⚠️ 加载栈文件失败: {e}\")\n            return []\n    \n    def _save_stack(self, stack: List[Dict]):\n        \"\"\"保存栈状态\"\"\"\n        try:\n            with open(self.stack_file, 'w', encoding='utf-8') as f:\n                json.dump({\n                    \"stack\": stack,\n                    \"last_updated\": datetime.now().isoformat()\n                }, f, indent=2, ensure_ascii=False)\n        except Exception as e:\n            safe_print(f\"⚠️ 保存栈文件失败: {e}\")\n    \n    def _load_context(self) -> Dict:\n        \"\"\"加载共享上下文\"\"\"\n        try:\n            with open(self.context_file, 'r', encoding='utf-8') as f:\n                return json.load(f)\n        except Exception as e:\n            safe_print(f\"⚠️ 加载共享上下文失败: {e}\")\n            return {\n                \"task_id\": self.task_id,\n                \"current\": {\n                    \"instructions\": [],\n                    \"hierarchy\": {},\n                    \"agents_status\": {}\n                },\n                \"agent_time_history\": {},\n                \"history\": []\n            }\n\n    def _save_context(self, context: Dict):\n        \"\"\"保存共享上下文\"\"\"\n        try:\n            context[\"last_updated\"] = datetime.now().isoformat()\n            with open(self.context_file, 'w', encoding='utf-8') as f:\n                json.dump(context, f, indent=2, ensure_ascii=False)\n        except Exception as e:\n            safe_print(f\"⚠️ 保存共享上下文失败: {e}\")\n    \n    def start_new_instruction(self, instruction: str) -> str:\n        \"\"\"\n        开始一个新的指令\n        \n        Args:\n            instruction: 新的指令内容\n            \n        Returns:\n            指令ID\n        \"\"\"\n        return self.append_instruction(instruction, dedupe=True, source=\"user\")\n\n    def append_instruction(self, instruction: str, dedupe: bool = False, source: str = \"user\") -> str:\n        \"\"\"\n        向 current.instructions 追加一条消息/指令。\n\n        Args:\n            instruction: 消息内容\n            dedupe: 是否按完全相同文本去重\n            source: 来源标记，例如 user / agent / system\n        \"\"\"\n        with self.lock:\n            import hashlib\n            context = self._load_context()\n\n            existing_instructions = context[\"current\"].get(\"instructions\", [])\n            if dedupe:\n                for existing in existing_instructions:\n                    if existing.get(\"instruction\") == instruction:\n                        safe_print(f\"ℹ️ 指令已存在，跳过添加: {instruction[:50]}...\")\n                        return existing.get(\"instruction_id\", \"\")\n\n            content_for_hash = f\"{self.task_id}|{instruction}\"\n            hash_object = hashlib.md5(content_for_hash.encode())\n            instruction_hash = hash_object.hexdigest()[:12]\n            instruction_id = f\"instruction_{instruction_hash}\"\n\n            instruction_entry = {\n                \"instruction\": instruction,\n                \"instruction_id\": instruction_id,\n                \"start_time\": datetime.now().isoformat(),\n                \"source\": source\n            }\n\n            context[\"current\"][\"instructions\"].append(instruction_entry)\n            self._save_context(context)\n\n            safe_print(f\"📝 新指令已添加: {instruction_id} -> {instruction[:50]}...\")\n\n            return instruction_id\n\n    def get_runtime_metadata(self) -> Dict:\n        \"\"\"读取 task 级运行时元数据。\"\"\"\n        context = self._load_context()\n        runtime = context.get(\"runtime\", {})\n        return runtime if isinstance(runtime, dict) else {}\n\n    def set_runtime_metadata(self, **metadata):\n        \"\"\"写入 task 级运行时元数据（如 agent_system / agent_name / user_input）。\"\"\"\n        with self.lock:\n            context = self._load_context()\n            runtime = context.get(\"runtime\", {})\n            if not isinstance(runtime, dict):\n                runtime = {}\n\n            for key, value in metadata.items():\n                if value is None:\n                    continue\n                runtime[key] = value\n\n            runtime[\"last_updated\"] = datetime.now().isoformat()\n            context[\"runtime\"] = runtime\n            self._save_context(context)\n\n    def push_agent(self, agent_name: str, user_input: str) -> str:\n        \"\"\"\n        Agent入栈操作\n        \n        Args:\n            agent_name: Agent名称\n            user_input: 用户输入\n            \n        Returns:\n            生成的agent_id\n        \"\"\"\n        with self.lock:\n            import hashlib\n            \n            # 生成agent_id\n            content_for_hash = f\"{agent_name}|{self.task_id}|{user_input}\"\n            hash_object = hashlib.md5(content_for_hash.encode())\n            agent_hash = hash_object.hexdigest()[:12]\n            agent_id = f\"{agent_name}_{agent_hash}\"\n            \n            # 加载当前状态\n            stack = self._load_stack()\n            context = self._load_context()\n            \n            # 获取父Agent（栈顶）\n            parent_id = None\n            level = 0\n            if stack:\n                parent_id = stack[-1][\"agent_id\"]\n                level = stack[-1][\"level\"] + 1\n            \n            # 创建Agent栈条目\n            agent_entry = {\n                \"agent_id\": agent_id,\n                \"agent_name\": agent_name,\n                \"parent_id\": parent_id,\n                \"level\": level,\n                \"user_input\": user_input,\n                \"start_time\": datetime.now().isoformat()\n            }\n            \n            # 入栈\n            stack.append(agent_entry)\n            self._save_stack(stack)\n            \n            # 更新共享上下文\n            if agent_id not in context[\"current\"][\"hierarchy\"]:\n                context[\"current\"][\"hierarchy\"][agent_id] = {\n                    \"parent\": parent_id,\n                    \"children\": [],\n                    \"level\": level\n                }\n            \n            # 如果有父Agent，将当前Agent添加到父Agent的children列表\n            if parent_id and parent_id in context[\"current\"][\"hierarchy\"]:\n                if agent_id not in context[\"current\"][\"hierarchy\"][parent_id][\"children\"]:\n                    context[\"current\"][\"hierarchy\"][parent_id][\"children\"].append(agent_id)\n            \n            # 更新Agent状态（不保存action_history，它保存在单独文件中）\n            context[\"current\"][\"agents_status\"][agent_id] = {\n                \"agent_name\": agent_name,\n                \"status\": \"running\",\n                \"initial_input\": user_input,\n                \"start_time\": datetime.now().isoformat(),\n                \"parent_id\": parent_id,\n                \"level\": level,\n                \"latest_thinking\": \"\",  # 只保留最新的thinking\n                \"loaded_skills\": []     # 当前上下文中已注入的 skills\n            }\n            \n            # 记录时间历史\n            if \"agent_time_history\" not in context:\n                context[\"agent_time_history\"] = {}\n            context[\"agent_time_history\"][agent_id] = {\n                \"start_time\": datetime.now().isoformat(),\n                \"end_time\": None\n            }\n            \n            self._save_context(context)\n            \n            safe_print(f\"📚 Agent入栈: {agent_name} (ID: {agent_id}, Level: {level})\")\n            \n            return agent_id\n    \n    def pop_agent(self, agent_id: str, final_output: str = \"\"):\n        \"\"\"\n        Agent出栈操作\n        \n        Args:\n            agent_id: Agent ID\n            final_output: 最终输出内容\n        \"\"\"\n        with self.lock:\n            stack = self._load_stack()\n            \n            # 从栈中移除\n            new_stack = [entry for entry in stack if entry[\"agent_id\"] != agent_id]\n            self._save_stack(new_stack)\n            \n            # 更新共享上下文中的Agent状态\n            context = self._load_context()\n            if agent_id in context[\"current\"][\"agents_status\"]:\n                end_time = datetime.now().isoformat()\n                context[\"current\"][\"agents_status\"][agent_id][\"status\"] = \"completed\"\n                context[\"current\"][\"agents_status\"][agent_id][\"final_output\"] = final_output\n                context[\"current\"][\"agents_status\"][agent_id][\"end_time\"] = end_time\n                \n                # 删除latest_thinking（已完成的agent不需要thinking，只保留final_output）\n                if \"latest_thinking\" in context[\"current\"][\"agents_status\"][agent_id]:\n                    del context[\"current\"][\"agents_status\"][agent_id][\"latest_thinking\"]\n                \n                # 更新时间历史\n                if agent_id in context.get(\"agent_time_history\", {}):\n                    context[\"agent_time_history\"][agent_id][\"end_time\"] = end_time\n            \n            self._save_context(context)\n            \n            # 检查是否当前栈已清空（无可 resume 的运行中 agent），若是则归档 current 到 history\n            self._check_and_complete_if_all_done()\n            \n            safe_print(f\"📚 Agent出栈: {agent_id}\")\n    \n    def update_thinking(self, agent_id: str, thinking: str):\n        \"\"\"\n        更新Agent的thinking（只保留最新的）\n        \n        Args:\n            agent_id: Agent ID\n            thinking: thinking内容\n        \"\"\"\n        with self.lock:\n            context = self._load_context()\n            \n            if agent_id in context[\"current\"][\"agents_status\"]:\n                context[\"current\"][\"agents_status\"][agent_id][\"latest_thinking\"] = thinking\n                context[\"current\"][\"agents_status\"][agent_id][\"thinking_updated_at\"] = datetime.now().isoformat()\n                self._save_context(context)\n\n    def get_loaded_skills(self, agent_id: str) -> List[Dict]:\n        \"\"\"获取当前 agent 已加载到上下文中的 skills。\"\"\"\n        context = self._load_context()\n        agent_info = context.get(\"current\", {}).get(\"agents_status\", {}).get(agent_id, {})\n        skills = agent_info.get(\"loaded_skills\", [])\n        return skills if isinstance(skills, list) else []\n\n    def add_loaded_skill(self, agent_id: str, skill_info: Dict):\n        \"\"\"向当前 agent 的上下文挂载一个 skill。\"\"\"\n        with self.lock:\n            context = self._load_context()\n            agent_info = context.get(\"current\", {}).get(\"agents_status\", {}).get(agent_id)\n            if not agent_info:\n                return\n            loaded = agent_info.get(\"loaded_skills\", [])\n            if not isinstance(loaded, list):\n                loaded = []\n            skill_name = skill_info.get(\"name\")\n            loaded = [s for s in loaded if s.get(\"name\") != skill_name]\n            loaded.append(skill_info)\n            agent_info[\"loaded_skills\"] = loaded\n            self._save_context(context)\n\n    def remove_loaded_skill(self, agent_id: str, skill_name: str):\n        \"\"\"从当前 agent 的上下文卸载一个 skill。\"\"\"\n        with self.lock:\n            context = self._load_context()\n            agent_info = context.get(\"current\", {}).get(\"agents_status\", {}).get(agent_id)\n            if not agent_info:\n                return\n            loaded = agent_info.get(\"loaded_skills\", [])\n            if not isinstance(loaded, list):\n                loaded = []\n            agent_info[\"loaded_skills\"] = [s for s in loaded if s.get(\"name\") != skill_name]\n            self._save_context(context)\n    \n    def add_action(self, agent_id: str, action: Dict):\n        \"\"\"\n        添加动作记录（仅用于兼容，实际action_history保存在单独文件中）\n        \n        Args:\n            agent_id: Agent ID\n            action: 动作记录\n        \"\"\"\n        # 不再在share_context中保存action_history\n        # action_history由ConversationStorage管理\n        pass\n    \n    def get_context(self) -> Dict:\n        \"\"\"获取完整的共享上下文\"\"\"\n        return self._load_context()\n    \n    def _check_and_complete_if_all_done(self):\n        \"\"\"\n        检查是否应将 current 归档到 history。\n        \n        关键逻辑：**以 stack 是否为空为准**（而不是 agents_status 是否都为 completed / 终态）。\n        \n        原因：\n        - 用户可能会人为中断/暂停任务（例如 Ctrl+C、需求变更），导致某些 agent 状态仍停留在 running，\n          但 stack 已被清空（不可 resume / 实际已无运行中的 agent）。\n        - 如果仍按 agents_status 判断，会出现 current 永远无法归档到 history 的问题。\n        \"\"\"\n        context = self._load_context()\n        current_agents = context.get(\"current\", {}).get(\"agents_status\", {})\n        \n        # 栈非空：说明仍存在运行链路，不能归档\n        stack = self._load_stack()\n        if stack:\n            return\n        \n        # 栈为空：仅当 current 有实际内容时才归档（避免空归档）\n        current_instructions = context.get(\"current\", {}).get(\"instructions\", [])\n        if not current_agents and not current_instructions:\n            return\n        \n        safe_print(\"🎉 当前栈已清空，移动current到history\")\n        \n        # 移动到history\n        history_entry = {\n            \"instructions\": context[\"current\"][\"instructions\"].copy(),\n            \"hierarchy\": context[\"current\"][\"hierarchy\"].copy(),\n            \"agents_status\": context[\"current\"][\"agents_status\"].copy(),\n            \"start_time\": context[\"current\"].get(\"start_time\"),\n            \"completion_time\": datetime.now().isoformat()\n        }\n        \n        context[\"history\"].append(history_entry)\n        \n        # 清空current\n        context[\"current\"] = {\n            \"instructions\": [],\n            \"hierarchy\": {},\n            \"agents_status\": {},\n            \"start_time\": datetime.now().isoformat(),\n            \"last_updated\": datetime.now().isoformat()\n        }\n        \n        # 清空栈（保持幂等）\n        self._save_stack([])\n        \n        self._save_context(context)\n        try:\n            from utils.task_history_index import sync_task_history_from_context\n            sync_task_history_from_context(self.task_id, context)\n        except Exception:\n            pass\n        safe_print(\"✅ 任务已归档到history\")\n    \n    def get_current_agent_id(self) -> Optional[str]:\n        \"\"\"获取当前栈顶的Agent ID\"\"\"\n        stack = self._load_stack()\n        return stack[-1][\"agent_id\"] if stack else None\n\n\n# 全局管理器缓存\n_managers_cache = {}\n_cache_lock = threading.Lock()\n\n\ndef get_hierarchy_manager(task_id: str) -> HierarchyManager:\n    \"\"\"\n    获取缓存的层级管理器实例\n    \n    Args:\n        task_id: 任务ID\n        \n    Returns:\n        HierarchyManager实例\n    \"\"\"\n    with _cache_lock:\n        cache_key = (str(task_id), str(get_user_conversations_dir()))\n        if cache_key not in _managers_cache:\n            _managers_cache[cache_key] = HierarchyManager(task_id)\n        return _managers_cache[cache_key]\n\n\nif __name__ == \"__main__\":\n    # 测试层级管理器\n    manager = HierarchyManager(\"test_task\")\n    safe_print(\"✅ 层级管理器初始化成功\")\n    \n    # 测试指令添加\n    instr_id = manager.start_new_instruction(\"测试任务\")\n    safe_print(f\"✅ 添加指令: {instr_id}\")\n    \n    # 测试Agent入栈\n    agent1_id = manager.push_agent(\"test_agent\", \"测试输入\")\n    safe_print(f\"✅ Agent入栈: {agent1_id}\")\n    \n    # 测试thinking更新\n    manager.update_thinking(agent1_id, \"这是一个测试thinking\")\n    safe_print(\"✅ Thinking更新成功\")\n    \n    # 测试动作添加\n    manager.add_action(agent1_id, {\n        \"tool_name\": \"file_read\",\n        \"arguments\": {\"path\": \"test.txt\"},\n        \"result\": {\"status\": \"success\"}\n    })\n    safe_print(\"✅ 动作记录成功\")\n"
  },
  {
    "path": "core/runtime_exceptions.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n运行时异常定义。\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, List, Optional\n\n\nclass InfiAgentRunError(RuntimeError):\n    \"\"\"SDK / 库模式下用于向外部抛出的统一运行时异常。\"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        *,\n        task_id: str = \"\",\n        agent_name: str = \"\",\n        stage: str = \"run\",\n        result: Optional[Dict[str, Any]] = None,\n        events: Optional[List[Dict[str, Any]]] = None,\n        trace: Optional[Dict[str, Any]] = None,\n    ):\n        super().__init__(message)\n        self.task_id = str(task_id or \"\")\n        self.agent_name = str(agent_name or \"\")\n        self.stage = str(stage or \"run\")\n        self.result = result or {}\n        self.events = list(events or [])\n        self.trace = trace\n\n    @classmethod\n    def from_result(\n        cls,\n        result: Optional[Dict[str, Any]],\n        *,\n        task_id: str = \"\",\n        agent_name: str = \"\",\n        stage: str = \"run\",\n        events: Optional[List[Dict[str, Any]]] = None,\n        trace: Optional[Dict[str, Any]] = None,\n    ) -> \"InfiAgentRunError\":\n        payload = result or {}\n        message = (\n            str(payload.get(\"error_information\") or \"\").strip()\n            or str(payload.get(\"error\") or \"\").strip()\n            or str(payload.get(\"output\") or \"\").strip()\n            or \"InfiAgent run failed\"\n        )\n        return cls(\n            message,\n            task_id=task_id,\n            agent_name=agent_name,\n            stage=stage,\n            result=payload,\n            events=events,\n            trace=trace,\n        )\n"
  },
  {
    "path": "core/state_cleaner.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n状态清理器 - 启动前清理栈和current状态\n参考原项目的smart_clean_for_restart逻辑\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\n# 确保可以导入\nif __name__ == \"__main__\":\n    sys.path.insert(0, str(Path(__file__).parent.parent))\n\nfrom core.hierarchy_manager import get_hierarchy_manager\n\n\ndef clean_before_start(task_id: str, new_user_input: str = None):\n    \"\"\"\n    启动前清理状态\n    \n    策略：\n    1. 如果用户输入改变 → 归档 running agents 到 history，清空 current\n    2. 如果用户输入相同 → 保留 running agents（续跑）\n    3. 仅在“新任务”时清空栈；续跑/恢复时必须保留栈（否则会出现 stack 为空但 current 仍为 running 的不一致状态，且无法 resume）\n    \n    Args:\n        task_id: 任务ID\n        new_user_input: 新的用户输入（用于判断是否续跑）\n    \"\"\"\n    try:\n        hierarchy_manager = get_hierarchy_manager(task_id)\n        context = hierarchy_manager._load_context()\n        \n        # 检查是否有current数据\n        if not context.get(\"current\") or not context[\"current\"].get(\"agents_status\"):\n            safe_print(\"ℹ️ 无需清理，状态为空\")\n            return\n        \n        current_agents = context[\"current\"][\"agents_status\"]\n        current_hierarchy = context[\"current\"][\"hierarchy\"]\n        \n        safe_print(f\"🧹 启动前清理状态...\")\n        safe_print(f\"   当前agents数量: {len(current_agents)}\")\n        \n        # 检查用户输入是否改变\n        last_instruction = context[\"current\"].get(\"instructions\", [])\n        is_same_task = False\n        \n        if last_instruction and new_user_input:\n            last_input = last_instruction[-1].get(\"instruction\", \"\")\n            is_same_task = (last_input == new_user_input)\n            if is_same_task:\n                safe_print(f\"   ℹ️ 检测到相同任务，将续跑\")\n        \n        # 分类：completed vs running\n        completed_agents = {}\n        completed_hierarchy = {}\n        running_agents = {}\n        running_count = 0\n        \n        for agent_id, agent_info in current_agents.items():\n            if agent_info.get(\"status\") == \"completed\":\n                # 保留已完成的\n                completed_agents[agent_id] = agent_info\n                if agent_id in current_hierarchy:\n                    completed_hierarchy[agent_id] = current_hierarchy[agent_id]\n                safe_print(f\"   ✅ 保留已完成: {agent_info.get('agent_name')}\")\n            else:\n                # 收集运行中的（准备归档）\n                running_agents[agent_id] = agent_info\n                running_count += 1\n                safe_print(f\"   📦 归档运行中: {agent_info.get('agent_name')}\")\n        \n        # 清理completed agents的children引用（移除running的children）\n        for agent_id, hierarchy_info in completed_hierarchy.items():\n            # 只保留completed的children\n            filtered_children = [\n                child_id for child_id in hierarchy_info.get(\"children\", [])\n                if child_id in completed_agents\n            ]\n            completed_hierarchy[agent_id][\"children\"] = filtered_children\n        \n        # ✅ 如果有 running agents 且任务改变，归档到 history\n        if running_count > 0 and not is_same_task:\n            # 找到顶层 running agent（Level 0，即直接调用的）\n            top_running = None\n            for agent_id, agent_info in running_agents.items():\n                parent = current_hierarchy.get(agent_id, {}).get(\"parent\")\n                if parent is None:  # 顶层\n                    top_running = (agent_id, agent_info)\n                    break\n            \n            if top_running:\n                agent_id, agent_info = top_running\n                \n                # 构造 final_output: latest_thinking + 子 agent 的 final_output\n                thinking = agent_info.get(\"latest_thinking\", \"(无思考记录)\")\n                \n                # 收集所有已完成的子 agent 的 final_output\n                children_outputs = []\n                for child_id, child_info in completed_agents.items():\n                    child_parent = completed_hierarchy.get(child_id, {}).get(\"parent\")\n                    if child_parent == agent_id and child_info.get(\"final_output\"):\n                        agent_name = child_info.get(\"agent_name\", \"unknown\")\n                        output = child_info.get(\"final_output\", \"\")\n                        children_outputs.append(f\"【{agent_name}】\\n{output}\")\n                \n                # 组合 final_output\n                final_output = f\"【中断任务归档】\\n\\n\"\n                final_output += f\"## 最新思考\\n{thinking}\\n\\n\"\n                \n                if children_outputs:\n                    final_output += f\"## 已完成的子任务\\n\"\n                    final_output += \"\\n\\n\".join(children_outputs)\n                else:\n                    final_output += \"## 已完成的子任务\\n(无)\"\n                \n                # 标记为 interrupted 并设置 final_output（语义更准确，且不会误导为“已成功完成”）\n                agent_info[\"status\"] = \"interrupted\"\n                agent_info[\"final_output\"] = final_output\n                # 尝试补齐 end_time（若缺失）\n                try:\n                    from datetime import datetime\n                    end_time = datetime.now().isoformat()\n                    agent_info[\"end_time\"] = end_time\n                    if agent_id in context.get(\"agent_time_history\", {}):\n                        context[\"agent_time_history\"][agent_id][\"end_time\"] = end_time\n                except Exception:\n                    pass\n                \n                # 移到 history\n                if \"history\" not in context:\n                    context[\"history\"] = []\n                \n                history_entry = {\n                    \"instructions\": context[\"current\"].get(\"instructions\", []),\n                    \"start_time\": context[\"current\"].get(\"start_time\", \"\"),\n                    \"completion_time\": context.get(\"agent_time_history\", {}).get(agent_id, {}).get(\"end_time\", \"\"),\n                    \"agents_status\": {\n                        agent_id: agent_info,\n                        **{k: v for k, v in completed_agents.items() \n                           if completed_hierarchy.get(k, {}).get(\"parent\") == agent_id}\n                    },\n                    \"hierarchy\": {\n                        agent_id: current_hierarchy.get(agent_id, {}),\n                        **{k: v for k, v in completed_hierarchy.items() \n                           if v.get(\"parent\") == agent_id}\n                    }\n                }\n                \n                context[\"history\"].append(history_entry)\n                safe_print(f\"   📦 已将中断任务归档到 history\")\n                safe_print(f\"      顶层 agent: {agent_info.get('agent_name')}\")\n                safe_print(f\"      子任务数: {len(children_outputs)}\")\n        \n        # 更新context\n        if not is_same_task:\n            # 新任务：清空 current\n            context[\"current\"][\"agents_status\"] = {}\n            context[\"current\"][\"hierarchy\"] = {}\n            context[\"current\"][\"instructions\"] = []\n            # 删除压缩的历史（如果有）\n            if \"_compressed_user_agent_history\" in context[\"current\"]:\n                del context[\"current\"][\"_compressed_user_agent_history\"]\n            if \"_compressed_user_agent_history_meta\" in context[\"current\"]:\n                del context[\"current\"][\"_compressed_user_agent_history_meta\"]\n            # 删除所有agent的结构化调用信息压缩缓存\n            keys_to_delete = [k for k in context[\"current\"].keys() if k.startswith(\"_compressed_structured_call_info_\")]\n            for key in keys_to_delete:\n                del context[\"current\"][key]\n            safe_print(f\"   🗑️ 清空 current，准备新任务\")\n        else:\n            # 续跑：保留 running agents\n            context[\"current\"][\"agents_status\"] = {**completed_agents, **running_agents}\n            # hierarchy 保留所有\n            safe_print(f\"   ♻️ 保留 running agents，继续任务\")\n            safe_print(f\"      Running: {running_count} 个\")\n            safe_print(f\"      Completed: {len(completed_agents)} 个\")\n        \n        # 保存\n        hierarchy_manager._save_context(context)\n        try:\n            from utils.task_history_index import sync_task_history_from_context\n            sync_task_history_from_context(task_id, context)\n        except Exception:\n            pass\n        \n        # 栈处理：\n        # - 新任务：清空栈（重新建立层级）\n        # - 续跑/恢复：保留栈（否则无法 resume，且会造成“stack 为空但 current 仍 running”）\n        if not is_same_task:\n            hierarchy_manager._save_stack([])\n            safe_print(f\"   栈已清空\")\n        else:\n            safe_print(f\"   栈保留（续跑/恢复）\")\n        \n        safe_print(f\"✅ 清理完成:\")\n        safe_print(f\"   保留: {len(completed_agents)} 个已完成agent\")\n        safe_print(f\"   删除: {running_count} 个运行中agent\")\n        # 栈状态在上面已打印\n    \n    except Exception as e:\n        safe_print(f\"⚠️ 清理失败: {e}\")\n        import traceback\n        traceback.print_exc()\n\n\nif __name__ == \"__main__\":\n    import sys\n    from pathlib import Path\n    sys.path.insert(0, str(Path(__file__).parent.parent))\n    \n    # 测试清理功能\n    clean_before_start(\"test_task_123\")\n"
  },
  {
    "path": "core/tool_executor.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n工具执行器 - 统一使用进程内 direct-tools 模式。\n\"\"\"\n\nimport json\nimport time\nimport uuid\nimport asyncio\nimport threading\nfrom typing import Dict, Any\n\nfrom tool_server_lite.registry import get_runtime_registry, get_runtime_registry_failures\nfrom utils.mcp_manager import call_mcp_tool\nfrom utils.tool_hooks import trigger_tool_hooks\n\nclass ToolExecutor:\n    \"\"\"工具执行器 - 统一使用进程内 direct-tools 模式\"\"\"\n    \n    # 危险工具列表（需要用户确认）\n    DANGEROUS_TOOLS = [\n        \"file_write\",      # 文件写入\n        \"execute_command\", # 执行命令\n    ]\n    \n    def __init__(\n        self,\n        config_loader,\n        hierarchy_manager,\n        direct_mode=False,\n        extra_event_handlers=None,\n        exit_on_error: bool = True,\n        raise_on_error: bool = False,\n        stream_llm_tokens: bool = False,\n    ):\n        \"\"\"\n        初始化工具执行器\n        \n        Args:\n            config_loader: 配置加载器\n            hierarchy_manager: 层级管理器\n            direct_mode: 兼容旧参数，当前始终使用进程内 direct-tools 模式\n        \"\"\"\n        self.config_loader = config_loader\n        self.hierarchy_manager = hierarchy_manager\n        self.direct_mode = True\n        self.extra_event_handlers = list(extra_event_handlers or [])\n        self.exit_on_error = bool(exit_on_error)\n        self.raise_on_error = bool(raise_on_error)\n        self.stream_llm_tokens = bool(stream_llm_tokens)\n        self._tools_registry = None  # 懒加载\n        safe_print(\"🔧 工具执行器: 进程内直接调用模式（无需 ToolServer）\")\n        \n        # 权限管理：task_id → auto_mode 映射\n        self.task_permissions = {}  # {task_id: {\"auto_mode\": True/False}}\n        self.agent_id = \"\"\n        self.agent_name = \"\"\n\n    def set_agent_context(self, *, agent_id: str = \"\", agent_name: str = \"\"):\n        self.agent_id = str(agent_id or \"\")\n        self.agent_name = str(agent_name or \"\")\n\n    def _agent_level(self) -> int:\n        try:\n            context = self.hierarchy_manager.get_context()\n            hierarchy = ((context or {}).get(\"current\") or {}).get(\"hierarchy\") or {}\n            return int(((hierarchy.get(self.agent_id) or {}).get(\"level\")) or 0)\n        except Exception:\n            return 0\n    \n    def _init_tools_registry(self):\n        \"\"\"\n        懒加载：初始化进程内工具注册表（与 server.py 的注册中心一致）\n        仅在 direct_mode=True 时使用\n        \"\"\"\n        if self._tools_registry is not None:\n            return\n        \n        safe_print(\"🔧 初始化进程内工具注册表...\")\n        self._tools_registry = get_runtime_registry(force_reload=True)\n        safe_print(f\"✅ 工具注册表初始化完成，共 {len(self._tools_registry)} 个工具\")\n    \n    def _call_direct(self, tool_name: str, arguments: Dict, task_id: str) -> Dict:\n        \"\"\"\n        进程内直接调用工具（不经过 HTTP）\n        \n        返回格式保持与旧工具执行层一致（data 被 json.dumps 到 output 字符串），\n        确保 agent_executor 中的后续处理逻辑（如 image_read base64 提取）兼容。\n        \"\"\"\n        try:\n            # 懒加载工具注册表\n            self._init_tools_registry()\n            \n            tool = self._tools_registry.get(tool_name)\n            if not tool:\n                failure_reason = \"\"\n                for item in get_runtime_registry_failures():\n                    if item.get(\"name\") == tool_name:\n                        failure_reason = item.get(\"error\", \"\")\n                        break\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error_information\": (\n                        f\"工具未注册到运行时: {tool_name}\"\n                        + (f\"（加载失败原因: {failure_reason}）\" if failure_reason else \"\")\n                    )\n                }\n            \n            safe_print(f\"   🔧 直接调用工具: {tool_name}\")\n            \n            # 调用工具（保持与既有工具返回格式兼容）\n            #\n            # 注意：部分工具（如 human_in_loop）只实现 execute_async（用于非阻塞等待），\n            # 在 direct_mode 下也必须支持，否则会触发 NotImplementedError。\n            if hasattr(tool, \"execute_async\") and callable(getattr(tool, \"execute_async\")):\n                # 在子线程里创建 event loop 执行，避免未来在已有 event loop 场景下崩溃\n                result_holder: Dict[str, Any] = {}\n                err_holder: Dict[str, Any] = {}\n\n                def _runner():\n                    try:\n                        loop = asyncio.new_event_loop()\n                        asyncio.set_event_loop(loop)\n                        try:\n                            coro = tool.execute_async(task_id, arguments)\n                            result_holder[\"tool_result\"] = loop.run_until_complete(coro)\n                        finally:\n                            loop.close()\n                    except Exception as e:\n                        err_holder[\"error\"] = e\n\n                t = threading.Thread(target=_runner, daemon=True)\n                t.start()\n                t.join()\n\n                if err_holder.get(\"error\") is not None:\n                    raise err_holder[\"error\"]\n                tool_result = result_holder.get(\"tool_result\")\n            else:\n                tool_result = tool.execute(task_id, arguments)\n            \n            # 包装返回值（保持与既有工具执行层的 output 字段格式一致）\n            wrapped_status = \"success\"\n            wrapped_error_information = \"\"\n            if isinstance(tool_result, dict):\n                inner_status = str(tool_result.get(\"status\") or \"\").strip().lower()\n                if inner_status:\n                    wrapped_status = inner_status\n                wrapped_error_information = str(\n                    tool_result.get(\"error_information\")\n                    or tool_result.get(\"error\")\n                    or \"\"\n                )\n            wrapped = {\n                \"status\": wrapped_status,\n                \"output\": json.dumps(tool_result, indent=2, ensure_ascii=False),\n                \"error_information\": wrapped_error_information\n            }\n            # 透传内部控制字段，供 agent_executor 处理特殊副作用（load/offload skill、fresh 等）\n            if isinstance(tool_result, dict):\n                for key, value in tool_result.items():\n                    if str(key).startswith(\"_\"):\n                        wrapped[key] = value\n            return wrapped\n        \n        except Exception as e:\n            try:\n                safe_print(f\"❌ 直接调用工具异常: {tool_name}: {str(e)[:300]}\")\n            except Exception:\n                pass\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error_information\": f\"直接调用工具失败: {str(e)}\"\n            }\n    \n    def set_task_permission(self, task_id: str, auto_mode: bool):\n        \"\"\"设置任务的权限模式\"\"\"\n        self.task_permissions[task_id] = {\"auto_mode\": auto_mode}\n        safe_print(f\"🔐 任务权限设置: {task_id} → auto_mode={auto_mode}\")\n    \n    def is_auto_mode(self, task_id: str) -> bool:\n        \"\"\"检查任务是否为自动模式（默认 True）\"\"\"\n        return self.task_permissions.get(task_id, {}).get(\"auto_mode\", True)\n    \n    def _request_tool_confirmation(self, tool_name: str, arguments: Dict[str, Any], task_id: str) -> bool:\n        \"\"\"\n        请求工具执行确认\n        \n        Returns:\n            True - 用户批准执行\n            False - 用户拒绝执行\n        \"\"\"\n        try:\n            # 生成唯一确认ID\n            confirm_id = f\"confirm_{tool_name}_{int(time.time())}_{uuid.uuid4().hex[:8]}\"\n            from tool_server_lite.tools.human_tools import (\n                create_tool_confirmation,\n                get_tool_confirmation_status,\n            )\n\n            created = create_tool_confirmation(confirm_id, task_id, tool_name, arguments)\n            if not created.get(\"success\"):\n                safe_print(\"⚠️  创建确认请求失败，默认拒绝执行\")\n                return False\n            \n            safe_print(f\"⏸️  等待用户确认: {tool_name}\")\n            \n            # 轮询等待用户响应（最多等待 300 秒）\n            max_wait = 300\n            check_interval = 2\n            elapsed = 0\n            \n            while elapsed < max_wait:\n                time.sleep(check_interval)\n                elapsed += check_interval\n                \n                try:\n                    result = get_tool_confirmation_status(confirm_id)\n                    if result.get(\"found\") and result.get(\"status\") == \"completed\":\n                        approved = result.get(\"result\") == \"approved\"\n                        if approved:\n                            safe_print(f\"✅ 用户批准执行: {tool_name}\")\n                        else:\n                            safe_print(f\"❌ 用户拒绝执行: {tool_name}\")\n                        return approved\n                except Exception:\n                    continue\n            \n            # 超时，默认拒绝\n            safe_print(f\"⏱️  确认超时，拒绝执行: {tool_name}\")\n            return False\n            \n        except Exception as e:\n            safe_print(f\"❌ 确认请求失败: {e}，拒绝执行\")\n            return False\n    \n    def execute(self, tool_name: str, arguments: Dict[str, Any], task_id: str) -> Dict:\n        \"\"\"\n        执行工具调用\n        \n        Args:\n            tool_name: 工具名称\n            arguments: 工具参数\n            task_id: 任务ID\n            \n        Returns:\n            执行结果字典\n        \"\"\"\n        try:\n            trigger_tool_hooks(\n                when=\"before\",\n                tool_name=tool_name,\n                task_id=task_id,\n                arguments=arguments,\n                agent_id=self.agent_id,\n                agent_name=self.agent_name,\n                agent_level=self._agent_level(),\n            )\n        except Exception:\n            pass\n\n        try:\n            # 获取工具配置\n            tool_config = self.config_loader.get_tool_config(tool_name)\n            tool_type = tool_config.get(\"type\")\n            \n            # 特殊处理final_output\n            if tool_name == \"final_output\":\n                result = {\n                    \"status\": arguments.get(\"status\", \"success\"),\n                    \"output\": arguments.get(\"output\", \"\"),\n                    \"error_information\": arguments.get(\"error_information\", \"\")\n                }\n            elif tool_type == \"tool_call_agent\":\n                if tool_name in self.DANGEROUS_TOOLS and not self.is_auto_mode(task_id):\n                    approved = self._request_tool_confirmation(tool_name, arguments, task_id)\n                    if not approved:\n                        result = {\n                            \"status\": \"error\",\n                            \"output\": \"\",\n                            \"error_information\": f\"工具执行被用户拒绝: {tool_name}\"\n                        }\n                    elif tool_config.get(\"_mcp\"):\n                        result = call_mcp_tool(tool_config, arguments)\n                    else:\n                        result = self._call_direct(tool_name, arguments, task_id)\n                elif tool_config.get(\"_mcp\"):\n                    result = call_mcp_tool(tool_config, arguments)\n                else:\n                    result = self._call_direct(tool_name, arguments, task_id)\n            elif tool_type == \"llm_call_agent\":\n                result = self._execute_sub_agent(tool_name, tool_config, arguments, task_id)\n            else:\n                result = {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error_information\": f\"不支持的工具类型: {tool_type}\"\n                }\n        except Exception as e:\n            result = {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error_information\": f\"工具执行失败: {str(e)}\"\n            }\n\n        try:\n            trigger_tool_hooks(\n                when=\"after\",\n                tool_name=tool_name,\n                task_id=task_id,\n                arguments=arguments,\n                result=result,\n                agent_id=self.agent_id,\n                agent_name=self.agent_name,\n                agent_level=self._agent_level(),\n            )\n        except Exception:\n            pass\n        return result\n    \n    def _execute_sub_agent(\n        self,\n        agent_name: str,\n        agent_config: Dict,\n        arguments: Dict,\n        task_id: str\n    ) -> Dict:\n        \"\"\"执行子Agent调用\"\"\"\n        try:\n            # 导入Agent执行器（避免循环导入）\n            from core.agent_executor import AgentExecutor\n            \n            # 获取任务输入\n            task_input = arguments.get(\"task_input\", \"\")\n            \n            # 创建子Agent执行器（传递 direct_mode 保持一致）\n            sub_agent = AgentExecutor(\n                agent_name=agent_name,\n                agent_config=agent_config,\n                config_loader=self.config_loader,\n                hierarchy_manager=self.hierarchy_manager,\n                direct_tools=self.direct_mode,\n                extra_event_handlers=self.extra_event_handlers,\n                exit_on_error=self.exit_on_error,\n                raise_on_error=self.raise_on_error,\n                stream_llm_tokens=self.stream_llm_tokens,\n            )\n            \n            # 执行子Agent\n            result = sub_agent.run(task_id, task_input)\n            \n            return result\n        \n        except Exception as e:\n            import traceback\n            error_detail = traceback.format_exc()\n            safe_print(f\"❌ 子Agent执行失败: {e}\")\n            safe_print(f\"详细错误:\\n{error_detail}\")\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error_information\": f\"子Agent执行失败: {str(e)}\\n{error_detail}\"\n            }\n\n\nif __name__ == \"__main__\":\n    from utils.config_loader import ConfigLoader\n    from core.hierarchy_manager import get_hierarchy_manager\n    \n    # 测试工具执行器\n    config_loader = ConfigLoader(\"infiHelper\")\n    hierarchy_manager = get_hierarchy_manager(\"test_task\")\n    \n    executor = ToolExecutor(config_loader, hierarchy_manager)\n    safe_print(f\"✅ 工具执行器初始化成功\")\n    safe_print(\"   Mode: direct-tools\")\n    \n    # 测试final_output\n    result = executor.execute(\"final_output\", {\n        \"task_id\": \"test\",\n        \"status\": \"success\",\n        \"output\": \"测试完成\"\n    }, \"test_task\")\n    \n    safe_print(f\"✅ final_output测试: {result}\")\n"
  },
  {
    "path": "desktop_app/package.json",
    "content": "{\n  \"name\": \"infiagent-desktop\",\n  \"version\": \"1.0.0\",\n  \"description\": \"infiAgent Desktop - AI Agent for long-running complex tasks\",\n  \"main\": \"src/main.js\",\n  \"scripts\": {\n    \"start\": \"cross-env ELECTRON_RUN_AS_NODE= electron .\",\n    \"build:mac\": \"rm -rf dist/mac-universal dist/mac-universal-* dist/infiAgent-*-universal.dmg dist/infiAgent-*-universal.dmg.blockmap && bash ../backend_build/build_mac_universal.sh && electron-builder --mac --arm64\",\n    \"build:mac:universal\": \"rm -rf dist/mac-universal dist/mac-universal-* dist/infiAgent-*-universal.dmg dist/infiAgent-*-universal.dmg.blockmap && MLA_BUILD_X64_BACKEND=1 bash ../backend_build/build_mac_universal.sh && electron-builder --mac --universal\",\n    \"build:mac:universal:dmg\": \"rm -rf dist/mac-universal dist/mac-universal-* dist/infiAgent-*-universal.dmg dist/infiAgent-*-universal.dmg.blockmap dist/infiAgent-*-universal-mac.zip dist/infiAgent-*-universal-mac.zip.blockmap && MLA_BUILD_X64_BACKEND=1 bash ../backend_build/build_mac_universal.sh && electron-builder --mac dmg --universal\",\n    \"build:win\": \"electron-builder --win\",\n    \"build:linux\": \"electron-builder --linux\"\n  },\n  \"build\": {\n    \"appId\": \"com.infiagent.desktop\",\n    \"productName\": \"infiAgent\",\n    \"directories\": {\n      \"output\": \"dist\"\n    },\n    \"mac\": {\n      \"category\": \"public.app-category.productivity\",\n      \"x64ArchFiles\": \"Contents/Resources/python-backend/**/{*,.*}/**\",\n      \"target\": [\n        \"dmg\",\n        \"zip\"\n      ],\n      \"icon\": \"../icon.png\",\n      \"darkModeSupport\": true\n    },\n    \"dmg\": {\n      \"title\": \"infiAgent\",\n      \"contents\": [\n        {\n          \"x\": 130,\n          \"y\": 220\n        },\n        {\n          \"x\": 410,\n          \"y\": 220,\n          \"type\": \"link\",\n          \"path\": \"/Applications\"\n        }\n      ],\n      \"window\": {\n        \"width\": 540,\n        \"height\": 380\n      }\n    },\n    \"win\": {\n      \"target\": [\n        \"nsis\"\n      ],\n      \"icon\": \"../icon.png\"\n    },\n    \"linux\": {\n      \"target\": [\n        \"AppImage\"\n      ],\n      \"icon\": \"../icon.png\"\n    },\n    \"files\": [\n      \"src/**/*\",\n      \"node_modules/**/*\"\n    ],\n    \"extraResources\": [\n      {\n        \"from\": \"backend_dist\",\n        \"to\": \"python-backend\"\n      },\n      {\n        \"from\": \"../skills\",\n        \"to\": \"python-backend/skills\"\n      },\n      {\n        \"from\": \"../config/agent_library\",\n        \"to\": \"python-backend/config/agent_library\"\n      },\n      {\n        \"from\": \"../config/run_env_config\",\n        \"to\": \"python-backend/config/run_env_config\",\n        \"filter\": [\n          \"**/*\",\n          \"!llm_config.yaml\"\n        ]\n      }\n    ],\n    \"asar\": false\n  },\n  \"devDependencies\": {\n    \"cross-env\": \"^7.0.3\",\n    \"electron\": \"^40.2.1\",\n    \"electron-builder\": \"^25.0.0\"\n  },\n  \"dependencies\": {\n    \"adm-zip\": \"^0.5.16\",\n    \"dompurify\": \"^3.3.1\",\n    \"js-yaml\": \"^4.1.0\",\n    \"marked\": \"^17.0.1\"\n  }\n}\n"
  },
  {
    "path": "desktop_app/src/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>infiAgent</title>\n  <link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n  <!-- Titlebar drag region (macOS hidden titlebar) -->\n  <div class=\"titlebar\"></div>\n\n  <div class=\"app-container\">\n    <!-- Sidebar -->\n    <aside class=\"sidebar\">\n      <div class=\"sidebar-header\">\n        <h1 class=\"app-title\">infiAgent</h1>\n        <button id=\"new-chat-btn\" class=\"new-chat-btn\" title=\"New Chat\">+</button>\n      </div>\n\n      <!-- Workspace selector -->\n      <div class=\"workspace-section\">\n        <button id=\"select-folder-btn\" class=\"workspace-btn\">\n          <span class=\"icon\">📁</span>\n          <span id=\"workspace-label\">Open new workspace…</span>\n        </button>\n        <div id=\"workspace-current\" class=\"workspace-current\">No workspace selected</div>\n      </div>\n\n      <!-- Agent system selector -->\n      <div class=\"sidebar-section\">\n        <label class=\"section-label\">Agent System</label>\n        <select id=\"agent-system-select\" class=\"sidebar-select\">\n          <option value=\"OpenCowork\">OpenCowork</option>\n          <option value=\"Researcher\">Researcher</option>\n        </select>\n      </div>\n\n      <!-- Conversations list -->\n      <div class=\"sidebar-section conversations-list\">\n        <div class=\"section-label-row\">\n          <label class=\"section-label\">History</label>\n          <button id=\"refresh-conversations-btn\" class=\"sidebar-icon-btn\" title=\"Refresh\">↻</button>\n        </div>\n        <div id=\"conversations\" class=\"conversations-scroll\">\n          <div class=\"empty-state\">Loading conversations...</div>\n        </div>\n      </div>\n\n      <!-- Sidebar footer -->\n      <div class=\"sidebar-footer\">\n        <button id=\"skills-btn\" class=\"sidebar-btn-text\" title=\"Import / Manage Skills\">Import skills</button>\n        <button id=\"market-btn\" class=\"sidebar-btn-text\" title=\"Marketplace\">Marketplace</button>\n        <button id=\"settings-btn\" class=\"sidebar-btn-icon\" title=\"Settings\">⚙️</button>\n      </div>\n    </aside>\n\n    <!-- Main chat area -->\n    <main class=\"chat-area\">\n      <!-- Messages -->\n      <div id=\"messages\" class=\"messages-container\">\n        <div class=\"welcome-message\">\n          <h2>Welcome to infiAgent</h2>\n          <p>Select a workspace folder to begin. Your agent will work within that directory.</p>\n          <div class=\"feature-cards\">\n            <div class=\"feature-card\">\n              <span class=\"feature-icon\">🔄</span>\n              <span class=\"feature-text\">Days-long tasks with resume</span>\n            </div>\n            <div class=\"feature-card\">\n              <span class=\"feature-icon\">🧠</span>\n              <span class=\"feature-text\">Persistent memory per workspace</span>\n            </div>\n            <div class=\"feature-card\">\n              <span class=\"feature-icon\">⚡</span>\n              <span class=\"feature-text\">Agent Skills support</span>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Input area -->\n      <div class=\"input-area\">\n        <div class=\"input-wrapper\">\n          <textarea id=\"user-input\" placeholder=\"Message infiAgent...\" rows=\"1\" disabled></textarea>\n          <button id=\"send-btn\" class=\"send-btn\" disabled>\n            <span class=\"send-icon\">↑</span>\n          </button>\n          <button id=\"stop-btn\" class=\"stop-btn\" style=\"display:none;\">\n            <span class=\"stop-icon\">■</span>\n          </button>\n        </div>\n        <div class=\"input-footer\">\n          <span id=\"status-text\" class=\"status-text\">Select a workspace to start</span>\n          <button id=\"auto-scroll-btn\" class=\"auto-scroll-btn\" title=\"Toggle auto scroll\">Auto Scroll: On</button>\n          <button id=\"resume-btn\" class=\"resume-btn\" style=\"display:none;\" title=\"Resume interrupted task\">Resume</button>\n        </div>\n      </div>\n    </main>\n  </div>\n\n  <!-- ==================== Settings Modal ==================== -->\n  <div id=\"settings-modal\" class=\"modal-overlay\" style=\"display:none;\">\n    <div class=\"modal-container\">\n      <div class=\"modal-header\">\n        <h2 class=\"modal-title\">Settings</h2>\n        <button id=\"settings-close-btn\" class=\"modal-close-btn\">✕</button>\n      </div>\n      \n      <!-- Tabs -->\n      <div class=\"modal-tabs\">\n        <button class=\"modal-tab active\" data-tab=\"api\">API Configuration</button>\n        <button class=\"modal-tab\" data-tab=\"model\">Model Settings</button>\n        <button class=\"modal-tab\" data-tab=\"agent\">Agent System</button>\n        <button class=\"modal-tab\" data-tab=\"env\">Environment</button>\n        <button class=\"modal-tab\" data-tab=\"yaml\">Raw YAML</button>\n      </div>\n      \n      <div class=\"modal-body\">\n        <!-- API Tab -->\n        <div id=\"tab-api\" class=\"tab-content active\">\n          <div class=\"form-group\">\n            <label class=\"form-label\">API Base URL</label>\n            <input type=\"text\" id=\"setting-base-url\" class=\"form-input\" placeholder=\"https://api.openai.com/v1\">\n          </div>\n          <div class=\"form-group\">\n            <label class=\"form-label\">API Key</label>\n            <div class=\"password-wrapper\">\n              <input type=\"password\" id=\"setting-api-key\" class=\"form-input\" placeholder=\"sk-...\">\n              <button id=\"toggle-api-key\" class=\"toggle-password-btn\">👁</button>\n            </div>\n          </div>\n          <div class=\"form-group\">\n            <label class=\"form-label\">Timeout (seconds)</label>\n            <input type=\"number\" id=\"setting-timeout\" class=\"form-input\" placeholder=\"600\">\n          </div>\n          <div class=\"form-group\">\n            <label class=\"form-label\">Stream Timeout (seconds)</label>\n            <input type=\"number\" id=\"setting-stream-timeout\" class=\"form-input\" placeholder=\"30\">\n          </div>\n          <div class=\"form-group\">\n            <label class=\"form-label\">First Chunk Timeout (seconds)</label>\n            <input type=\"number\" id=\"setting-first-chunk-timeout\" class=\"form-input\" placeholder=\"30\">\n            <p class=\"form-hint-block\">应用层强制：连接建立 + 首包接收的最大时间（防止连接池/网络卡死）。</p>\n          </div>\n        </div>\n        \n        <!-- Model Tab -->\n        <div id=\"tab-model\" class=\"tab-content\">\n          <div class=\"form-hint-block\">\n            API 页签里填写的是默认 <code>base_url</code> 和 <code>api_key</code>。这里的每条模型都可以选择复用默认凭据，\n            也可以切到自定义 source，单独填写 URL / Key。Shared Models 会自动应用到所有功能分区。\n          </div>\n\n          <details class=\"tool-details\" open>\n            <summary class=\"tool-params-toggle\">Shared Models (apply to all slots)</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">共享模型会同时写入主模型、读图、生图、压缩、thinking 五个分区。</span>\n              <button id=\"add-shared-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Shared Model</button>\n            </div>\n            <div id=\"model-shared-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <details class=\"tool-details\" open>\n            <summary class=\"tool-params-toggle\">Main Models</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">主执行模型，可配置多候选顺序。</span>\n              <button id=\"add-main-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Main Model</button>\n            </div>\n            <div id=\"model-main-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <details class=\"tool-details\">\n            <summary class=\"tool-params-toggle\">Read Figure Models</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">图片理解 / 读图场景。</span>\n              <button id=\"add-read-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Read Figure Model</button>\n            </div>\n            <div id=\"model-read-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <details class=\"tool-details\">\n            <summary class=\"tool-params-toggle\">Figure Generation Models</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">生图模型列表。</span>\n              <button id=\"add-figure-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Figure Model</button>\n            </div>\n            <div id=\"model-figure-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <details class=\"tool-details\">\n            <summary class=\"tool-params-toggle\">Compressor Models</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">历史压缩 / 摘要模型。</span>\n              <button id=\"add-compressor-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Compressor Model</button>\n            </div>\n            <div id=\"model-compressor-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <details class=\"tool-details\">\n            <summary class=\"tool-params-toggle\">Thinking Models</summary>\n            <div class=\"model-slot-toolbar\">\n              <span class=\"form-hint\">Thinking Agent 专用模型。</span>\n              <button id=\"add-thinking-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Thinking Model</button>\n            </div>\n            <div id=\"model-thinking-list\" class=\"model-slot-list\"></div>\n          </details>\n\n          <p class=\"form-hint-block\">Raw YAML 仍然保留完整高级能力；保存本页后 Raw YAML 会立刻同步刷新。</p>\n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Temperature</label>\n              <input type=\"number\" id=\"setting-temperature\" class=\"form-input\" step=\"0.1\" min=\"0\" max=\"2\" placeholder=\"0\">\n            </div>\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Max Tokens</label>\n              <input type=\"number\" id=\"setting-max-tokens\" class=\"form-input\" placeholder=\"0 = auto\">\n            </div>\n          </div>\n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Max Context Window</label>\n              <input type=\"number\" id=\"setting-max-context\" class=\"form-input\" placeholder=\"500000\">\n            </div>\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">\n                <input type=\"checkbox\" id=\"setting-multimodal\"> Multimodal\n              </label>\n            </div>\n          </div>\n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">\n                <input type=\"checkbox\" id=\"setting-compressor-multimodal\"> Compressor Multimodal\n              </label>\n            </div>\n          </div>\n        </div>\n        \n        <!-- Agent System Tab -->\n        <div id=\"tab-agent\" class=\"tab-content\">\n          <div class=\"form-group\">\n            <label class=\"form-label\">Active Agent System</label>\n            <select id=\"setting-agent-system\" class=\"form-input\">\n              <!-- Populated dynamically -->\n            </select>\n            <div class=\"form-row\" style=\"margin-top:10px; gap:10px;\">\n              <button id=\"import-agent-system-btn\" class=\"btn-secondary\" type=\"button\">Import Agent System Folder…</button>\n              <button id=\"delete-agent-system-btn\" class=\"btn-secondary\" type=\"button\">Delete Selected (User)…</button>\n            </div>\n            <p class=\"form-hint-block\">\n              Agent System defines the available tools, agents and prompts.\n              Bundled systems live in <code>config/agent_library/</code>.\n              Imported systems will be copied to <code>~/mla_v3/agent_library/</code>.\n            </p>\n          </div>\n          \n          <div class=\"form-divider\"></div>\n          \n          <div class=\"form-group\">\n            <label class=\"form-label\">Config File Location</label>\n            <p id=\"config-path-display\" class=\"config-path\">—</p>\n          </div>\n        </div>\n\n        <!-- Environment Tab -->\n        <div id=\"tab-env\" class=\"tab-content\">\n          <div class=\"form-group\">\n            <label class=\"form-label\">Command Execution Mode</label>\n            <select id=\"setting-command-mode\" class=\"form-input\">\n              <option value=\"direct\">Direct (default, backend subprocess)</option>\n              <option value=\"system_terminal\">System Terminal (macOS only, use Terminal.app permissions)</option>\n            </select>\n            <p class=\"form-hint-block\">\n              仅影响 <code>execute_command</code>。选择 System Terminal 后，命令会通过 Terminal.app 执行，\n              可用于对齐终端侧权限（如录屏相关场景）。\n            </p>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">PATH Mode</label>\n            <select id=\"setting-path-mode\" class=\"form-input\">\n              <option value=\"system\">System (path_helper + common paths)</option>\n              <option value=\"zsh_login_interactive\">Zsh login+interactive (closest to Terminal, may be slow)</option>\n            </select>\n            <p class=\"form-hint-block\">\n              桌面端从 Finder 启动时不会加载 <code>~/.zshrc</code>。此处用于让后端/execute_command 更接近你终端里的工具环境。\n            </p>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Extra PATH entries <span class=\"form-hint\">(one per line)</span></label>\n            <textarea id=\"setting-extra-path\" class=\"form-textarea\" rows=\"4\" placeholder=\"/opt/anaconda3/bin&#10;/opt/homebrew/bin\"></textarea>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Extra environment variables <span class=\"form-hint\">(KEY=VALUE per line)</span></label>\n            <textarea id=\"setting-extra-env\" class=\"form-textarea\" rows=\"4\" placeholder=\"HTTP_PROXY=http://127.0.0.1:7890\"></textarea>\n          </div>\n\n          <div class=\"form-divider\"></div>\n          \n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">\n                <input type=\"checkbox\" id=\"setting-thinking-enabled\"> Enable Thinking Agent Mode\n              </label>\n            </div>\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Thinking Steps</label>\n              <input type=\"number\" id=\"setting-thinking-steps\" class=\"form-input\" min=\"1\" placeholder=\"30\">\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">No-tool Retry Limit</label>\n            <input type=\"number\" id=\"setting-no-tool-retry-limit\" class=\"form-input\" min=\"1\" placeholder=\"7\">\n            <p class=\"form-hint-block\">\n              仅在 Thinking Agent 模式下使用。表示模型连续多少次未调用工具后，框架会强提醒并最终报错。\n            </p>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Max Turns</label>\n            <input type=\"number\" id=\"setting-max-turns\" class=\"form-input\" min=\"1\" placeholder=\"100000\">\n            <p class=\"form-hint-block\">\n              单次 agent loop 的最大轮次上限。默认保持高上限，只有你想强行限制任务成本或时长时再收紧。\n            </p>\n          </div>\n\n          <div class=\"form-divider\"></div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">User History Compress Threshold (tokens)</label>\n            <input type=\"number\" id=\"setting-user-history-threshold\" class=\"form-input\" min=\"0\" placeholder=\"1500\">\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Recent History Items</label>\n            <input type=\"number\" id=\"setting-user-history-recent-items\" class=\"form-input\" min=\"0\" placeholder=\"0 = all history\">\n            <p class=\"form-hint-block\">\n              0 表示沿用旧行为：读取全部历史任务后再按 token 阈值决定是否压缩。大于 0 时只读取最近 N 条历史任务。\n            </p>\n          </div>\n\n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Structured Call Compress Agent Threshold</label>\n              <input type=\"number\" id=\"setting-structured-call-agent-threshold\" class=\"form-input\" min=\"1\" placeholder=\"10\">\n            </div>\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Structured Call Compress Token Threshold</label>\n              <input type=\"number\" id=\"setting-structured-call-token-threshold\" class=\"form-input\" min=\"0\" placeholder=\"2200\">\n            </div>\n          </div>\n\n          <div class=\"form-row\">\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">\n                <input type=\"checkbox\" id=\"setting-fresh-enabled\"> Enable scheduled fresh\n              </label>\n            </div>\n            <div class=\"form-group form-half\">\n              <label class=\"form-label\">Fresh Interval (seconds)</label>\n              <input type=\"number\" id=\"setting-fresh-interval-sec\" class=\"form-input\" min=\"0\" placeholder=\"0 = disabled\">\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Skills Root</label>\n            <p class=\"config-path\"><code>~/.agent/skills</code></p>\n            <p class=\"form-hint-block\">\n              这是当前主 skills 目录。导入 skill 或首次播种后，技能会放在这个目录下。\n            </p>\n            <div class=\"form-row\" style=\"margin-top:10px; gap:10px;\">\n              <button id=\"fresh-runtime-btn\" class=\"btn-secondary\" type=\"button\">Fresh Runtime</button>\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">MCP Servers <span class=\"form-hint\">(one per line: JSON / name=url / url)</span></label>\n            <textarea id=\"setting-mcp-servers\" class=\"form-textarea\" rows=\"5\" placeholder='{\"name\":\"github\",\"transport\":\"streamable_http\",\"url\":\"https://example.com/mcp\"}&#10;github=https://example.com/mcp&#10;https://example.com/mcp'></textarea>\n            <p class=\"form-hint-block\">\n              MCP server 本身不是本地工具类。系统会连接这些 server，发现它们暴露的 tools，并把这些 tools 自动加入当前 agent 的可见工具集中。\n            </p>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Visible Skills <span class=\"form-hint\">(one per line, optional)</span></label>\n            <textarea id=\"setting-visible-skills\" class=\"form-textarea\" rows=\"4\" placeholder=\"browser-use&#10;paper-analyze\"></textarea>\n            <p class=\"form-hint-block\">\n              若填写，则只向当前 agent 暴露这些 skills。留空表示暴露全部可见 skills。\n            </p>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"form-label\">Marketplace Base URL</label>\n            <input type=\"text\" id=\"setting-market-url\" class=\"form-input\" placeholder=\"http://101.200.231.88\">\n            <p class=\"form-hint-block\">\n              用于 Skills + Agent System 市场。你可以部署一个 FastAPI 市场服务，并在此配置地址，然后在侧边栏 Marketplace 一键安装。\n            </p>\n          </div>\n        </div>\n\n        <!-- Raw YAML Tab -->\n        <div id=\"tab-yaml\" class=\"tab-content\">\n          <div class=\"form-group\">\n            <label class=\"form-label\">llm_config.yaml (raw)</label>\n            <textarea id=\"setting-raw-yaml\" class=\"form-textarea\" rows=\"14\" placeholder=\"Paste full llm_config.yaml here\"></textarea>\n            <p class=\"form-hint-block\">\n              该模式会<strong>原样保存</strong> YAML，不会丢字段；支持标准示例里的对象格式（每模型独立 api_key/base_url）。\n              保存后下次启动任务会自动生效。\n            </p>\n          </div>\n        </div>\n      </div>\n      \n      <div class=\"modal-footer\">\n        <span id=\"settings-status\" class=\"settings-status\"></span>\n        <button id=\"settings-save-btn\" class=\"btn-primary\">Save Settings</button>\n      </div>\n    </div>\n  </div>\n\n  <!-- ==================== Skills Modal ==================== -->\n  <div id=\"skills-modal\" class=\"modal-overlay\" style=\"display:none;\">\n    <div class=\"modal-container\">\n      <div class=\"modal-header\">\n        <h2 class=\"modal-title\">Skills Library</h2>\n        <button id=\"skills-close-btn\" class=\"modal-close-btn\">✕</button>\n      </div>\n      \n      <div class=\"modal-body\">\n        <p class=\"modal-description\">Import skill folders into <code>~/.agent/skills/</code>. Each skill folder should contain a <code>SKILL.md</code> file with frontmatter.</p>\n        \n        <div class=\"skills-toolbar\">\n          <button id=\"import-skill-btn\" class=\"btn-primary\">\n            <span>📂</span> Import Skill Folder\n          </button>\n          <button id=\"refresh-skills-btn\" class=\"sidebar-icon-btn\" title=\"Refresh\">↻</button>\n        </div>\n        \n        <div id=\"skills-list\" class=\"skills-list\">\n          <div class=\"empty-state\">No skills imported yet</div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- ==================== Marketplace Modal ==================== -->\n  <div id=\"market-modal\" class=\"modal-overlay\" style=\"display:none;\">\n    <div class=\"modal-container\">\n      <div class=\"modal-header\">\n        <h2 class=\"modal-title\">Marketplace</h2>\n        <button id=\"market-close-btn\" class=\"modal-close-btn\">✕</button>\n      </div>\n      <div class=\"modal-body\">\n        <div class=\"skills-toolbar\">\n          <input id=\"market-search\" class=\"form-input\" style=\"flex:1;\" placeholder=\"Search skills / agent systems...\">\n          <button id=\"market-refresh-btn\" class=\"sidebar-icon-btn\" title=\"Refresh\">↻</button>\n        </div>\n        <div class=\"form-row\" style=\"margin-top:10px; gap:10px;\">\n          <button id=\"market-tab-skills\" class=\"btn-secondary\" type=\"button\">Skills</button>\n          <button id=\"market-tab-systems\" class=\"btn-secondary\" type=\"button\">Agent Systems</button>\n        </div>\n        <div id=\"market-status\" class=\"settings-status\" style=\"margin-top:10px;\"></div>\n        <div id=\"market-list\" class=\"skills-list\" style=\"margin-top:10px;\"></div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Markdown renderer (safe) -->\n  <script src=\"../node_modules/marked/lib/marked.umd.js\"></script>\n  <script src=\"../node_modules/dompurify/dist/purify.min.js\"></script>\n\n  <script src=\"renderer.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "desktop_app/src/main.js",
    "content": "const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');\nconst path = require('path');\nconst fs = require('fs');\nconst { spawn } = require('child_process');\nconst childProcess = require('child_process');\nconst yaml = require('js-yaml');\nconst os = require('os');\nconst crypto = require('crypto');\nconst AdmZip = require('adm-zip');\n\nlet mainWindow;\nlet pythonProcess = null;\nlet currentTaskLogger = null;\n\n// ==================== Path Helpers ====================\n\n// Python backend path (development vs packaged)\nfunction getPythonBackendPath() {\n  if (app.isPackaged) {\n    return path.join(process.resourcesPath, 'python-backend');\n  }\n  return path.join(__dirname, '..', '..');\n}\n\nfunction getPackagedBackendArchDir() {\n  // For universal app, we ship two PyInstaller backends and select at runtime.\n  // Layout inside resources:\n  //   resources/python-backend/darwin-arm64/mlav3-backend/mlav3-backend\n  //   resources/python-backend/darwin-x64/mlav3-backend/mlav3-backend\n  // Later we can extend for win32/linux similarly.\n  if (process.platform === 'darwin') {\n    if (process.arch === 'arm64') return 'darwin-arm64';\n    if (process.arch === 'x64') return 'darwin-x64';\n  }\n  // Fallback: use platform-arch\n  return `${process.platform}-${process.arch}`;\n}\n\nfunction getPackagedBackendExecutablePath() {\n  const backendRoot = getPythonBackendPath();\n  const archDir = getPackagedBackendArchDir();\n  const exeName = process.platform === 'win32' ? 'mlav3-backend.exe' : 'mlav3-backend';\n  // PyInstaller --onedir default: <dist>/<name>/<name>\n  return path.join(backendRoot, archDir, 'mlav3-backend', exeName);\n}\n\nfunction getPackagedBackendPlaywrightBrowsersPath() {\n  const backendRoot = getPythonBackendPath();\n  const archDir = getPackagedBackendArchDir();\n  return path.join(\n    backendRoot,\n    archDir,\n    'mlav3-backend',\n    '_internal',\n    'playwright',\n    'driver',\n    'package',\n    '.local-browsers'\n  );\n}\n\nfunction getBackendLaunchSpecDev(userInput, workspacePath, agentName, agentSystem, appendTimestamp) {\n  const backendPath = getPythonBackendPath();\n  const startScript = path.join(backendPath, 'start.py');\n  const now = new Date();\n  const timestamp = now.toISOString().slice(0, 19).replace('T', ' ');\n  const ui = appendTimestamp ? `${userInput} [时间: ${timestamp}]` : userInput;\n  const args = [\n    startScript,\n    '--task_id', workspacePath,\n    '--agent_name', agentName || 'alpha_agent',\n    '--user_input', ui,\n    '--agent_system', agentSystem || 'OpenCowork',\n    '--jsonl',\n    '--direct-tools'\n  ];\n  return { command: 'python3', args, cwd: backendPath };\n}\n\nfunction getBackendLaunchSpecPackaged(userInput, workspacePath, agentName, agentSystem, appendTimestamp) {\n  const backendPath = getPythonBackendPath();\n  const backendExe = getPackagedBackendExecutablePath();\n  const now = new Date();\n  const timestamp = now.toISOString().slice(0, 19).replace('T', ' ');\n  const ui = appendTimestamp ? `${userInput} [时间: ${timestamp}]` : userInput;\n  const args = [\n    '--task_id', workspacePath,\n    '--agent_name', agentName || 'alpha_agent',\n    '--user_input', ui,\n    '--agent_system', agentSystem || 'OpenCowork',\n    '--jsonl',\n    '--direct-tools'\n  ];\n  return { command: backendExe, args, cwd: backendPath };\n}\n\n// User data root: ~/mla_v3/\nfunction getUserDataRoot() {\n  return path.join(os.homedir(), 'mla_v3');\n}\n\nfunction getUserConfigDir() {\n  return path.join(getUserDataRoot(), 'config');\n}\n\nfunction getAppConfigPath() {\n  return path.join(getUserConfigDir(), 'app_config.json');\n}\n\n// LLM config file path\nfunction getLlmConfigPath() {\n  // Always store user-editable config under ~/mla_v3/config/\n  return path.join(getUserConfigDir(), 'llm_config.yaml');\n}\n\nfunction defaultAppConfig() {\n  return {\n    env: {\n      // system: use /usr/libexec/path_helper + common paths\n      // zsh_login_interactive: use zsh -lic to get PATH (more terminal-like, may have side effects)\n      shell_mode: 'system',\n      // direct: run execute_command in backend process\n      // system_terminal: macOS only, execute_command is proxied via Terminal.app\n      command_mode: 'direct',\n      extra_path: [],\n      // additional env vars to inject into backend + execute_command\n      extra_env: {}\n    },\n    runtime: {\n      action_window_steps: 30,\n      thinking_interval: 30,\n      thinking_enabled: true,\n      thinking_steps: 30,\n      no_tool_retry_limit: 7,\n      visible_skills: [],\n      max_turns: 100000,\n      fresh_enabled: false,\n      fresh_interval_sec: 0\n    },\n    context: {\n      user_history_compress_threshold_tokens: 1500,\n      user_history_recent_items: 0,\n      structured_call_info_compress_threshold_agents: 10,\n      structured_call_info_compress_threshold_tokens: 2200\n    },\n    mcp: {\n      servers: []\n    },\n    market: {\n      // Default marketplace (user can change in Settings → Environment)\n      base_url: 'http://101.200.231.88'\n    }\n  };\n}\n\nfunction safeReadJsonFile(filePath) {\n  try {\n    if (!fs.existsSync(filePath)) return null;\n    const content = fs.readFileSync(filePath, 'utf-8');\n    return JSON.parse(content);\n  } catch (_) {\n    return null;\n  }\n}\n\nfunction ensureUserAppConfigExists() {\n  ensureUserDataRootScaffold();\n  const p = getAppConfigPath();\n  if (fs.existsSync(p)) return p;\n  fs.writeFileSync(p, JSON.stringify(defaultAppConfig(), null, 2) + '\\n', 'utf-8');\n  return p;\n}\n\nfunction readAppConfig() {\n  ensureUserAppConfigExists();\n  const raw = safeReadJsonFile(getAppConfigPath());\n  if (!raw || typeof raw !== 'object') return defaultAppConfig();\n  const base = defaultAppConfig();\n  // shallow merge\n  const out = { ...base, ...raw };\n  out.env = { ...base.env, ...(raw.env || {}) };\n  out.runtime = { ...base.runtime, ...(raw.runtime || {}) };\n  out.context = { ...base.context, ...(raw.context || {}) };\n  out.mcp = { ...base.mcp, ...(raw.mcp || {}) };\n  out.market = { ...base.market, ...(raw.market || {}) };\n  // normalize types\n  if (!Array.isArray(out.env.extra_path)) out.env.extra_path = [];\n  if (!out.env.extra_env || typeof out.env.extra_env !== 'object') out.env.extra_env = {};\n  if (typeof out.env.command_mode !== 'string' || !out.env.command_mode.trim()) out.env.command_mode = 'direct';\n  if (!Array.isArray(out.mcp.servers)) out.mcp.servers = [];\n  if (typeof out.market.base_url !== 'string') out.market.base_url = '';\n  if (!Array.isArray(out.runtime.visible_skills)) out.runtime.visible_skills = [];\n  return out;\n}\n\nfunction stripApiKeysFromYaml(yamlText) {\n  // Best-effort sanitizer: blank any `api_key:` values (including nested model entries).\n  // Keep file otherwise unchanged to preserve advanced YAML structures.\n  if (typeof yamlText !== 'string') return '';\n  return yamlText.replace(/^(\\s*api_key\\s*:\\s*).*/gm, '$1\"\"');\n}\n\nfunction _parsePathFromPathHelperOutput(text) {\n  // path_helper -s output example:\n  //   PATH=\"/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin\"; export PATH;\n  if (!text) return null;\n  const m = String(text).match(/PATH=\"([^\"]*)\"/);\n  if (!m) return null;\n  return m[1];\n}\n\nfunction getSystemPathFromPathHelper() {\n  try {\n    const out = childProcess.execFileSync('/usr/libexec/path_helper', ['-s'], {\n      encoding: 'utf-8',\n      timeout: 1500\n    });\n    return _parsePathFromPathHelperOutput(out);\n  } catch (_) {\n    return null;\n  }\n}\n\nfunction getZshLoginInteractivePath() {\n  try {\n    // zsh -lic: reads login + interactive configs (closest to user's terminal env)\n    const out = childProcess.execFileSync('/bin/zsh', ['-lic', 'echo -n \"$PATH\"'], {\n      encoding: 'utf-8',\n      timeout: 4000\n    });\n    const p = String(out || '').trim();\n    return p || null;\n  } catch (_) {\n    return null;\n  }\n}\n\nfunction computeEffectivePath(appCfg) {\n  const mode = appCfg?.env?.shell_mode || 'system';\n\n  let basePath = null;\n  if (mode === 'zsh_login_interactive') {\n    basePath = getZshLoginInteractivePath();\n  }\n  if (!basePath) {\n    basePath = getSystemPathFromPathHelper() || process.env.PATH || '';\n  }\n\n  const baseParts = basePath.split(':').filter(Boolean);\n  const extraParts = Array.isArray(appCfg?.env?.extra_path) ? appCfg.env.extra_path : [];\n\n  // Common user tool locations (best-effort; harmless if missing)\n  const common = [\n    '/opt/homebrew/bin',\n    '/opt/homebrew/sbin',\n    '/usr/local/bin',\n    '/usr/local/sbin',\n    '/opt/anaconda3/bin',\n    '/opt/anaconda3/condabin'\n  ];\n\n  const all = [...common, ...baseParts, ...extraParts].map(s => String(s || '').trim()).filter(Boolean);\n  const seen = new Set();\n  const dedup = [];\n  for (const p of all) {\n    if (seen.has(p)) continue;\n    seen.add(p);\n    dedup.push(p);\n  }\n  return dedup.join(':');\n}\n\nfunction buildRuntimeEnv() {\n  const appCfg = readAppConfig();\n  const env = { ...process.env };\n  env.PATH = computeEffectivePath(appCfg);\n  env.MLA_EXECUTE_COMMAND_MODE = (appCfg?.env?.command_mode === 'system_terminal') ? 'system_terminal' : 'direct';\n  env.MLA_ACTION_WINDOW_STEPS = String(appCfg?.runtime?.action_window_steps || 30);\n  env.MLA_THINKING_INTERVAL = String(appCfg?.runtime?.thinking_interval || appCfg?.runtime?.action_window_steps || 30);\n  env.MLA_THINKING_ENABLED = appCfg?.runtime?.thinking_enabled !== false ? 'true' : 'false';\n  env.MLA_THINKING_STEPS = String(appCfg?.runtime?.thinking_steps || appCfg?.runtime?.thinking_interval || appCfg?.runtime?.action_window_steps || 30);\n  env.MLA_NO_TOOL_RETRY_LIMIT = String(appCfg?.runtime?.no_tool_retry_limit || 7);\n  env.MLA_MAX_TURNS = String(appCfg?.runtime?.max_turns || 100000);\n  env.MLA_FRESH_ENABLED = appCfg?.runtime?.fresh_enabled ? 'true' : 'false';\n  env.MLA_FRESH_INTERVAL_SEC = String(appCfg?.runtime?.fresh_interval_sec || 0);\n  env.MLA_VISIBLE_SKILLS_JSON = JSON.stringify(Array.isArray(appCfg?.runtime?.visible_skills) ? appCfg.runtime.visible_skills : []);\n  env.MLA_SKILLS_LIBRARY_DIR = getSkillsLibraryPath();\n\n  // Encourage consistent unicode behavior\n  env.LANG = env.LANG || 'en_US.UTF-8';\n  env.LC_ALL = env.LC_ALL || 'en_US.UTF-8';\n\n  // Inject extra env\n  const extraEnv = appCfg?.env?.extra_env || {};\n  for (const [k, v] of Object.entries(extraEnv)) {\n    const key = String(k || '').trim();\n    if (!key) continue;\n    env[key] = String(v ?? '');\n  }\n\n  return env;\n}\n\nfunction ensureUserDataRootScaffold() {\n  // Create user-writable dirs under ~/mla_v3 (do not overwrite user files).\n  fs.mkdirSync(getUserDataRoot(), { recursive: true });\n  fs.mkdirSync(getUserConfigDir(), { recursive: true });\n  fs.mkdirSync(getSkillsLibraryPath(), { recursive: true });\n  fs.mkdirSync(getUserAgentLibraryPath(), { recursive: true });\n  fs.mkdirSync(getConversationsPath(), { recursive: true });\n  fs.mkdirSync(getLogsPath(), { recursive: true });\n\n  // Migrate old ~/mla_v3/skills_library -> ~/.agent/skills if needed.\n  try {\n    const oldSkillsRoot = path.join(getUserDataRoot(), 'skills_library');\n    if (fs.existsSync(oldSkillsRoot)) {\n      const entries = fs.readdirSync(oldSkillsRoot, { withFileTypes: true });\n      for (const e of entries) {\n        if (!e.isDirectory() || e.name.startsWith('.')) continue;\n        const src = path.join(oldSkillsRoot, e.name);\n        const dst = path.join(getSkillsLibraryPath(), e.name);\n        if (fs.existsSync(dst)) continue;\n        copyDirSync(src, dst);\n      }\n    }\n  } catch (_) {}\n\n  // Seed default bundled skills (best-effort; never overwrite existing ones)\n  try {\n    const bundledSkillsDir = path.join(getPythonBackendPath(), 'skills');\n    if (fs.existsSync(bundledSkillsDir)) {\n      const entries = fs.readdirSync(bundledSkillsDir, { withFileTypes: true });\n      for (const e of entries) {\n        if (!e.isDirectory() || e.name.startsWith('.')) continue;\n        const src = path.join(bundledSkillsDir, e.name);\n        const dst = path.join(getSkillsLibraryPath(), e.name);\n        if (fs.existsSync(dst)) continue; // do not overwrite user skill\n        copyDirSync(src, dst);\n      }\n    }\n  } catch (_) {\n    // Seeding skills should never block app startup\n  }\n\n  // Seed bundled agent systems into ~/mla_v3/agent_library (best-effort; never overwrite existing ones)\n  try {\n    const backendPath = getPythonBackendPath();\n    const bundledAgentLibDir = path.join(backendPath, 'config', 'agent_library');\n    if (fs.existsSync(bundledAgentLibDir)) {\n      const destRoot = getUserAgentLibraryPath();\n      fs.mkdirSync(destRoot, { recursive: true });\n      const entries = fs.readdirSync(bundledAgentLibDir, { withFileTypes: true });\n      for (const e of entries) {\n        if (!e.isDirectory() || e.name.startsWith('.')) continue;\n        const src = path.join(bundledAgentLibDir, e.name);\n        const dst = path.join(destRoot, e.name);\n        if (fs.existsSync(dst)) continue; // do not overwrite user system\n        copyDirSync(src, dst);\n      }\n    }\n  } catch (_) {\n    // Seeding agent systems should never block app startup\n  }\n}\n\nfunction ensureUserLlmConfigExists() {\n  ensureUserDataRootScaffold();\n  const userConfigPath = getLlmConfigPath();\n  if (fs.existsSync(userConfigPath)) return userConfigPath;\n\n  // Bootstrap from bundled example (always no key, safe to copy)\n  const backendPath = getPythonBackendPath();\n  const bundled = path.join(backendPath, 'config', 'run_env_config', 'llm_config.example.yaml');\n  if (fs.existsSync(bundled)) {\n    const example = fs.readFileSync(bundled, 'utf-8');\n    fs.writeFileSync(userConfigPath, stripApiKeysFromYaml(example), 'utf-8');\n    return userConfigPath;\n  }\n\n  // Last resort: create minimal config\n  fs.writeFileSync(\n    userConfigPath,\n    [\n      'temperature: 0',\n      'max_tokens: 0',\n      'max_context_window: 200000',\n      'base_url: \"\"',\n      'api_key: \"\"',\n      'models:',\n      '- openai/gpt-4o-mini',\n      'multimodal: false',\n      'compressor_multimodal: false',\n      ''\n    ].join('\\n'),\n    'utf-8'\n  );\n  return userConfigPath;\n}\n\n// Skills library path: ~/.agent/skills\nfunction getSkillsLibraryPath() {\n  return path.join(os.homedir(), '.agent', 'skills');\n}\n\n// Agent system library (user import): ~/mla_v3/agent_library/\nfunction getUserAgentLibraryPath() {\n  return path.join(getUserDataRoot(), 'agent_library');\n}\n\n// Conversations path: ~/mla_v3/conversations/\nfunction getConversationsPath() {\n  return path.join(getUserDataRoot(), 'conversations');\n}\n\nfunction getLogsPath() {\n  return path.join(getUserDataRoot(), 'logs');\n}\n\nfunction sanitizeFilenamePart(input) {\n  const s = String(input || '').trim();\n  if (!s) return 'unknown';\n  return s.replace(/[^\\w.-]+/g, '_').slice(0, 80) || 'unknown';\n}\n\nfunction createTaskLogger({ workspacePath, agentName, agentSystem, mode, launchSpec }) {\n  try {\n    fs.mkdirSync(getLogsPath(), { recursive: true });\n    const now = new Date();\n    const ts = now.toISOString().replace(/[-:]/g, '').replace(/\\..+/, '').replace('T', '_');\n    const workspaceName = sanitizeFilenamePart(path.basename(String(workspacePath || 'workspace')));\n    const runHash = crypto.createHash('md5')\n      .update(`${workspacePath}|${agentName}|${agentSystem}|${now.toISOString()}`)\n      .digest('hex')\n      .slice(0, 8);\n    const fileName = `${ts}_${workspaceName}_${runHash}_${mode}.log`;\n    const filePath = path.join(getLogsPath(), fileName);\n    const stream = fs.createWriteStream(filePath, { flags: 'a', encoding: 'utf-8' });\n\n    const write = (line) => {\n      try {\n        stream.write(`${new Date().toISOString()} ${line}\\n`);\n      } catch (_) {}\n    };\n\n    write('[TASK_START]');\n    write(`[META] mode=${mode} workspace=\"${workspacePath}\" agent=\"${agentName}\" system=\"${agentSystem}\"`);\n    if (launchSpec && launchSpec.command) {\n      const args = Array.isArray(launchSpec.args) ? launchSpec.args.join(' ') : '';\n      write(`[LAUNCH] ${launchSpec.command} ${args}`);\n    }\n\n    return {\n      filePath,\n      write,\n      close(exitCode) {\n        try {\n          write(`[TASK_END] exit_code=${exitCode}`);\n          stream.end();\n        } catch (_) {}\n      }\n    };\n  } catch (_) {\n    return null;\n  }\n}\n\nfunction safeReadJson(filePath) {\n  try {\n    const content = fs.readFileSync(filePath, 'utf-8');\n    return JSON.parse(content);\n  } catch (e) {\n    return null;\n  }\n}\n\nfunction pickPreviewFromShareContext(data) {\n  // Prefer latest instruction in `current`, fallback to last `history`\n  const currentInstructions = data?.current?.instructions;\n  if (Array.isArray(currentInstructions) && currentInstructions.length > 0) {\n    const last = currentInstructions[currentInstructions.length - 1];\n    if (last?.instruction) return String(last.instruction);\n  }\n  const history = data?.history;\n  if (Array.isArray(history) && history.length > 0) {\n    const lastTurn = history[history.length - 1];\n    const lastInst = Array.isArray(lastTurn?.instructions) ? lastTurn.instructions[lastTurn.instructions.length - 1] : null;\n    if (lastInst?.instruction) return String(lastInst.instruction);\n  }\n  return '';\n}\n\nfunction computeTaskNameForConversation(taskId) {\n  // Must match `core/hierarchy_manager.py`\n  const taskHash = crypto.createHash('md5').update(String(taskId)).digest('hex').slice(0, 8);\n  const taskFolder = path.basename(String(taskId));\n  return `${taskHash}_${taskFolder}`;\n}\n\nfunction getStackFilePath(taskId) {\n  const convDir = getConversationsPath();\n  const taskName = computeTaskNameForConversation(taskId);\n  return path.join(convDir, `${taskName}_stack.json`);\n}\n\n// ==================== Window ====================\n\nfunction createWindow() {\n  ensureUserDataRootScaffold();\n  mainWindow = new BrowserWindow({\n    width: 1200,\n    height: 800,\n    minWidth: 800,\n    minHeight: 600,\n    titleBarStyle: 'hiddenInset', // macOS native look\n    trafficLightPosition: { x: 16, y: 16 },\n    backgroundColor: '#faf7f2',\n    webPreferences: {\n      preload: path.join(__dirname, 'preload.js'),\n      contextIsolation: true,\n      nodeIntegration: false\n    }\n  });\n\n  mainWindow.loadFile(path.join(__dirname, 'index.html'));\n  \n  // Open DevTools in development\n  if (!app.isPackaged) {\n    mainWindow.webContents.openDevTools();\n  }\n}\n\napp.whenReady().then(createWindow);\n\napp.on('window-all-closed', () => {\n  killPythonProcess();\n  if (process.platform !== 'darwin') app.quit();\n});\n\napp.on('activate', () => {\n  if (BrowserWindow.getAllWindows().length === 0) createWindow();\n});\n\n// ==================== IPC: Workspace ====================\n\n// Select workspace folder\nipcMain.handle('select-folder', async () => {\n  const result = await dialog.showOpenDialog(mainWindow, {\n    properties: ['openDirectory'],\n    title: 'Select Workspace Folder'\n  });\n  if (result.canceled) return null;\n  return result.filePaths[0];\n});\n\n// ==================== IPC: Agent Task ====================\n\n// Start agent task (spawn Python subprocess with JSONL mode)\nipcMain.handle('start-task', async (event, { workspacePath, userInput, agentName, agentSystem }) => {\n  if (pythonProcess) {\n    return { error: 'A task is already running' };\n  }\n\n  const llmConfigPath = ensureUserLlmConfigExists();\n  \n  const spec = app.isPackaged\n    ? getBackendLaunchSpecPackaged(userInput, workspacePath, agentName, agentSystem, true)\n    : getBackendLaunchSpecDev(userInput, workspacePath, agentName, agentSystem, true);\n\n  currentTaskLogger = createTaskLogger({\n    workspacePath,\n    agentName: agentName || 'alpha_agent',\n    agentSystem: agentSystem || 'OpenCowork',\n    mode: 'start',\n    launchSpec: spec\n  });\n\n  pythonProcess = spawn(spec.command, spec.args, {\n    cwd: spec.cwd,\n    env: {\n      ...buildRuntimeEnv(),\n      PYTHONUNBUFFERED: '1',\n      MLA_LLM_CONFIG_PATH: llmConfigPath,\n      // Allow importing agent systems under ~/mla_v3/agent_library/\n      MLA_AGENT_LIBRARY_DIR: getUserDataRoot(),\n      ...(app.isPackaged && fs.existsSync(getPackagedBackendPlaywrightBrowsersPath())\n        ? { PLAYWRIGHT_BROWSERS_PATH: getPackagedBackendPlaywrightBrowsersPath() }\n        : {})\n    }\n  });\n\n  let buffer = '';\n  let errBuffer = '';\n\n  pythonProcess.stdout.on('data', (data) => {\n    if (currentTaskLogger) currentTaskLogger.write(`[STDOUT_CHUNK] ${JSON.stringify(data.toString())}`);\n    buffer += data.toString();\n    const lines = buffer.split('\\n');\n    buffer = lines.pop() || '';\n    \n    for (const line of lines) {\n      if (!line.trim()) continue;\n      try {\n        const evt = JSON.parse(line);\n        if (currentTaskLogger) currentTaskLogger.write(`[EVENT] ${line}`);\n        mainWindow.webContents.send('agent-event', evt);\n      } catch (e) {\n        // Non-JSON output (debug prints, etc.)\n        if (currentTaskLogger) currentTaskLogger.write(`[LOG] ${line}`);\n        mainWindow.webContents.send('agent-log', line);\n      }\n    }\n  });\n\n  pythonProcess.stderr.on('data', (data) => {\n    if (currentTaskLogger) currentTaskLogger.write(`[STDERR_CHUNK] ${JSON.stringify(data.toString())}`);\n    errBuffer += data.toString();\n    const lines = errBuffer.split('\\n');\n    errBuffer = lines.pop() || '';\n    for (const line of lines) {\n      if (!line.trim()) continue;\n      if (currentTaskLogger) currentTaskLogger.write(`[ERR] ${line}`);\n      mainWindow.webContents.send('agent-log', line);\n    }\n  });\n\n  pythonProcess.on('close', (code) => {\n    pythonProcess = null;\n    if (currentTaskLogger) {\n      currentTaskLogger.close(code);\n      currentTaskLogger = null;\n    }\n    mainWindow.webContents.send('agent-done', { code });\n  });\n\n  return { success: true, log_file: currentTaskLogger?.filePath || null };\n});\n\n// Human-in-loop respond (no-HTTP, via stdin JSONL to Python)\nipcMain.handle('hil-respond', async (event, { hil_id, response }) => {\n  try {\n    if (!pythonProcess || !pythonProcess.stdin) {\n      return { error: 'No running task process' };\n    }\n    const hid = (hil_id || '').toString().trim();\n    if (!hid) return { error: 'Missing hil_id' };\n    const payload = { type: 'hil_response', hil_id: hid, response: (response ?? '').toString() };\n    pythonProcess.stdin.write(JSON.stringify(payload) + '\\n');\n    return { success: true };\n  } catch (e) {\n    return { error: e.message || String(e) };\n  }\n});\n\n// Check if there is an interrupted task that can be resumed (CLI-compatible: check stack file)\nipcMain.handle('check-resume', async (event, taskId) => {\n  try {\n    if (!taskId || typeof taskId !== 'string') return { found: false, message: 'Invalid task_id' };\n\n    const stackFile = getStackFilePath(taskId);\n    if (!fs.existsSync(stackFile)) {\n      return { found: false, message: 'No interrupted task (stack file missing)' };\n    }\n\n    const data = safeReadJson(stackFile);\n    const stack = Array.isArray(data?.stack) ? data.stack : [];\n    if (stack.length === 0) {\n      return { found: false, message: 'No interrupted task (stack empty)' };\n    }\n\n    const bottom = stack[0] || {};\n    const agentName = bottom.agent_name || bottom.agentName || bottom.agent || null;\n    const userInput = bottom.user_input || bottom.userInput || bottom.input || null;\n    if (!agentName || !userInput) {\n      return { found: false, message: 'Interrupted task data incomplete' };\n    }\n\n    return {\n      found: true,\n      agent_name: String(agentName),\n      user_input: String(userInput),\n      interrupted_at: bottom.start_time || bottom.startTime || '',\n      stack_depth: stack.length\n    };\n  } catch (e) {\n    return { found: false, message: String(e.message || e) };\n  }\n});\n\n// Resume task: re-run start.py with SAME agent_name & user_input (do NOT append timestamp)\nipcMain.handle('resume-task', async (event, { workspacePath, agentSystem }) => {\n  if (pythonProcess) {\n    return { error: 'A task is already running' };\n  }\n\n  try {\n    if (!workspacePath || typeof workspacePath !== 'string') return { error: 'Invalid workspacePath' };\n\n    // Recompute interrupted info\n    const stackFile = getStackFilePath(workspacePath);\n    const data = safeReadJson(stackFile);\n    const stack = Array.isArray(data?.stack) ? data.stack : [];\n    if (stack.length === 0) return { error: 'No interrupted task to resume' };\n\n    const bottom = stack[0] || {};\n    const agentName = bottom.agent_name || bottom.agentName || bottom.agent || 'alpha_agent';\n    const userInput = bottom.user_input || bottom.userInput || bottom.input || '';\n    if (!userInput) return { error: 'No interrupted task input found' };\n\n    const llmConfigPath = ensureUserLlmConfigExists();\n    const spec = app.isPackaged\n      ? getBackendLaunchSpecPackaged(String(userInput), workspacePath, String(agentName), agentSystem, false)\n      : getBackendLaunchSpecDev(String(userInput), workspacePath, String(agentName), agentSystem, false);\n\n    currentTaskLogger = createTaskLogger({\n      workspacePath,\n      agentName: String(agentName),\n      agentSystem: agentSystem || 'OpenCowork',\n      mode: 'resume',\n      launchSpec: spec\n    });\n\n    pythonProcess = spawn(spec.command, spec.args, {\n      cwd: spec.cwd,\n      env: {\n        ...buildRuntimeEnv(),\n        PYTHONUNBUFFERED: '1',\n        MLA_LLM_CONFIG_PATH: llmConfigPath,\n        MLA_AGENT_LIBRARY_DIR: getUserDataRoot(),\n        ...(app.isPackaged && fs.existsSync(getPackagedBackendPlaywrightBrowsersPath())\n          ? { PLAYWRIGHT_BROWSERS_PATH: getPackagedBackendPlaywrightBrowsersPath() }\n          : {})\n      }\n    });\n\n    let buffer = '';\n    let errBuffer = '';\n\n    pythonProcess.stdout.on('data', (data) => {\n      if (currentTaskLogger) currentTaskLogger.write(`[STDOUT_CHUNK] ${JSON.stringify(data.toString())}`);\n      buffer += data.toString();\n      const lines = buffer.split('\\n');\n      buffer = lines.pop() || '';\n\n      for (const line of lines) {\n        if (!line.trim()) continue;\n        try {\n          const evt = JSON.parse(line);\n          if (currentTaskLogger) currentTaskLogger.write(`[EVENT] ${line}`);\n          mainWindow.webContents.send('agent-event', evt);\n        } catch (e) {\n          if (currentTaskLogger) currentTaskLogger.write(`[LOG] ${line}`);\n          mainWindow.webContents.send('agent-log', line);\n        }\n      }\n    });\n\n    pythonProcess.stderr.on('data', (data) => {\n      if (currentTaskLogger) currentTaskLogger.write(`[STDERR_CHUNK] ${JSON.stringify(data.toString())}`);\n      errBuffer += data.toString();\n      const lines = errBuffer.split('\\n');\n      errBuffer = lines.pop() || '';\n      for (const line of lines) {\n        if (!line.trim()) continue;\n        if (currentTaskLogger) currentTaskLogger.write(`[ERR] ${line}`);\n        mainWindow.webContents.send('agent-log', line);\n      }\n    });\n\n    pythonProcess.on('close', (code) => {\n      pythonProcess = null;\n      if (currentTaskLogger) {\n        currentTaskLogger.close(code);\n        currentTaskLogger = null;\n      }\n      mainWindow.webContents.send('agent-done', { code });\n    });\n\n    return { success: true, log_file: currentTaskLogger?.filePath || null };\n  } catch (e) {\n    pythonProcess = null;\n    if (currentTaskLogger) {\n      currentTaskLogger.close(-1);\n      currentTaskLogger = null;\n    }\n    return { error: e.message || String(e) };\n  }\n});\n\n// Stop running task\nipcMain.handle('stop-task', async () => {\n  killPythonProcess();\n  return { success: true };\n});\n\nfunction killPythonProcess() {\n  if (pythonProcess) {\n    if (currentTaskLogger) {\n      currentTaskLogger.write('[STOP_REQUESTED] task stopped by user');\n    }\n    try {\n      process.kill(-pythonProcess.pid, 'SIGTERM');\n    } catch (e) {\n      try { pythonProcess.kill('SIGTERM'); } catch (e2) {}\n    }\n    pythonProcess = null;\n  }\n}\n\n// ==================== IPC: Settings (llm_config.yaml) ====================\n\nfunction parseSettingsYaml(text) {\n  const parsed = yaml.load(text) || {};\n  return (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) ? parsed : {};\n}\n\nfunction serializeSettingsYaml(obj) {\n  return yaml.dump(obj || {}, {\n    lineWidth: 120,\n    noRefs: true,\n    sortKeys: false\n  });\n}\n\n// Read LLM config\nipcMain.handle('get-settings', async () => {\n  try {\n    ensureUserLlmConfigExists();\n    const configPath = getLlmConfigPath();\n    if (!fs.existsSync(configPath)) {\n      return { error: 'Config file not found', path: configPath };\n    }\n    const content = fs.readFileSync(configPath, 'utf-8');\n    const config = parseSettingsYaml(content);\n    return { success: true, config, raw_yaml: content, path: configPath };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Save LLM config\nipcMain.handle('save-settings', async (event, config) => {\n  try {\n    ensureUserLlmConfigExists();\n    const configPath = getLlmConfigPath();\n    // Accept either a config object (simple form) or raw YAML string (full fidelity)\n    if (typeof config === 'string') {\n      fs.writeFileSync(configPath, config, 'utf-8');\n    } else {\n      const yamlText = serializeSettingsYaml(config);\n      fs.writeFileSync(configPath, yamlText, 'utf-8');\n    }\n    return { success: true };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// List available agent systems (scan config/agent_library/)\nipcMain.handle('get-agent-systems', async () => {\n  try {\n    ensureUserDataRootScaffold();\n    const systems = new Set();\n\n    // Bundled systems (read-only)\n    const backendPath = getPythonBackendPath();\n    const bundledAgentLibDir = path.join(backendPath, 'config', 'agent_library');\n    if (fs.existsSync(bundledAgentLibDir)) {\n      const entries = fs.readdirSync(bundledAgentLibDir, { withFileTypes: true });\n      for (const e of entries) {\n        if (e.isDirectory() && !e.name.startsWith('.')) systems.add(e.name);\n      }\n    }\n\n    // User imported systems under ~/mla_v3/agent_library/<System>/\n    const userAgentLibRoot = getUserAgentLibraryPath();\n    if (fs.existsSync(userAgentLibRoot)) {\n      const entries = fs.readdirSync(userAgentLibRoot, { withFileTypes: true });\n      for (const e of entries) {\n        if (e.isDirectory() && !e.name.startsWith('.')) systems.add(e.name);\n      }\n    }\n\n    return { success: true, systems: Array.from(systems).sort() };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Delete an imported/seeded agent system under ~/mla_v3/agent_library/<System>/\nipcMain.handle('delete-agent-system', async (event, systemName) => {\n  try {\n    const name = String(systemName || '').trim();\n    if (!name) return { error: 'Invalid system name' };\n    const userRoot = getUserAgentLibraryPath();\n    const target = path.join(userRoot, name);\n    if (!fs.existsSync(target)) {\n      return { success: true, deleted: false };\n    }\n    fs.rmSync(target, { recursive: true, force: true });\n    return { success: true, deleted: true };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Import Agent System folder into ~/mla_v3/agent_library/\nipcMain.handle('import-agent-system-folder', async () => {\n  try {\n    const result = await dialog.showOpenDialog(mainWindow, {\n      properties: ['openDirectory'],\n      title: 'Select Agent System Folder to Import'\n    });\n    if (result.canceled) return { canceled: true };\n\n    const srcDir = result.filePaths[0];\n    const systemName = path.basename(srcDir);\n    const destRoot = getUserAgentLibraryPath();\n    const destDir = path.join(destRoot, systemName);\n    fs.mkdirSync(destRoot, { recursive: true });\n    copyDirSync(srcDir, destDir);\n    return { success: true, name: systemName, path: destDir };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// ==================== IPC: App Config (app_config.json) ====================\n\nipcMain.handle('get-app-config', async () => {\n  try {\n    const cfg = readAppConfig();\n    return { success: true, config: cfg, path: getAppConfigPath() };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\nipcMain.handle('save-app-config', async (event, config) => {\n  try {\n    ensureUserAppConfigExists();\n    const base = defaultAppConfig();\n    const raw = (config && typeof config === 'object') ? config : {};\n    const out = { ...base, ...raw };\n    out.env = { ...base.env, ...(raw.env || {}) };\n    out.runtime = { ...base.runtime, ...(raw.runtime || {}) };\n    out.context = { ...base.context, ...(raw.context || {}) };\n    out.mcp = { ...base.mcp, ...(raw.mcp || {}) };\n    out.market = { ...base.market, ...(raw.market || {}) };\n    fs.writeFileSync(getAppConfigPath(), JSON.stringify(out, null, 2) + '\\n', 'utf-8');\n    return { success: true };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\nipcMain.handle('fresh-runtime', async (event, payload) => {\n  try {\n    const reason = String(payload?.reason || '').trim() || 'manual runtime refresh';\n    const taskId = String(payload?.task_id || '').trim();\n    if (pythonProcess && pythonProcess.stdin && !pythonProcess.killed) {\n      pythonProcess.stdin.write(JSON.stringify({\n        type: 'fresh_request',\n        reason,\n        ...(taskId ? { task_id: taskId } : {})\n      }) + '\\n');\n      return { success: true, running: true };\n    }\n    return { success: true, running: false };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// ==================== IPC: Marketplace ====================\n\nfunction normalizeMarketBaseUrl(url) {\n  const u = String(url || '').trim();\n  if (!u) return '';\n  return u.replace(/\\/+$/, '');\n}\n\nasync function fetchJson(url) {\n  const res = await fetch(url, { method: 'GET' });\n  if (!res.ok) {\n    const t = await res.text().catch(() => '');\n    throw new Error(`HTTP ${res.status}: ${t.slice(0, 300)}`);\n  }\n  return await res.json();\n}\n\nasync function fetchBuffer(url) {\n  const res = await fetch(url, { method: 'GET' });\n  if (!res.ok) {\n    const t = await res.text().catch(() => '');\n    throw new Error(`HTTP ${res.status}: ${t.slice(0, 300)}`);\n  }\n  const ab = await res.arrayBuffer();\n  return Buffer.from(ab);\n}\n\nfunction resolveUniqueName(rootDir, baseName) {\n  let name = baseName;\n  if (!fs.existsSync(path.join(rootDir, name))) return name;\n  for (let i = 2; i < 1000; i++) {\n    const candidate = `${baseName}__${i}`;\n    if (!fs.existsSync(path.join(rootDir, candidate))) return candidate;\n  }\n  // fallback\n  return `${baseName}__${Date.now()}`;\n}\n\nfunction extractSingleTopFolderFromZip(zipBuffer, tempDir) {\n  fs.mkdirSync(tempDir, { recursive: true });\n  const zip = new AdmZip(zipBuffer);\n  zip.extractAllTo(tempDir, true);\n  const entries = fs.readdirSync(tempDir, { withFileTypes: true }).filter(e => !e.name.startsWith('.'));\n  const dirs = entries.filter(e => e.isDirectory());\n  if (dirs.length === 1) {\n    return path.join(tempDir, dirs[0].name);\n  }\n  // If zip doesn't have a single top folder, treat tempDir as root\n  return tempDir;\n}\n\nipcMain.handle('market-get-index', async () => {\n  try {\n    const appCfg = readAppConfig();\n    const base = normalizeMarketBaseUrl(appCfg?.market?.base_url);\n    if (!base) return { error: 'Market base_url is empty. Set it in Settings → Environment / Marketplace.' };\n    const index = await fetchJson(`${base}/api/v1/index`);\n    return { success: true, base_url: base, index };\n  } catch (e) {\n    return { error: e.message || String(e) };\n  }\n});\n\nipcMain.handle('market-install', async (event, { kind, name, strategy }) => {\n  try {\n    const k = String(kind || '').trim(); // 'skill' | 'agent_system'\n    const n = String(name || '').trim();\n    const s = String(strategy || '').trim(); // 'overwrite' | 'keep_both'\n    if (!n) return { error: 'Missing name' };\n    if (k !== 'skill' && k !== 'agent_system') return { error: 'Invalid kind' };\n\n    const appCfg = readAppConfig();\n    const base = normalizeMarketBaseUrl(appCfg?.market?.base_url);\n    if (!base) return { error: 'Market base_url is empty' };\n\n    const dlUrl = (k === 'skill')\n      ? `${base}/api/v1/skills/${encodeURIComponent(n)}/download`\n      : `${base}/api/v1/agent-systems/${encodeURIComponent(n)}/download`;\n\n    const buf = await fetchBuffer(dlUrl);\n    const tempRoot = path.join(getUserDataRoot(), 'tmp', 'market');\n    const tempDir = path.join(tempRoot, `${k}_${Date.now()}_${Math.random().toString(16).slice(2)}`);\n    const extractedRoot = extractSingleTopFolderFromZip(buf, tempDir);\n\n    const destRoot = (k === 'skill') ? getSkillsLibraryPath() : getUserAgentLibraryPath();\n    fs.mkdirSync(destRoot, { recursive: true });\n\n    // Determine installed folder name\n    let installName = path.basename(extractedRoot);\n    if (!installName || installName === '.' || installName === '..') installName = n;\n\n    let destDir = path.join(destRoot, installName);\n    if (fs.existsSync(destDir)) {\n      if (!s) {\n        return { success: false, conflict: true, existing: installName };\n      }\n      if (s === 'overwrite') {\n        fs.rmSync(destDir, { recursive: true, force: true });\n      } else if (s === 'keep_both') {\n        const uniq = resolveUniqueName(destRoot, installName);\n        installName = uniq;\n        destDir = path.join(destRoot, installName);\n      } else {\n        return { error: `Unknown strategy: ${s}` };\n      }\n    }\n\n    copyDirSync(extractedRoot, destDir);\n    try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch (_) {}\n\n    return { success: true, installed_name: installName, path: destDir };\n  } catch (e) {\n    return { error: e.message || String(e) };\n  }\n});\n\n// ==================== IPC: Skills Library ====================\n\n// Select skill folder and copy to ~/.agent/skills\nipcMain.handle('import-skill-folder', async () => {\n  try {\n    const result = await dialog.showOpenDialog(mainWindow, {\n      properties: ['openDirectory'],\n      title: 'Select Skill Folder to Import'\n    });\n    if (result.canceled) return { canceled: true };\n    \n    const srcDir = result.filePaths[0];\n    const folderName = path.basename(srcDir);\n    const destDir = path.join(getSkillsLibraryPath(), folderName);\n    \n    // Ensure ~/.agent/skills exists\n    fs.mkdirSync(getSkillsLibraryPath(), { recursive: true });\n    \n    // Copy recursively\n    copyDirSync(srcDir, destDir);\n    \n    return { success: true, name: folderName, path: destDir };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// List imported skills\nipcMain.handle('get-skills', async () => {\n  try {\n    const skillsDir = getSkillsLibraryPath();\n    if (!fs.existsSync(skillsDir)) {\n      fs.mkdirSync(skillsDir, { recursive: true });\n      return { success: true, skills: [] };\n    }\n    \n    const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n    const skills = [];\n    \n    for (const entry of entries) {\n      if (!entry.isDirectory() || entry.name.startsWith('.')) continue;\n      \n      const skillMd = path.join(skillsDir, entry.name, 'SKILL.md');\n      let description = '';\n      \n      if (fs.existsSync(skillMd)) {\n        // Parse frontmatter for description\n        const content = fs.readFileSync(skillMd, 'utf-8');\n        const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n        if (fmMatch) {\n          const descMatch = fmMatch[1].match(/description:\\s*(.+)/);\n          if (descMatch) description = descMatch[1].trim();\n        }\n      }\n      \n      skills.push({\n        name: entry.name,\n        description,\n        path: path.join(skillsDir, entry.name),\n        hasSkillMd: fs.existsSync(skillMd)\n      });\n    }\n    \n    return { success: true, skills };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Delete a skill\nipcMain.handle('delete-skill', async (event, skillName) => {\n  try {\n    const skillDir = path.join(getSkillsLibraryPath(), skillName);\n    if (fs.existsSync(skillDir)) {\n      fs.rmSync(skillDir, { recursive: true, force: true });\n    }\n    return { success: true };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Recursive copy helper\nfunction copyDirSync(src, dest) {\n  fs.mkdirSync(dest, { recursive: true });\n  const entries = fs.readdirSync(src, { withFileTypes: true });\n  for (const entry of entries) {\n    const srcPath = path.join(src, entry.name);\n    const destPath = path.join(dest, entry.name);\n    if (entry.isDirectory()) {\n      copyDirSync(srcPath, destPath);\n    } else {\n      fs.copyFileSync(srcPath, destPath);\n    }\n  }\n}\n\n// ==================== IPC: Conversation History ====================\n\n// List all conversations from ~/mla_v3/conversations/\nipcMain.handle('get-conversations', async () => {\n  try {\n    const convDir = getConversationsPath();\n    if (!fs.existsSync(convDir)) {\n      fs.mkdirSync(convDir, { recursive: true });\n      return { success: true, conversations: [] };\n    }\n    \n    // Only scan share context JSONs to avoid duplicates\n    const files = fs\n      .readdirSync(convDir)\n      .filter(f => f.endsWith('.json') && f.includes('share'));\n\n    const byTaskId = new Map(); // taskId -> conversation item (keep latest)\n\n    for (const file of files) {\n      const filePath = path.join(convDir, file);\n      const stat = fs.statSync(filePath);\n      const data = safeReadJson(filePath);\n      if (!data || !data.task_id) continue;\n\n      const taskId = String(data.task_id || '');\n      const workspaceName = path.basename(taskId) || taskId;\n\n      const rawPreview = pickPreviewFromShareContext(data);\n      const preview = rawPreview.length > 60 ? rawPreview.substring(0, 60) + '...' : rawPreview;\n\n      const item = {\n        id: file.replace('.json', ''),\n        file: file,\n        taskId,\n        workspaceName,\n        preview,\n        // turns = number of completed user instructions in history\n        turns: Array.isArray(data.history) ? data.history.length : 0,\n        lastUpdated: data.last_updated || stat.mtime.toISOString(),\n        mtime: stat.mtime.getTime()\n      };\n\n      const prev = byTaskId.get(taskId);\n      if (!prev || item.mtime > prev.mtime) {\n        byTaskId.set(taskId, item);\n      }\n    }\n\n    const conversations = Array.from(byTaskId.values()).sort((a, b) => b.mtime - a.mtime);\n    return { success: true, conversations };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Read a share_context.json by filename\nipcMain.handle('get-conversation-detail', async (event, fileName) => {\n  try {\n    if (!fileName || typeof fileName !== 'string') return { error: 'Invalid file name' };\n    const base = path.basename(fileName);\n    // Restrict to share json files only\n    if (!base.endsWith('.json') || !base.includes('share')) return { error: 'Not a share context file' };\n\n    const filePath = path.join(getConversationsPath(), base);\n    if (!fs.existsSync(filePath)) return { error: 'File not found' };\n\n    const data = safeReadJson(filePath);\n    if (!data) return { error: 'Failed to parse JSON' };\n    return { success: true, data };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Delete a conversation file\nipcMain.handle('delete-conversation', async (event, fileName) => {\n  try {\n    const filePath = path.join(getConversationsPath(), fileName);\n    if (fs.existsSync(filePath)) {\n      fs.unlinkSync(filePath);\n    }\n    return { success: true };\n  } catch (e) {\n    return { error: e.message };\n  }\n});\n\n// Open conversations folder in Finder\nipcMain.handle('open-conversations-folder', async () => {\n  const convDir = getConversationsPath();\n  fs.mkdirSync(convDir, { recursive: true });\n  shell.openPath(convDir);\n  return { success: true };\n});\n"
  },
  {
    "path": "desktop_app/src/preload.js",
    "content": "const { contextBridge, ipcRenderer } = require('electron');\n\ncontextBridge.exposeInMainWorld('api', {\n  // Workspace\n  selectFolder: () => ipcRenderer.invoke('select-folder'),\n  \n  // Agent\n  startTask: (params) => ipcRenderer.invoke('start-task', params),\n  stopTask: () => ipcRenderer.invoke('stop-task'),\n  hilRespond: (params) => ipcRenderer.invoke('hil-respond', params),\n  \n  // Events from main process\n  onAgentEvent: (callback) => ipcRenderer.on('agent-event', (_, event) => callback(event)),\n  onAgentLog: (callback) => ipcRenderer.on('agent-log', (_, log) => callback(log)),\n  onAgentDone: (callback) => ipcRenderer.on('agent-done', (_, result) => callback(result)),\n  \n  // Settings (llm_config.yaml)\n  getSettings: () => ipcRenderer.invoke('get-settings'),\n  saveSettings: (config) => ipcRenderer.invoke('save-settings', config),\n  getAgentSystems: () => ipcRenderer.invoke('get-agent-systems'),\n  importAgentSystemFolder: () => ipcRenderer.invoke('import-agent-system-folder'),\n  deleteAgentSystem: (name) => ipcRenderer.invoke('delete-agent-system', name),\n\n  // App config (app_config.json)\n  getAppConfig: () => ipcRenderer.invoke('get-app-config'),\n  saveAppConfig: (config) => ipcRenderer.invoke('save-app-config', config),\n  freshRuntime: (payload) => ipcRenderer.invoke('fresh-runtime', payload || {}),\n\n  // Marketplace\n  marketGetIndex: () => ipcRenderer.invoke('market-get-index'),\n  marketInstall: (params) => ipcRenderer.invoke('market-install', params),\n  \n  // Skills library\n  importSkillFolder: () => ipcRenderer.invoke('import-skill-folder'),\n  getSkills: () => ipcRenderer.invoke('get-skills'),\n  deleteSkill: (name) => ipcRenderer.invoke('delete-skill', name),\n  \n  // Conversation history\n  getConversations: () => ipcRenderer.invoke('get-conversations'),\n  getConversationDetail: (fileName) => ipcRenderer.invoke('get-conversation-detail', fileName),\n  deleteConversation: (fileName) => ipcRenderer.invoke('delete-conversation', fileName),\n  openConversationsFolder: () => ipcRenderer.invoke('open-conversations-folder'),\n\n  // Resume (CLI-compatible)\n  checkResume: (taskId) => ipcRenderer.invoke('check-resume', taskId),\n  resumeTask: (params) => ipcRenderer.invoke('resume-task', params),\n  \n  // Remove listeners\n  removeAllListeners: (channel) => ipcRenderer.removeAllListeners(channel)\n});\n"
  },
  {
    "path": "desktop_app/src/renderer.js",
    "content": "// ==================== DOM Elements ====================\nconst selectFolderBtn = document.getElementById('select-folder-btn');\nconst workspaceLabel = document.getElementById('workspace-label');\nconst agentSystemSelect = document.getElementById('agent-system-select');\nconst messagesContainer = document.getElementById('messages');\nconst userInput = document.getElementById('user-input');\nconst sendBtn = document.getElementById('send-btn');\nconst stopBtn = document.getElementById('stop-btn');\nconst statusText = document.getElementById('status-text');\nconst newChatBtn = document.getElementById('new-chat-btn');\nconst workspaceCurrent = document.getElementById('workspace-current');\nconst resumeBtn = document.getElementById('resume-btn');\nconst autoScrollBtn = document.getElementById('auto-scroll-btn');\n\n// ==================== State ====================\nlet workspacePath = null;\nlet isRunning = false;\nlet autoScrollEnabled = true;\nlet lastLoadedSettingsConfig = {};\n\n// Streaming state\nlet currentAgentBubble = null;\nlet currentAgentContentDiv = null;\nlet currentStreamText = '';\n\nasync function reloadAgentSystems(selectedValue = null) {\n  const systemsResult = await window.api.getAgentSystems();\n  if (!systemsResult?.success) return systemsResult;\n\n  const systems = systemsResult.systems || [];\n  const currentSidebarValue = selectedValue || agentSystemSelect.value || systems[0] || 'OpenCowork';\n\n  const settingSelect = document.getElementById('setting-agent-system');\n  if (settingSelect) settingSelect.innerHTML = '';\n  agentSystemSelect.innerHTML = '';\n\n  for (const sys of systems) {\n    const opt1 = document.createElement('option');\n    opt1.value = sys;\n    opt1.textContent = sys;\n    agentSystemSelect.appendChild(opt1);\n\n    if (settingSelect) {\n      const opt2 = document.createElement('option');\n      opt2.value = sys;\n      opt2.textContent = sys;\n      settingSelect.appendChild(opt2);\n    }\n  }\n\n  if (systems.includes(currentSidebarValue)) {\n    agentSystemSelect.value = currentSidebarValue;\n    if (settingSelect) settingSelect.value = currentSidebarValue;\n  } else if (systems[0]) {\n    agentSystemSelect.value = systems[0];\n    if (settingSelect) settingSelect.value = systems[0];\n  }\n\n  return systemsResult;\n}\n\n// ==================== Markdown Render ====================\n\nfunction renderMarkdownSafe(mdText) {\n  try {\n    const text = String(mdText ?? '');\n\n    // marked + DOMPurify loaded via script tags in index.html\n    if (window.marked && window.DOMPurify) {\n      const html = window.marked.parse(text, {\n        gfm: true,\n        breaks: true\n      });\n      return window.DOMPurify.sanitize(html, { USE_PROFILES: { html: true } });\n    }\n\n    // Fallback: preserve newlines safely\n    return escapeHtml(text).replace(/\\n/g, '<br>');\n  } catch (e) {\n    return escapeHtml(String(mdText ?? ''));\n  }\n}\n\nfunction setMarkdown(el, mdText) {\n  if (!el) return;\n  el.classList.add('markdown');\n  el.innerHTML = renderMarkdownSafe(mdText);\n}\n\n\n// ==================== Workspace Selection ====================\nselectFolderBtn.addEventListener('click', async () => {\n  const folder = await window.api.selectFolder();\n  if (folder) {\n    workspacePath = folder;\n    const folderName = folder.split('/').pop() || folder.split('\\\\').pop();\n    // Keep button label stable, show current workspace separately\n    if (workspaceCurrent) {\n      workspaceCurrent.textContent = folder;\n      workspaceCurrent.title = folder;\n    }\n    \n    userInput.disabled = false;\n    sendBtn.disabled = false;\n    statusText.textContent = `Workspace: ${folderName}`;\n    \n    const welcome = messagesContainer.querySelector('.welcome-message');\n    if (welcome) welcome.remove();\n\n    await refreshResumeButton();\n  }\n});\n\n// ==================== New Chat ====================\nnewChatBtn.addEventListener('click', () => {\n  if (isRunning) return;\n  // Clear messages\n  messagesContainer.innerHTML = `\n    <div class=\"welcome-message\">\n      <h2>Welcome to infiAgent</h2>\n      <p>Select a workspace folder to begin. Your agent will work within that directory.</p>\n      <div class=\"feature-cards\">\n        <div class=\"feature-card\">\n          <span class=\"feature-icon\">🔄</span>\n          <span class=\"feature-text\">Days-long tasks with resume</span>\n        </div>\n        <div class=\"feature-card\">\n          <span class=\"feature-icon\">🧠</span>\n          <span class=\"feature-text\">Persistent memory per workspace</span>\n        </div>\n        <div class=\"feature-card\">\n          <span class=\"feature-icon\">⚡</span>\n          <span class=\"feature-text\">Agent Skills support</span>\n        </div>\n      </div>\n    </div>\n  `;\n  finalizeCurrentStream();\n  statusText.textContent = workspacePath \n    ? `Workspace: ${workspacePath.split('/').pop()}`\n    : 'Select a workspace to start';\n  statusText.style.color = '';\n  refreshResumeButton();\n});\n\n// ==================== Resume (CLI-compatible) ====================\n\nasync function refreshResumeButton() {\n  if (!resumeBtn) return;\n  if (!workspacePath) {\n    resumeBtn.style.display = 'none';\n    return;\n  }\n\n  // If running, keep it visible but disabled\n  if (isRunning) {\n    resumeBtn.style.display = 'inline-flex';\n    resumeBtn.disabled = true;\n    resumeBtn.textContent = 'Resume';\n    resumeBtn.title = 'Task is running. Resume is disabled.';\n    return;\n  }\n\n  const info = await window.api.checkResume(workspacePath);\n  if (!info || !info.found) {\n    resumeBtn.style.display = 'none';\n    return;\n  }\n\n  resumeBtn.style.display = 'inline-flex';\n  resumeBtn.disabled = false;\n  resumeBtn.textContent = 'Resume';\n  resumeBtn.title = `Resume interrupted task (stack depth: ${info.stack_depth || '?'})`;\n}\n\nif (resumeBtn) {\n  resumeBtn.addEventListener('click', async () => {\n    if (!workspacePath || isRunning) return;\n    const info = await window.api.checkResume(workspacePath);\n    if (!info?.found) {\n      addErrorMessage('No resumable task found for this workspace.');\n      await refreshResumeButton();\n      return;\n    }\n\n    isRunning = true;\n    sendBtn.style.display = 'none';\n    stopBtn.style.display = 'flex';\n    userInput.disabled = true;\n    statusText.textContent = 'Resuming...';\n    await refreshResumeButton();\n\n    showTypingIndicator();\n    const result = await window.api.resumeTask({\n      workspacePath,\n      agentSystem: agentSystemSelect.value\n    });\n    if (result?.error) {\n      removeTypingIndicator();\n      addErrorMessage(result.error);\n      resetState();\n      await refreshResumeButton();\n    }\n  });\n}\n\n// ==================== Send Message ====================\nsendBtn.addEventListener('click', sendMessage);\nuserInput.addEventListener('keydown', (e) => {\n  if (e.key === 'Enter' && !e.shiftKey) {\n    e.preventDefault();\n    sendMessage();\n  }\n});\n\nuserInput.addEventListener('input', () => {\n  userInput.style.height = 'auto';\n  userInput.style.height = Math.min(userInput.scrollHeight, 200) + 'px';\n});\n\nasync function sendMessage() {\n  const text = userInput.value.trim();\n  if (!text || !workspacePath || isRunning) return;\n  \n  addUserMessage(text);\n  userInput.value = '';\n  userInput.style.height = 'auto';\n  \n  isRunning = true;\n  sendBtn.style.display = 'none';\n  stopBtn.style.display = 'flex';\n  userInput.disabled = true;\n  statusText.textContent = 'Running...';\n  \n  showTypingIndicator();\n  \n  const result = await window.api.startTask({\n    workspacePath,\n    userInput: text,\n    agentName: 'alpha_agent',\n    agentSystem: agentSystemSelect.value\n  });\n  \n  if (result.error) {\n    removeTypingIndicator();\n    addErrorMessage(result.error);\n    resetState();\n    await refreshResumeButton();\n  }\n}\n\n// ==================== Stop Task ====================\nstopBtn.addEventListener('click', async () => {\n  await window.api.stopTask();\n  statusText.textContent = 'Stopping...';\n});\n\n// ==================== Agent Events ====================\nwindow.api.onAgentEvent((event) => {\n  const type = event.type;\n  \n  switch (type) {\n    case 'token':\n      removeTypingIndicator();\n      finalizeReasoningStream();\n      streamToken(event.text || '');\n      break;\n      \n    case 'reasoning_token':\n      removeTypingIndicator();\n      finalizeCurrentStream();\n      streamReasoningToken(event.text || '');\n      break;\n      \n    case 'thinking_token':\n      removeTypingIndicator();\n      finalizeCurrentStream();\n      streamThinkingAgentToken(event.text || '');\n      break;\n      \n    case 'tool_call':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      addToolMessage(event.tool || event.name || 'unknown', 'running', event.arguments);\n      showTypingIndicator();\n      break;\n      \n    case 'tool_result':\n      removeTypingIndicator();\n      updateLastToolStatus(\n        event.status === 'error' ? 'error' : 'success',\n        event.output_preview\n      );\n      break;\n      \n    case 'agent_start':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      addSystemMessage(`${event.agent || 'Agent'} started`);\n      showTypingIndicator();\n      break;\n      \n    case 'agent_end':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      break;\n      \n    case 'thinking_start':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      startThinkingAgentStream();\n      break;\n      \n    case 'thinking_end':\n      removeTypingIndicator();\n      finalizeThinkingAgentStream();\n      break;\n      \n    case 'error':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      addErrorMessage(event.message || event.error || 'Unknown error');\n      break;\n      \n    case 'result':\n      finalizeCurrentStream();\n      removeTypingIndicator();\n      if (event.summary) {\n        streamToken(event.summary);\n        finalizeCurrentStream();\n      }\n      break;\n      \n    default:\n      if (event.text) {\n        removeTypingIndicator();\n        streamToken(event.text);\n      }\n  }\n  \n  scrollToBottom();\n});\n\nwindow.api.onAgentLog((log) => {\n  console.log('[Agent Log]', log);\n});\n\nwindow.api.onAgentDone((result) => {\n  finalizeCurrentStream();\n  removeTypingIndicator();\n  \n  if (result.code !== 0 && result.code !== null) {\n    statusText.textContent = `Ended with code ${result.code}`;\n    statusText.style.color = '#c75450';\n  } else {\n    statusText.textContent = 'Task completed';\n    statusText.style.color = '#5a9a6a';\n  }\n  \n  resetState();\n  scrollToBottom();\n  \n  // Refresh conversation list after task ends\n  loadConversations();\n  refreshResumeButton();\n});\n\n// ==================== Message Builders ====================\n\nfunction addUserMessage(text) {\n  const div = document.createElement('div');\n  div.className = 'message-user';\n  div.innerHTML = `<div class=\"bubble\">${escapeHtml(text)}</div>`;\n  messagesContainer.appendChild(div);\n  scrollToBottom();\n}\n\nfunction addSystemMessage(text) {\n  const div = document.createElement('div');\n  div.className = 'message-system';\n  div.textContent = `— ${text} —`;\n  messagesContainer.appendChild(div);\n}\n\nfunction addErrorMessage(text) {\n  const div = document.createElement('div');\n  div.className = 'message-error';\n  div.innerHTML = `<div class=\"error-card\">${escapeHtml(text)}</div>`;\n  messagesContainer.appendChild(div);\n}\n\nfunction addToolMessage(toolName, status, args) {\n  const div = document.createElement('div');\n  div.className = 'message-tool';\n  \n  let argsHtml = '';\n  if (args && typeof args === 'object' && Object.keys(args).length > 0) {\n    const argsStr = JSON.stringify(args, null, 2);\n    argsHtml = `\n      <details class=\"tool-details\">\n        <summary class=\"tool-params-toggle\">Parameters</summary>\n        <pre class=\"tool-params-content\">${escapeHtml(argsStr)}</pre>\n      </details>\n    `;\n  }\n\n  // Human-in-loop: inline response UI (seamless)\n  let hilHtml = '';\n  if (toolName === 'human_in_loop' && args && typeof args === 'object') {\n    const hilId = args.hil_id || '';\n    const instruction = args.instruction || '';\n    if (hilId && instruction) {\n      hilHtml = `\n        <div class=\"hil-card\">\n          <div class=\"hil-title\">Human-in-loop</div>\n          <div class=\"hil-instruction\">${escapeHtml(String(instruction))}</div>\n          <div class=\"hil-actions\">\n            <textarea class=\"hil-input\" rows=\"3\" placeholder=\"在这里输入你的回复，然后发送…\"></textarea>\n            <button class=\"btn hil-send\">Send</button>\n          </div>\n          <div class=\"hil-meta\">hil_id: <code>${escapeHtml(String(hilId))}</code></div>\n        </div>\n      `;\n    }\n  }\n  \n  div.innerHTML = `\n    <div class=\"tool-card tool-${status}\">\n      <div class=\"tool-header\">\n        <span class=\"tool-dot tool-dot-${status}\"></span>\n        <span class=\"tool-name\">${escapeHtml(toolName)}</span>\n        <span class=\"tool-status-label\">${status === 'running' ? 'running...' : status}</span>\n      </div>\n      ${argsHtml}\n      ${hilHtml}\n      <div class=\"tool-result-area\" style=\"display:none;\"></div>\n    </div>\n  `;\n  div.dataset.toolMessage = 'true';\n  messagesContainer.appendChild(div);\n\n  // Bind HIL send button if present\n  if (toolName === 'human_in_loop' && args && typeof args === 'object') {\n    const hilId = args.hil_id;\n    const sendBtn = div.querySelector('.hil-send');\n    const input = div.querySelector('.hil-input');\n    if (sendBtn && input && hilId) {\n      sendBtn.addEventListener('click', async () => {\n        const text = (input.value || '').trim();\n        if (!text) return;\n        sendBtn.disabled = true;\n        input.disabled = true;\n        sendBtn.textContent = 'Sent';\n        const r = await window.api.hilRespond({ hil_id: hilId, response: text });\n        if (r && r.error) {\n          sendBtn.disabled = false;\n          input.disabled = false;\n          sendBtn.textContent = 'Send';\n          addErrorMessage(`HIL respond failed: ${r.error}`);\n        } else {\n          // show as a user message in chat for traceability\n          addUserMessage(text);\n        }\n      });\n    }\n  }\n  scrollToBottom();\n}\n\nfunction updateLastToolStatus(status, outputPreview) {\n  const tools = messagesContainer.querySelectorAll('[data-tool-message]');\n  if (tools.length > 0) {\n    const last = tools[tools.length - 1];\n    const card = last.querySelector('.tool-card');\n    const dot = last.querySelector('.tool-dot');\n    const label = last.querySelector('.tool-status-label');\n    if (card) card.className = `tool-card tool-${status}`;\n    if (dot) dot.className = `tool-dot tool-dot-${status}`;\n    if (label) label.textContent = status === 'success' ? 'done' : status;\n    \n    if (outputPreview) {\n      const resultArea = last.querySelector('.tool-result-area');\n      if (resultArea) {\n        resultArea.style.display = 'block';\n        resultArea.innerHTML = `\n          <details class=\"tool-details\">\n            <summary class=\"tool-params-toggle\">Result</summary>\n            <pre class=\"tool-params-content\">${escapeHtml(outputPreview)}</pre>\n          </details>\n        `;\n      }\n    }\n  }\n}\n\n// ==================== Streaming ====================\n\nfunction streamToken(text) {\n  if (!currentAgentBubble) {\n    const wrapper = document.createElement('div');\n    wrapper.className = 'message-agent';\n    \n    const bubble = document.createElement('div');\n    bubble.className = 'bubble';\n    \n    const label = document.createElement('div');\n    label.className = 'agent-label';\n    label.textContent = 'Agent';\n    \n    const content = document.createElement('div');\n    content.className = 'agent-content';\n    \n    bubble.appendChild(label);\n    bubble.appendChild(content);\n    wrapper.appendChild(bubble);\n    messagesContainer.appendChild(wrapper);\n    \n    currentAgentBubble = wrapper;\n    currentAgentContentDiv = content;\n    currentStreamText = '';\n  }\n  \n  currentStreamText += text;\n  currentAgentContentDiv.innerText = currentStreamText;\n  scrollToBottom();\n}\n\nfunction finalizeCurrentStream() {\n  // Convert the just-streamed text to Markdown on finalize\n  if (currentAgentContentDiv && currentStreamText) {\n    setMarkdown(currentAgentContentDiv, currentStreamText);\n  }\n  currentAgentBubble = null;\n  currentAgentContentDiv = null;\n  currentStreamText = '';\n}\n\n// ==================== Reasoning Stream ====================\n\nlet reasoningBubble = null;\nlet reasoningContentDiv = null;\nlet reasoningStreamText = '';\n\nfunction streamReasoningToken(text) {\n  if (!reasoningBubble) {\n    const div = document.createElement('div');\n    div.className = 'message-thinking';\n    div.innerHTML = `\n      <div class=\"thinking-card\">\n        <details open>\n          <summary>Model Reasoning</summary>\n          <div class=\"thinking-content\"></div>\n        </details>\n      </div>\n    `;\n    messagesContainer.appendChild(div);\n    reasoningBubble = div;\n    reasoningContentDiv = div.querySelector('.thinking-content');\n    reasoningStreamText = '';\n  }\n  \n  reasoningStreamText += text;\n  reasoningContentDiv.innerText = reasoningStreamText;\n  scrollToBottom();\n}\n\nfunction finalizeReasoningStream() {\n  if (reasoningBubble) {\n    const details = reasoningBubble.querySelector('details');\n    if (details) {\n      details.open = false;\n      const summary = details.querySelector('summary');\n      if (summary) summary.textContent = 'Model Reasoning (click to expand)';\n    }\n  }\n  // Convert reasoning to Markdown before finalize\n  if (reasoningContentDiv && reasoningStreamText) {\n    setMarkdown(reasoningContentDiv, reasoningStreamText);\n  }\n  reasoningBubble = null;\n  reasoningContentDiv = null;\n  reasoningStreamText = '';\n}\n\n// ==================== Thinking Agent Stream ====================\n\nlet thinkingAgentBubble = null;\nlet thinkingAgentContentDiv = null;\nlet thinkingAgentText = '';\n\nfunction startThinkingAgentStream() {\n  const div = document.createElement('div');\n  div.className = 'message-thinking';\n  div.innerHTML = `\n    <div class=\"thinking-card\">\n      <details open>\n        <summary>Thinking...</summary>\n        <div class=\"thinking-content\"></div>\n      </details>\n    </div>\n  `;\n  messagesContainer.appendChild(div);\n  thinkingAgentBubble = div;\n  thinkingAgentContentDiv = div.querySelector('.thinking-content');\n  thinkingAgentText = '';\n  scrollToBottom();\n}\n\nfunction streamThinkingAgentToken(text) {\n  if (!thinkingAgentBubble) startThinkingAgentStream();\n  thinkingAgentText += text;\n  thinkingAgentContentDiv.innerText = thinkingAgentText;\n  scrollToBottom();\n}\n\nfunction finalizeThinkingAgentStream() {\n  if (thinkingAgentBubble) {\n    const details = thinkingAgentBubble.querySelector('details');\n    if (details) {\n      details.open = false;\n      const summary = details.querySelector('summary');\n      if (summary) summary.textContent = 'Thinking (click to expand)';\n    }\n  }\n  // Convert thinking to Markdown before finalize\n  if (thinkingAgentContentDiv && thinkingAgentText) {\n    setMarkdown(thinkingAgentContentDiv, thinkingAgentText);\n  }\n  thinkingAgentBubble = null;\n  thinkingAgentContentDiv = null;\n  thinkingAgentText = '';\n}\n\n// ==================== UI Helpers ====================\n\nfunction showTypingIndicator() {\n  if (messagesContainer.querySelector('.typing-indicator')) return;\n  const div = document.createElement('div');\n  div.className = 'typing-indicator';\n  div.innerHTML = '<div class=\"typing-dot\"></div><div class=\"typing-dot\"></div><div class=\"typing-dot\"></div>';\n  messagesContainer.appendChild(div);\n  scrollToBottom();\n}\n\nfunction removeTypingIndicator() {\n  const indicator = messagesContainer.querySelector('.typing-indicator');\n  if (indicator) indicator.remove();\n}\n\nfunction resetState() {\n  isRunning = false;\n  sendBtn.style.display = 'flex';\n  stopBtn.style.display = 'none';\n  userInput.disabled = false;\n  userInput.focus();\n  refreshResumeButton();\n}\n\nfunction scrollToBottom() {\n  if (!autoScrollEnabled) return;\n  requestAnimationFrame(() => {\n    messagesContainer.scrollTop = messagesContainer.scrollHeight;\n  });\n}\n\nfunction forceScrollToBottom() {\n  requestAnimationFrame(() => {\n    messagesContainer.scrollTop = messagesContainer.scrollHeight;\n  });\n}\n\nfunction escapeHtml(text) {\n  const div = document.createElement('div');\n  div.textContent = text;\n  return div.innerHTML;\n}\n\n// ==================== Auto Scroll Toggle ====================\nfunction updateAutoScrollBtn() {\n  if (!autoScrollBtn) return;\n  autoScrollBtn.textContent = autoScrollEnabled ? 'Auto Scroll: On' : 'Auto Scroll: Off';\n  autoScrollBtn.classList.toggle('off', !autoScrollEnabled);\n}\n\nif (autoScrollBtn) {\n  autoScrollBtn.addEventListener('click', () => {\n    autoScrollEnabled = !autoScrollEnabled;\n    updateAutoScrollBtn();\n    if (autoScrollEnabled) forceScrollToBottom();\n  });\n  updateAutoScrollBtn();\n}\n\n// Keep chat scroll usable even when nested <pre>/<thinking> areas exist.\n// If inner scroll area can't continue scrolling in current direction,\n// route wheel delta to the main messages container.\nif (messagesContainer) {\n  const INNER_SCROLL_SELECTOR = '.tool-params-content, .thinking-content';\n  messagesContainer.addEventListener('wheel', (e) => {\n    let node = e.target;\n    while (node && node !== messagesContainer) {\n      if (node.matches && node.matches(INNER_SCROLL_SELECTOR)) {\n        const canScrollUp = node.scrollTop > 0;\n        const canScrollDown = node.scrollTop + node.clientHeight < node.scrollHeight - 1;\n        if ((e.deltaY < 0 && canScrollUp) || (e.deltaY > 0 && canScrollDown)) {\n          return; // Let inner panel consume wheel\n        }\n        break; // Inner panel at edge -> fall through to main container\n      }\n      node = node.parentElement;\n    }\n    e.preventDefault();\n    messagesContainer.scrollTop += e.deltaY;\n  }, { passive: false });\n}\n\n// ==================== Settings Modal ====================\n\nconst settingsModal = document.getElementById('settings-modal');\nconst settingsBtn = document.getElementById('settings-btn');\nconst settingsCloseBtn = document.getElementById('settings-close-btn');\nconst settingsSaveBtn = document.getElementById('settings-save-btn');\nconst settingsStatus = document.getElementById('settings-status');\nconst toggleApiKeyBtn = document.getElementById('toggle-api-key');\nconst importAgentSystemBtn = document.getElementById('import-agent-system-btn');\nconst deleteAgentSystemBtn = document.getElementById('delete-agent-system-btn');\nconst rawYamlTextarea = document.getElementById('setting-raw-yaml');\nconst freshRuntimeBtn = document.getElementById('fresh-runtime-btn');\n\n// Open settings\nsettingsBtn.addEventListener('click', async () => {\n  settingsModal.style.display = 'flex';\n  await loadSettings();\n});\n\n// Close settings\nsettingsCloseBtn.addEventListener('click', () => {\n  settingsModal.style.display = 'none';\n});\n\nsettingsModal.addEventListener('click', (e) => {\n  if (e.target === settingsModal) settingsModal.style.display = 'none';\n});\n\n// Tab switching\ndocument.querySelectorAll('.modal-tab').forEach(tab => {\n  tab.addEventListener('click', () => {\n    document.querySelectorAll('.modal-tab').forEach(t => t.classList.remove('active'));\n    document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));\n    tab.classList.add('active');\n    document.getElementById(`tab-${tab.dataset.tab}`).classList.add('active');\n  });\n});\n\n// Toggle API key visibility\ntoggleApiKeyBtn.addEventListener('click', () => {\n  const input = document.getElementById('setting-api-key');\n  input.type = input.type === 'password' ? 'text' : 'password';\n});\n\n// Load settings from backend\nasync function loadSettings() {\n  const result = await window.api.getSettings();\n  if (result.error) {\n    settingsStatus.textContent = `Error: ${result.error}`;\n    settingsStatus.style.color = '#c75450';\n    return;\n  }\n  \n  const c = result.config;\n  lastLoadedSettingsConfig = (c && typeof c === 'object') ? c : {};\n  document.getElementById('setting-base-url').value = c.base_url || '';\n  document.getElementById('setting-api-key').value = c.api_key || '';\n  document.getElementById('setting-timeout').value = c.timeout || 600;\n  document.getElementById('setting-stream-timeout').value = c.stream_timeout || 30;\n  document.getElementById('setting-first-chunk-timeout').value = c.first_chunk_timeout || 30;\n  document.getElementById('setting-temperature').value = c.temperature ?? 0;\n  document.getElementById('setting-max-tokens').value = c.max_tokens ?? 0;\n  document.getElementById('setting-max-context').value = c.max_context_window || 500000;\n  document.getElementById('setting-multimodal').checked = c.multimodal !== false;\n  document.getElementById('setting-compressor-multimodal').checked = c.compressor_multimodal !== false;\n  \n  loadModelEditorSettings(c);\n\n  // Raw yaml\n  if (rawYamlTextarea) rawYamlTextarea.value = result.raw_yaml || '';\n  \n  // Config path display\n  document.getElementById('config-path-display').textContent = result.path || '—';\n  \n  // Load agent systems for both sidebar + settings\n  await reloadAgentSystems(agentSystemSelect.value);\n\n  // Load app config (env + market)\n  const appCfgRes = await window.api.getAppConfig();\n  if (appCfgRes?.success) {\n    const cfg = appCfgRes.config || {};\n    const env = cfg.env || {};\n    const runtime = cfg.runtime || {};\n    const context = cfg.context || {};\n    const mcp = cfg.mcp || {};\n    const market = cfg.market || {};\n    const pathModeEl = document.getElementById('setting-path-mode');\n    const commandModeEl = document.getElementById('setting-command-mode');\n    const extraPathEl = document.getElementById('setting-extra-path');\n    const extraEnvEl = document.getElementById('setting-extra-env');\n    const marketUrlEl = document.getElementById('setting-market-url');\n    if (pathModeEl) pathModeEl.value = env.shell_mode || 'system';\n    if (commandModeEl) commandModeEl.value = env.command_mode || 'direct';\n    if (extraPathEl) extraPathEl.value = Array.isArray(env.extra_path) ? env.extra_path.join('\\n') : '';\n    if (extraEnvEl) {\n      const extraEnv = env.extra_env || {};\n      const lines = Object.entries(extraEnv).map(([k, v]) => `${k}=${v ?? ''}`);\n      extraEnvEl.value = lines.join('\\n');\n    }\n    if (marketUrlEl) marketUrlEl.value = market.base_url || '';\n    const thinkingEnabledEl = document.getElementById('setting-thinking-enabled');\n    const thinkingStepsEl = document.getElementById('setting-thinking-steps');\n    const noToolRetryLimitEl = document.getElementById('setting-no-tool-retry-limit');\n    const maxTurnsEl = document.getElementById('setting-max-turns');\n    const freshEnabledEl = document.getElementById('setting-fresh-enabled');\n    const freshIntervalEl = document.getElementById('setting-fresh-interval-sec');\n    const userHistoryThresholdEl = document.getElementById('setting-user-history-threshold');\n    const userHistoryRecentItemsEl = document.getElementById('setting-user-history-recent-items');\n    const structuredAgentThresholdEl = document.getElementById('setting-structured-call-agent-threshold');\n    const structuredTokenThresholdEl = document.getElementById('setting-structured-call-token-threshold');\n    const mcpServersEl = document.getElementById('setting-mcp-servers');\n    const visibleSkillsEl = document.getElementById('setting-visible-skills');\n    if (thinkingEnabledEl) thinkingEnabledEl.checked = runtime.thinking_enabled !== false;\n    if (thinkingStepsEl) thinkingStepsEl.value = runtime.thinking_steps ?? runtime.thinking_interval ?? runtime.action_window_steps ?? 30;\n    if (noToolRetryLimitEl) noToolRetryLimitEl.value = runtime.no_tool_retry_limit ?? 7;\n    if (maxTurnsEl) maxTurnsEl.value = runtime.max_turns ?? 100000;\n    if (freshEnabledEl) freshEnabledEl.checked = !!runtime.fresh_enabled;\n    if (freshIntervalEl) freshIntervalEl.value = runtime.fresh_interval_sec ?? 0;\n    if (userHistoryThresholdEl) userHistoryThresholdEl.value = context.user_history_compress_threshold_tokens ?? 1500;\n    if (userHistoryRecentItemsEl) userHistoryRecentItemsEl.value = context.user_history_recent_items ?? 0;\n    if (structuredAgentThresholdEl) structuredAgentThresholdEl.value = context.structured_call_info_compress_threshold_agents ?? 10;\n    if (structuredTokenThresholdEl) structuredTokenThresholdEl.value = context.structured_call_info_compress_threshold_tokens ?? 2200;\n    if (mcpServersEl) {\n      const lines = Array.isArray(mcp.servers) ? mcp.servers.map(item => JSON.stringify(item)) : [];\n      mcpServersEl.value = lines.join('\\n');\n    }\n    if (visibleSkillsEl) {\n      const lines = Array.isArray(runtime.visible_skills) ? runtime.visible_skills : [];\n      visibleSkillsEl.value = lines.join('\\n');\n    }\n  }\n  \n  settingsStatus.textContent = '';\n}\n\n// Import agent system folder\nif (importAgentSystemBtn) {\n  importAgentSystemBtn.addEventListener('click', async () => {\n    const result = await window.api.importAgentSystemFolder();\n    if (result?.canceled) return;\n    if (result?.error) {\n      settingsStatus.textContent = `Error: ${result.error}`;\n      settingsStatus.style.color = '#c75450';\n      return;\n    }\n    settingsStatus.textContent = `Imported Agent System: ${result.name}`;\n    settingsStatus.style.color = '#5a9a6a';\n\n    await reloadAgentSystems(result?.name || null);\n\n    setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n  });\n}\n\n// Delete selected agent system (user library only)\nif (deleteAgentSystemBtn) {\n  deleteAgentSystemBtn.addEventListener('click', async () => {\n    const select = document.getElementById('setting-agent-system');\n    const sys = select?.value;\n    if (!sys) return;\n    if (!confirm(`Delete Agent System \"${sys}\" from ~/mla_v3/agent_library/? (Bundled copy inside app is untouched)`)) return;\n    const res = await window.api.deleteAgentSystem(sys);\n    if (res?.error) {\n      settingsStatus.textContent = `Error: ${res.error}`;\n      settingsStatus.style.color = '#c75450';\n      return;\n    }\n    settingsStatus.textContent = `Deleted Agent System: ${sys}`;\n    settingsStatus.style.color = '#5a9a6a';\n    await reloadAgentSystems();\n    setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n  });\n}\n\nif (freshRuntimeBtn) {\n  freshRuntimeBtn.addEventListener('click', async () => {\n    const res = await window.api.freshRuntime({ reason: 'manual fresh from desktop settings' });\n    if (res?.error) {\n      settingsStatus.textContent = `Error: ${res.error}`;\n      settingsStatus.style.color = '#c75450';\n      return;\n    }\n    await reloadAgentSystems(agentSystemSelect.value);\n    settingsStatus.textContent = res?.running\n      ? 'Fresh request sent to running task'\n      : 'Runtime config updated. New tasks will use fresh settings';\n    settingsStatus.style.color = '#5a9a6a';\n    setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n  });\n}\n\n// Save settings\nsettingsSaveBtn.addEventListener('click', async () => {\n  // If Raw YAML tab is active, save raw YAML as-is\n  const activeTab = document.querySelector('.modal-tab.active')?.dataset?.tab;\n  if (activeTab === 'yaml') {\n    const yamlText = (rawYamlTextarea?.value || '').trimEnd() + '\\n';\n    const result = await window.api.saveSettings(yamlText);\n    if (result.success) {\n      await loadSettings();\n      settingsStatus.textContent = 'YAML saved successfully';\n      settingsStatus.style.color = '#5a9a6a';\n    } else {\n      settingsStatus.textContent = `Error: ${result.error}`;\n      settingsStatus.style.color = '#c75450';\n    }\n    setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n    return;\n  }\n\n  // Environment tab saves app_config.json\n  if (activeTab === 'env') {\n    const mode = document.getElementById('setting-path-mode')?.value || 'system';\n    const commandMode = document.getElementById('setting-command-mode')?.value || 'direct';\n    const extraPathText = document.getElementById('setting-extra-path')?.value || '';\n    const extraEnvText = document.getElementById('setting-extra-env')?.value || '';\n    const marketUrl = document.getElementById('setting-market-url')?.value || '';\n    const visibleSkillsText = document.getElementById('setting-visible-skills')?.value || '';\n\n    const extra_path = extraPathText.split('\\n').map(s => s.trim()).filter(Boolean);\n    const extra_env = {};\n    for (const line of extraEnvText.split('\\n')) {\n      const t = line.trim();\n      if (!t || t.startsWith('#')) continue;\n      const idx = t.indexOf('=');\n      if (idx <= 0) continue;\n      const k = t.slice(0, idx).trim();\n      const v = t.slice(idx + 1).trim();\n      if (k) extra_env[k] = v;\n    }\n\n    const mcpServersText = document.getElementById('setting-mcp-servers')?.value || '';\n    const mcpServers = [];\n    for (const rawLine of mcpServersText.split('\\n')) {\n      const line = rawLine.trim();\n      if (!line || line.startsWith('#')) continue;\n      if (line.startsWith('{')) {\n        try {\n          const parsed = JSON.parse(line);\n          if (parsed && typeof parsed === 'object') mcpServers.push(parsed);\n        } catch (_) {}\n        continue;\n      }\n      const idx = line.indexOf('=');\n      if (idx > 0) {\n        const name = line.slice(0, idx).trim();\n        const url = line.slice(idx + 1).trim();\n        if (name && url) mcpServers.push({ name, transport: 'streamable_http', url });\n      } else {\n        mcpServers.push({ transport: 'streamable_http', url: line });\n      }\n    }\n\n    const visible_skills = visibleSkillsText\n      .split('\\n')\n      .map((line) => line.trim())\n      .filter(Boolean);\n\n    const thinkingEnabled = !!document.getElementById('setting-thinking-enabled')?.checked;\n    const thinkingSteps = readPositiveNumber(document.getElementById('setting-thinking-steps')?.value, 30);\n\n    const appCfg = {\n      env: { shell_mode: mode, command_mode: commandMode, extra_path, extra_env },\n      runtime: {\n        action_window_steps: thinkingSteps,\n        thinking_interval: thinkingSteps,\n        thinking_enabled: thinkingEnabled,\n        thinking_steps: thinkingSteps,\n        no_tool_retry_limit: readPositiveNumber(document.getElementById('setting-no-tool-retry-limit')?.value, 7),\n        visible_skills,\n        max_turns: readPositiveNumber(document.getElementById('setting-max-turns')?.value, 100000),\n        fresh_enabled: !!document.getElementById('setting-fresh-enabled')?.checked,\n        fresh_interval_sec: Number(document.getElementById('setting-fresh-interval-sec')?.value) || 0\n      },\n      context: {\n        user_history_compress_threshold_tokens: readNonNegativeNumber(document.getElementById('setting-user-history-threshold')?.value, 1500),\n        user_history_recent_items: readNonNegativeNumber(document.getElementById('setting-user-history-recent-items')?.value, 0),\n        structured_call_info_compress_threshold_agents: readPositiveNumber(document.getElementById('setting-structured-call-agent-threshold')?.value, 10),\n        structured_call_info_compress_threshold_tokens: readNonNegativeNumber(document.getElementById('setting-structured-call-token-threshold')?.value, 2200)\n      },\n      mcp: { servers: mcpServers },\n      market: { base_url: String(marketUrl || '').trim() }\n    };\n\n    const res = await window.api.saveAppConfig(appCfg);\n    if (res?.success) {\n      await loadSettings();\n      settingsStatus.textContent = 'Environment settings saved';\n      settingsStatus.style.color = '#5a9a6a';\n    } else {\n      settingsStatus.textContent = `Error: ${res?.error || 'Failed to save'}`;\n      settingsStatus.style.color = '#c75450';\n    }\n    setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n    return;\n  }\n\n  const config = buildModelEditorConfig({\n    ...lastLoadedSettingsConfig,\n    temperature: Number(document.getElementById('setting-temperature').value) || 0,\n    max_tokens: Number(document.getElementById('setting-max-tokens').value) || 0,\n    max_context_window: Number(document.getElementById('setting-max-context').value) || 500000,\n    base_url: document.getElementById('setting-base-url').value.trim(),\n    api_key: document.getElementById('setting-api-key').value.trim(),\n    timeout: Number(document.getElementById('setting-timeout').value) || 600,\n    stream_timeout: Number(document.getElementById('setting-stream-timeout').value) || 30,\n    first_chunk_timeout: Number(document.getElementById('setting-first-chunk-timeout').value) || 30,\n    multimodal: document.getElementById('setting-multimodal').checked,\n    compressor_multimodal: document.getElementById('setting-compressor-multimodal').checked\n  });\n  \n  const result = await window.api.saveSettings(config);\n  if (result.success) {\n    settingsStatus.textContent = 'Settings saved successfully';\n    settingsStatus.style.color = '#5a9a6a';\n    await loadSettings();\n    \n    // Sync agent system select in sidebar\n    const agentSys = document.getElementById('setting-agent-system').value;\n    if (agentSys) {\n      // Update sidebar select if the option exists\n      const opt = agentSystemSelect.querySelector(`option[value=\"${agentSys}\"]`);\n      if (opt) agentSystemSelect.value = agentSys;\n    }\n  } else {\n    settingsStatus.textContent = `Error: ${result.error}`;\n    settingsStatus.style.color = '#c75450';\n  }\n  \n  setTimeout(() => { settingsStatus.textContent = ''; }, 3000);\n});\n\n// ==================== Marketplace Modal ====================\n\nconst marketModal = document.getElementById('market-modal');\nconst marketBtn = document.getElementById('market-btn');\nconst marketCloseBtn = document.getElementById('market-close-btn');\nconst marketRefreshBtn = document.getElementById('market-refresh-btn');\nconst marketSearch = document.getElementById('market-search');\nconst marketList = document.getElementById('market-list');\nconst marketStatus = document.getElementById('market-status');\nconst marketTabSkills = document.getElementById('market-tab-skills');\nconst marketTabSystems = document.getElementById('market-tab-systems');\n\nlet marketIndexCache = null;\nlet marketActiveKind = 'skill'; // 'skill' | 'agent_system'\n\nfunction setMarketStatus(text, isError = false) {\n  if (!marketStatus) return;\n  marketStatus.textContent = text || '';\n  marketStatus.style.color = isError ? '#c75450' : '#5a9a6a';\n}\n\nconst MODEL_EDITOR_SLOT_CONFIG_KEYS = {\n  shared: null,\n  main: 'models',\n  read: 'read_figure_models',\n  figure: 'figure_models',\n  compressor: 'compressor_models',\n  thinking: 'thinking_models'\n};\n\nconst MODEL_EDITOR_PROVIDER_OPTIONS = `\n  <option value=\"openrouter\">OpenRouter</option>\n  <option value=\"openai_compatible\">OpenAI-compatible API</option>\n  <option value=\"openai_official\">OpenAI Official</option>\n  <option value=\"google_official\">Google Official</option>\n  <option value=\"anthropic_official\">Anthropic Official</option>\n  <option value=\"local_openai_compatible\">Local / Keyless OpenAI-compatible</option>\n`;\n\nlet modelEditorEntryCounter = 0;\nlet modelEditorState = createEmptyModelEditorState();\n\nfunction createEmptyModelEditorState() {\n  return {\n    shared: [],\n    main: [],\n    read: [],\n    figure: [],\n    compressor: [],\n    thinking: []\n  };\n}\n\nfunction nextModelEditorId() {\n  modelEditorEntryCounter += 1;\n  return `model-entry-${modelEditorEntryCounter}`;\n}\n\nfunction inferModelProviderKind(modelName, entryBaseUrl, globalBaseUrl, hasApiKey) {\n  const name = String(modelName || '').trim();\n  const effectiveBaseUrl = String(entryBaseUrl || globalBaseUrl || '').trim().toLowerCase();\n  if (name.startsWith('openrouter/')) return 'openrouter';\n  if (effectiveBaseUrl.includes('openrouter.ai')) return 'openrouter';\n  if (name.startsWith('google/')) return 'google_official';\n  if (name.startsWith('anthropic/')) return 'anthropic_official';\n  if (name.startsWith('openai/')) {\n    if (entryBaseUrl) return hasApiKey ? 'openai_compatible' : 'local_openai_compatible';\n    return 'openai_official';\n  }\n  if (entryBaseUrl) return hasApiKey ? 'openai_compatible' : 'local_openai_compatible';\n  return 'openai_official';\n}\n\nfunction stripModelNameForProvider(providerKind, modelName, entryBaseUrl, globalBaseUrl) {\n  let name = String(modelName || '').trim();\n  const effectiveBaseUrl = String(entryBaseUrl || globalBaseUrl || '').trim().toLowerCase();\n  if (!name) return '';\n  if (providerKind === 'openrouter') {\n    if (name.startsWith('openrouter/')) return name.slice('openrouter/'.length);\n    if (effectiveBaseUrl.includes('openrouter.ai') && name.startsWith('openai/') && name.slice('openai/'.length).includes('/')) {\n      return name.slice('openai/'.length);\n    }\n    return name;\n  }\n  if (providerKind === 'google_official' && name.startsWith('google/')) return name.slice('google/'.length);\n  if (providerKind === 'anthropic_official' && name.startsWith('anthropic/')) return name.slice('anthropic/'.length);\n  if (name.startsWith('openai/')) return name.slice('openai/'.length);\n  return name;\n}\n\nfunction normalizeModelNameForProvider(providerKind, modelName) {\n  const raw = String(modelName || '').trim();\n  if (!raw) return '';\n  if (providerKind === 'openrouter') {\n    return raw.startsWith('openrouter/') ? raw : `openrouter/${raw}`;\n  }\n  const expectedPrefix = {\n    openai_compatible: 'openai/',\n    openai_official: 'openai/',\n    google_official: 'google/',\n    anthropic_official: 'anthropic/',\n    local_openai_compatible: 'openai/'\n  }[providerKind] || 'openai/';\n  if (raw.startsWith(expectedPrefix)) return raw;\n  return `${expectedPrefix}${raw.replace(/^(openrouter|openai|google|anthropic)\\//, '')}`;\n}\n\nfunction makeBlankModelEditorEntry() {\n  return {\n    id: nextModelEditorId(),\n    provider: 'openrouter',\n    model: '',\n    source: 'default',\n    base_url: '',\n    api_key: '',\n    tool_choice: ''\n  };\n}\n\nfunction deserializeModelEditorEntry(rawEntry, globalBaseUrl) {\n  const isObject = rawEntry && typeof rawEntry === 'object' && !Array.isArray(rawEntry);\n  const modelName = isObject ? String(rawEntry.name || '') : String(rawEntry || '');\n  const baseUrl = isObject ? String(rawEntry.base_url || '') : '';\n  const apiKey = isObject ? String(rawEntry.api_key || '') : '';\n  const toolChoice = isObject ? String(rawEntry.tool_choice || '') : '';\n  const provider = inferModelProviderKind(modelName, baseUrl, globalBaseUrl, !!apiKey);\n  return {\n    id: nextModelEditorId(),\n    provider,\n    model: stripModelNameForProvider(provider, modelName, baseUrl, globalBaseUrl),\n    source: (baseUrl || apiKey) ? 'custom' : 'default',\n    base_url: baseUrl,\n    api_key: apiKey,\n    tool_choice: toolChoice\n  };\n}\n\nfunction serializeModelEditorComparable(entry) {\n  return JSON.stringify({\n    provider: String(entry?.provider || '').trim(),\n    model: String(entry?.model || '').trim(),\n    source: String(entry?.source || 'default').trim(),\n    base_url: String(entry?.base_url || '').trim(),\n    api_key: String(entry?.api_key || '').trim(),\n    tool_choice: String(entry?.tool_choice || '').trim()\n  });\n}\n\nfunction cloneModelEditorEntry(entry) {\n  return {\n    id: nextModelEditorId(),\n    provider: entry.provider,\n    model: entry.model,\n    source: entry.source,\n    base_url: entry.base_url,\n    api_key: entry.api_key,\n    tool_choice: entry.tool_choice\n  };\n}\n\nfunction computeSharedModelEntries(slotEntries) {\n  const orderedBase = slotEntries.main || [];\n  if (!orderedBase.length) return [];\n  const otherSlots = ['read', 'figure', 'compressor', 'thinking'];\n  return orderedBase\n    .filter((entry) => otherSlots.every((slot) => (slotEntries[slot] || []).some((candidate) => serializeModelEditorComparable(candidate) === serializeModelEditorComparable(entry))))\n    .map((entry) => cloneModelEditorEntry(entry));\n}\n\nfunction createModelEntryPayload(entry) {\n  const resolvedName = normalizeModelNameForProvider(entry.provider, entry.model);\n  if (!resolvedName) return null;\n  const sourceMode = entry.source === 'custom' ? 'custom' : 'default';\n  const payload = { name: resolvedName };\n  if (sourceMode === 'custom' && String(entry.base_url || '').trim()) payload.base_url = String(entry.base_url || '').trim();\n  if (sourceMode === 'custom' && String(entry.api_key || '').trim()) payload.api_key = String(entry.api_key || '').trim();\n  if (String(entry.tool_choice || '').trim()) payload.tool_choice = String(entry.tool_choice || '').trim();\n  return Object.keys(payload).length === 1 ? payload.name : payload;\n}\n\nfunction buildModelEditorConfig(baseConfig) {\n  const config = { ...baseConfig };\n  const sharedPayload = modelEditorState.shared.map(createModelEntryPayload).filter(Boolean);\n  Object.entries(MODEL_EDITOR_SLOT_CONFIG_KEYS).forEach(([slotKey, configKey]) => {\n    if (!configKey) return;\n    const slotPayload = (modelEditorState[slotKey] || []).map(createModelEntryPayload).filter(Boolean);\n    config[configKey] = [...sharedPayload, ...slotPayload];\n  });\n  return config;\n}\n\nfunction getModelEditorEntry(slotKey, entryId) {\n  return (modelEditorState[slotKey] || []).find((entry) => entry.id === entryId);\n}\n\nfunction renderModelEditorEntry(slotKey, entry) {\n  const resolvedName = normalizeModelNameForProvider(entry.provider, entry.model);\n  const customVisible = entry.source === 'custom' ? '' : 'display:none;';\n  return `\n    <div class=\"model-entry-card\" data-slot=\"${slotKey}\" data-id=\"${entry.id}\">\n      <div class=\"model-entry-topbar\">\n        <div class=\"form-group form-half\">\n          <label class=\"form-label\">Provider</label>\n          <select class=\"form-input\" data-model-field=\"provider\">\n            ${MODEL_EDITOR_PROVIDER_OPTIONS}\n          </select>\n        </div>\n        <div class=\"form-group form-half\">\n          <label class=\"form-label\">Source</label>\n          <select class=\"form-input\" data-model-field=\"source\">\n            <option value=\"default\">Use default URL / Key</option>\n            <option value=\"custom\">Custom URL / Key</option>\n          </select>\n        </div>\n        <div class=\"form-group form-half\">\n          <label class=\"form-label\">Tool Choice</label>\n          <select class=\"form-input\" data-model-field=\"tool_choice\">\n            <option value=\"\">Default</option>\n            <option value=\"required\">required</option>\n            <option value=\"auto\">auto</option>\n            <option value=\"none\">none</option>\n          </select>\n        </div>\n        <div class=\"model-entry-actions\">\n          <button class=\"btn-secondary\" type=\"button\" data-model-action=\"delete\">Delete</button>\n        </div>\n      </div>\n      <div class=\"form-group\">\n        <label class=\"form-label\">Model Name</label>\n        <input type=\"text\" class=\"form-input\" data-model-field=\"model\" placeholder=\"For OpenRouter use vendor/model, e.g. google/gemini-3-flash-preview\" value=\"${escapeHtml(entry.model)}\">\n        <div class=\"model-entry-preview\">Resolved model id: <code>${escapeHtml(resolvedName || '(empty)')}</code></div>\n      </div>\n      <div class=\"form-row model-entry-custom-source\" style=\"${customVisible}\">\n        <div class=\"form-group form-half\">\n          <label class=\"form-label\">Custom Base URL</label>\n          <input type=\"text\" class=\"form-input\" data-model-field=\"base_url\" placeholder=\"https://...\" value=\"${escapeHtml(entry.base_url)}\">\n        </div>\n        <div class=\"form-group form-half\">\n          <label class=\"form-label\">Custom API Key</label>\n          <input type=\"text\" class=\"form-input\" data-model-field=\"api_key\" placeholder=\"sk-...\" value=\"${escapeHtml(entry.api_key)}\">\n        </div>\n      </div>\n    </div>\n  `;\n}\n\nfunction renderModelEditorSlot(slotKey) {\n  const container = document.getElementById(`model-${slotKey}-list`);\n  if (!container) return;\n  const entries = modelEditorState[slotKey] || [];\n  if (!entries.length) {\n    container.innerHTML = '<div class=\"model-slot-empty\">No models configured for this section.</div>';\n    return;\n  }\n  container.innerHTML = entries.map((entry) => renderModelEditorEntry(slotKey, entry)).join('');\n  entries.forEach((entry) => {\n    const card = container.querySelector(`[data-id=\"${entry.id}\"]`);\n    if (!card) return;\n    const providerEl = card.querySelector('[data-model-field=\"provider\"]');\n    const sourceEl = card.querySelector('[data-model-field=\"source\"]');\n    const toolChoiceEl = card.querySelector('[data-model-field=\"tool_choice\"]');\n    if (providerEl) providerEl.value = entry.provider;\n    if (sourceEl) sourceEl.value = entry.source;\n    if (toolChoiceEl) toolChoiceEl.value = entry.tool_choice || '';\n  });\n}\n\nfunction renderAllModelEditorSlots() {\n  ['shared', 'main', 'read', 'figure', 'compressor', 'thinking'].forEach(renderModelEditorSlot);\n}\n\nfunction loadModelEditorSettings(config) {\n  const globalBaseUrl = String(config?.base_url || '').trim();\n  const parsedSlots = {\n    main: Array.isArray(config?.models) ? config.models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n    read: Array.isArray(config?.read_figure_models) ? config.read_figure_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n    figure: Array.isArray(config?.figure_models) ? config.figure_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n    compressor: Array.isArray(config?.compressor_models) ? config.compressor_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n    thinking: Array.isArray(config?.thinking_models) ? config.thinking_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : []\n  };\n  const shared = computeSharedModelEntries(parsedSlots);\n  const sharedKeys = new Set(shared.map((entry) => serializeModelEditorComparable(entry)));\n  modelEditorState = {\n    shared,\n    main: parsedSlots.main.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n    read: parsedSlots.read.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n    figure: parsedSlots.figure.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n    compressor: parsedSlots.compressor.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n    thinking: parsedSlots.thinking.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry)\n  };\n  renderAllModelEditorSlots();\n}\n\nfunction addModelEditorEntry(slotKey) {\n  if (!modelEditorState[slotKey]) return;\n  modelEditorState[slotKey].push(makeBlankModelEditorEntry());\n  renderModelEditorSlot(slotKey);\n}\n\nfunction bindModelEditorList(slotKey) {\n  const container = document.getElementById(`model-${slotKey}-list`);\n  if (!container) return;\n  container.addEventListener('click', (event) => {\n    const button = event.target.closest('[data-model-action=\"delete\"]');\n    if (!button) return;\n    const card = button.closest('.model-entry-card');\n    if (!card) return;\n    const entryId = card.dataset.id;\n    modelEditorState[slotKey] = (modelEditorState[slotKey] || []).filter((entry) => entry.id !== entryId);\n    renderModelEditorSlot(slotKey);\n  });\n  container.addEventListener('input', (event) => {\n    const field = event.target?.dataset?.modelField;\n    if (!field) return;\n    const card = event.target.closest('.model-entry-card');\n    if (!card) return;\n    const entry = getModelEditorEntry(slotKey, card.dataset.id);\n    if (!entry) return;\n    entry[field] = event.target.value;\n    if (field === 'model' || field === 'base_url' || field === 'api_key') {\n      const preview = card.querySelector('.model-entry-preview code');\n      if (preview) preview.textContent = normalizeModelNameForProvider(entry.provider, entry.model) || '(empty)';\n    }\n  });\n  container.addEventListener('change', (event) => {\n    const field = event.target?.dataset?.modelField;\n    if (!field) return;\n    const card = event.target.closest('.model-entry-card');\n    if (!card) return;\n    const entry = getModelEditorEntry(slotKey, card.dataset.id);\n    if (!entry) return;\n    entry[field] = event.target.value;\n    if (field === 'source' || field === 'provider') {\n      renderModelEditorSlot(slotKey);\n    }\n  });\n}\n\n[\n  ['shared', 'add-shared-model-btn'],\n  ['main', 'add-main-model-btn'],\n  ['read', 'add-read-model-btn'],\n  ['figure', 'add-figure-model-btn'],\n  ['compressor', 'add-compressor-model-btn'],\n  ['thinking', 'add-thinking-model-btn']\n].forEach(([slotKey, buttonId]) => {\n  document.getElementById(buttonId)?.addEventListener('click', () => addModelEditorEntry(slotKey));\n  bindModelEditorList(slotKey);\n});\n\nfunction readPositiveNumber(value, fallback) {\n  const parsed = Number(value);\n  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nfunction readNonNegativeNumber(value, fallback) {\n  const parsed = Number(value);\n  return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;\n}\n\nfunction filterMarketItems(items, q) {\n  const query = String(q || '').trim().toLowerCase();\n  if (!query) return items;\n  return items.filter(it => {\n    const name = String(it?.name || '').toLowerCase();\n    const desc = String(it?.description || '').toLowerCase();\n    return name.includes(query) || desc.includes(query);\n  });\n}\n\nfunction renderMarketList() {\n  if (!marketList) return;\n  const q = marketSearch?.value || '';\n  const idx = marketIndexCache?.index || marketIndexCache;\n  if (!idx) {\n    marketList.innerHTML = '<div class=\"empty-state\">No data. Click refresh.</div>';\n    return;\n  }\n  const items = (marketActiveKind === 'skill') ? (idx.skills || []) : (idx.agent_systems || []);\n  const filtered = filterMarketItems(items, q);\n  if (filtered.length === 0) {\n    marketList.innerHTML = '<div class=\"empty-state\">No matches.</div>';\n    return;\n  }\n  marketList.innerHTML = filtered.map(it => `\n    <div class=\"skill-item\">\n      <div class=\"skill-info\">\n        <div class=\"skill-name\">${escapeHtml(it.name || '')}</div>\n        ${(() => {\n          const d = String(it.description || '');\n          const truncated = d.length > 120;\n          const safe = escapeHtml(d);\n          return `\n            <div class=\"skill-desc\">\n              <span class=\"desc-text ${truncated ? 'truncated' : ''}\">${safe}</span>\n              ${truncated ? '<span class=\"desc-toggle\" data-action=\"toggle\">More</span>' : ''}\n            </div>\n          `;\n        })()}\n      </div>\n      <button class=\"btn-secondary market-install-btn\" data-name=\"${escapeHtml(it.name || '')}\">Install</button>\n    </div>\n  `).join('');\n\n  marketList.querySelectorAll('.market-install-btn').forEach(btn => {\n    btn.addEventListener('click', async () => {\n      const name = btn.dataset.name;\n      await installFromMarket(marketActiveKind, name);\n    });\n  });\n\n  // Expand / collapse descriptions (event delegation)\n  marketList.querySelectorAll('.desc-toggle').forEach(t => {\n    t.addEventListener('click', () => {\n      const row = t.closest('.skill-item');\n      const text = row?.querySelector('.desc-text');\n      if (!text) return;\n      const isExpanded = text.classList.toggle('expanded');\n      if (isExpanded) {\n        text.classList.remove('truncated');\n        t.textContent = 'Less';\n      } else {\n        text.classList.add('truncated');\n        t.textContent = 'More';\n      }\n    });\n  });\n}\n\nasync function loadMarketIndex() {\n  setMarketStatus('Loading...', false);\n  const res = await window.api.marketGetIndex();\n  if (res?.error) {\n    marketIndexCache = null;\n    setMarketStatus(res.error, true);\n    renderMarketList();\n    return;\n  }\n  marketIndexCache = res;\n  setMarketStatus(`Loaded from ${res.base_url}`, false);\n  renderMarketList();\n}\n\nasync function installFromMarket(kind, name) {\n  setMarketStatus(`Installing ${name}...`, false);\n  const res1 = await window.api.marketInstall({ kind: kind === 'skill' ? 'skill' : 'agent_system', name });\n  if (res1?.conflict) {\n    const overwrite = confirm(`\"${name}\" already exists. Click OK to overwrite, Cancel to keep both.`);\n    const strategy = overwrite ? 'overwrite' : 'keep_both';\n    const res2 = await window.api.marketInstall({ kind: kind === 'skill' ? 'skill' : 'agent_system', name, strategy });\n    if (res2?.success) {\n      setMarketStatus(`Installed: ${res2.installed_name}`, false);\n      // refresh agent systems if installed\n      if (kind !== 'skill') await reloadAgentSystems();\n      return;\n    }\n    setMarketStatus(res2?.error || 'Install failed', true);\n    return;\n  }\n  if (res1?.success) {\n    setMarketStatus(`Installed: ${res1.installed_name}`, false);\n    if (kind !== 'skill') await reloadAgentSystems();\n    return;\n  }\n  setMarketStatus(res1?.error || 'Install failed', true);\n}\n\nif (marketBtn) {\n  marketBtn.addEventListener('click', async () => {\n    marketModal.style.display = 'flex';\n    marketActiveKind = 'skill';\n    await loadMarketIndex();\n  });\n}\nif (marketCloseBtn) {\n  marketCloseBtn.addEventListener('click', () => { marketModal.style.display = 'none'; });\n}\nif (marketModal) {\n  marketModal.addEventListener('click', (e) => {\n    if (e.target === marketModal) marketModal.style.display = 'none';\n  });\n}\nif (marketRefreshBtn) marketRefreshBtn.addEventListener('click', loadMarketIndex);\nif (marketSearch) marketSearch.addEventListener('input', renderMarketList);\nif (marketTabSkills) marketTabSkills.addEventListener('click', () => { marketActiveKind = 'skill'; renderMarketList(); });\nif (marketTabSystems) marketTabSystems.addEventListener('click', () => { marketActiveKind = 'agent_system'; renderMarketList(); });\n\n// ==================== Skills Modal ====================\n\nconst skillsModal = document.getElementById('skills-modal');\nconst skillsBtn = document.getElementById('skills-btn');\nconst skillsCloseBtn = document.getElementById('skills-close-btn');\nconst importSkillBtn = document.getElementById('import-skill-btn');\nconst refreshSkillsBtn = document.getElementById('refresh-skills-btn');\nconst skillsList = document.getElementById('skills-list');\n\n// Open skills modal\nskillsBtn.addEventListener('click', async () => {\n  skillsModal.style.display = 'flex';\n  await loadSkills();\n});\n\n// Close skills modal\nskillsCloseBtn.addEventListener('click', () => {\n  skillsModal.style.display = 'none';\n});\n\nskillsModal.addEventListener('click', (e) => {\n  if (e.target === skillsModal) skillsModal.style.display = 'none';\n});\n\n// Initial sidebar agent-system refresh on app startup, even before opening Settings.\nreloadAgentSystems().catch(() => {});\n\n// Import skill folder\nimportSkillBtn.addEventListener('click', async () => {\n  const result = await window.api.importSkillFolder();\n  if (result.canceled) return;\n  if (result.error) {\n    alert(`Import failed: ${result.error}`);\n    return;\n  }\n  await loadSkills();\n});\n\n// Refresh skills\nrefreshSkillsBtn.addEventListener('click', loadSkills);\n\nasync function loadSkills() {\n  const result = await window.api.getSkills();\n  if (result.error) {\n    skillsList.innerHTML = `<div class=\"empty-state\">Error: ${escapeHtml(result.error)}</div>`;\n    return;\n  }\n  \n  if (result.skills.length === 0) {\n    skillsList.innerHTML = '<div class=\"empty-state\">No skills imported yet. Click \"Import Skill Folder\" to add one.</div>';\n    return;\n  }\n  \n  skillsList.innerHTML = result.skills.map(skill => `\n    <div class=\"skill-item\">\n      <div class=\"skill-info\">\n        <div class=\"skill-name\">${escapeHtml(skill.name)}</div>\n        <div class=\"skill-desc\">${escapeHtml(skill.description || 'No description')}</div>\n        ${skill.hasSkillMd ? '<span class=\"skill-badge\">SKILL.md ✓</span>' : '<span class=\"skill-badge warn\">No SKILL.md</span>'}\n      </div>\n      <button class=\"skill-delete-btn\" data-skill=\"${escapeHtml(skill.name)}\" title=\"Delete\">✕</button>\n    </div>\n  `).join('');\n  \n  // Attach delete handlers\n  skillsList.querySelectorAll('.skill-delete-btn').forEach(btn => {\n    btn.addEventListener('click', async () => {\n      const name = btn.dataset.skill;\n      if (confirm(`Delete skill \"${name}\"?`)) {\n        await window.api.deleteSkill(name);\n        await loadSkills();\n      }\n    });\n  });\n}\n\n// ==================== Conversation History ====================\n\nconst conversationsContainer = document.getElementById('conversations');\nconst refreshConversationsBtn = document.getElementById('refresh-conversations-btn');\n\nrefreshConversationsBtn.addEventListener('click', loadConversations);\n\nasync function loadConversations() {\n  const result = await window.api.getConversations();\n  if (result.error) {\n    conversationsContainer.innerHTML = `<div class=\"empty-state\">Error loading</div>`;\n    return;\n  }\n  \n  if (result.conversations.length === 0) {\n    conversationsContainer.innerHTML = '<div class=\"empty-state\">No conversations yet</div>';\n    return;\n  }\n  \n  conversationsContainer.innerHTML = result.conversations.map(conv => {\n    const date = new Date(conv.lastUpdated);\n    const timeStr = formatRelativeTime(date);\n    \n    return `\n      <div class=\"conversation-item\" data-task-id=\"${escapeHtml(conv.taskId)}\" data-file=\"${escapeHtml(conv.file)}\" title=\"${escapeHtml(conv.taskId)}\">\n        <div class=\"conv-main\">\n          <div class=\"conv-workspace\">${escapeHtml(conv.workspaceName)}</div>\n          <div class=\"conv-preview\">${escapeHtml(conv.preview)}</div>\n        </div>\n        <div class=\"conv-meta\">\n          <span class=\"conv-time\">${timeStr}</span>\n          <span class=\"conv-turns\">${conv.turns || 0} turns</span>\n        </div>\n        <button class=\"conv-delete-btn\" data-file=\"${escapeHtml(conv.file)}\" title=\"Delete\">✕</button>\n      </div>\n    `;\n  }).join('');\n  \n  // Click to load workspace\n  conversationsContainer.querySelectorAll('.conversation-item').forEach(item => {\n    item.addEventListener('click', async (e) => {\n      // Don't trigger on delete button\n      if (e.target.closest('.conv-delete-btn')) return;\n      \n      const taskId = item.dataset.taskId;\n      const file = item.dataset.file;\n      if (taskId && !isRunning) {\n        workspacePath = taskId;\n        const folderName = taskId.split('/').pop() || taskId.split('\\\\').pop();\n        if (workspaceCurrent) {\n          workspaceCurrent.textContent = taskId;\n          workspaceCurrent.title = taskId;\n        }\n        userInput.disabled = false;\n        sendBtn.disabled = false;\n        statusText.textContent = `Workspace: ${folderName}`;\n        \n        const welcome = messagesContainer.querySelector('.welcome-message');\n        if (welcome) welcome.remove();\n\n        if (file) {\n          await loadConversationDetail(file);\n        }\n        await refreshResumeButton();\n        \n        // Highlight selected\n        conversationsContainer.querySelectorAll('.conversation-item').forEach(i => i.classList.remove('active'));\n        item.classList.add('active');\n      }\n    });\n  });\n  \n  // Delete handlers\n  conversationsContainer.querySelectorAll('.conv-delete-btn').forEach(btn => {\n    btn.addEventListener('click', async (e) => {\n      e.stopPropagation();\n      const fileName = btn.dataset.file;\n      if (confirm('Delete this conversation history?')) {\n        await window.api.deleteConversation(fileName);\n        await loadConversations();\n      }\n    });\n  });\n}\n\nfunction formatRelativeTime(date) {\n  const now = new Date();\n  const diffMs = now - date;\n  const diffMins = Math.floor(diffMs / 60000);\n  const diffHours = Math.floor(diffMs / 3600000);\n  const diffDays = Math.floor(diffMs / 86400000);\n  \n  if (diffMins < 1) return 'just now';\n  if (diffMins < 60) return `${diffMins}m ago`;\n  if (diffHours < 24) return `${diffHours}h ago`;\n  if (diffDays < 7) return `${diffDays}d ago`;\n  \n  return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\nasync function loadConversationDetail(fileName) {\n  const res = await window.api.getConversationDetail(fileName);\n  if (res?.error) {\n    addErrorMessage(`Failed to load conversation: ${res.error}`);\n    return;\n  }\n  const data = res?.data;\n  if (!data) return;\n\n  // Clear chat area and render share_context content\n  messagesContainer.innerHTML = '';\n  finalizeCurrentStream();\n  finalizeReasoningStream();\n  finalizeThinkingAgentStream();\n\n  renderShareContext(data);\n  scrollToBottom();\n}\n\nfunction renderShareContext(data) {\n  const turns = Array.isArray(data.history) ? data.history : [];\n  for (const turn of turns) {\n    const instructions = Array.isArray(turn?.instructions) ? turn.instructions : [];\n    for (const inst of instructions) {\n      if (inst?.instruction) addUserMessage(String(inst.instruction));\n    }\n\n    const agentsStatus = turn?.agents_status && typeof turn.agents_status === 'object' ? Object.values(turn.agents_status) : [];\n    const topLevel = agentsStatus.filter(a => a && a.final_output && (a.parent_id === null || a.parent_id === undefined) && (a.level === 0 || a.level === undefined));\n    const picked = topLevel.length > 0 ? topLevel : agentsStatus.filter(a => a && a.final_output);\n\n    for (const a of picked) {\n      addAgentMessage(String(a.agent_name || 'Agent'), String(a.final_output || ''));\n    }\n  }\n}\n\nfunction addAgentMessage(label, text) {\n  const wrapper = document.createElement('div');\n  wrapper.className = 'message-agent';\n\n  const bubble = document.createElement('div');\n  bubble.className = 'bubble';\n\n  const l = document.createElement('div');\n  l.className = 'agent-label';\n  l.textContent = label;\n\n  const content = document.createElement('div');\n  content.className = 'agent-content markdown';\n  setMarkdown(content, text);\n\n  bubble.appendChild(l);\n  bubble.appendChild(content);\n  wrapper.appendChild(bubble);\n  messagesContainer.appendChild(wrapper);\n}\n\n// ==================== Keyboard Shortcuts ====================\n\ndocument.addEventListener('keydown', (e) => {\n  // Escape to close modals\n  if (e.key === 'Escape') {\n    settingsModal.style.display = 'none';\n    skillsModal.style.display = 'none';\n  }\n  \n  // Cmd+, to open settings\n  if ((e.metaKey || e.ctrlKey) && e.key === ',') {\n    e.preventDefault();\n    settingsBtn.click();\n  }\n  \n  // Cmd+N for new chat\n  if ((e.metaKey || e.ctrlKey) && e.key === 'n') {\n    e.preventDefault();\n    newChatBtn.click();\n  }\n});\n\n// ==================== Init ====================\n\n// Load conversations on startup\nloadConversations();\n"
  },
  {
    "path": "desktop_app/src/styles.css",
    "content": "/* ==================== Warm Light Theme - Claude Desktop Style ==================== */\n\n* {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n}\n\n:root {\n  --bg-primary: #faf7f2;\n  --bg-secondary: #f5f0e8;\n  --bg-chat: #ffffff;\n  --bg-input: #f8f5ef;\n  --bg-message-user: #e8dfd3;\n  --bg-message-agent: #f9f6f1;\n  --bg-sidebar: #f0ebe3;\n  --bg-tool: #eef6ee;\n  --bg-thinking: #f0ecf8;\n  --text-primary: #2c2417;\n  --text-secondary: #6b5d4f;\n  --text-muted: #a09585;\n  --accent: #b5885a;\n  --accent-hover: #a07848;\n  --border: #e0d8cc;\n  --border-light: #ece6da;\n  --success: #5a9a6a;\n  --error: #c75450;\n  --warning: #c8943e;\n  --radius: 16px;\n  --radius-sm: 10px;\n  --shadow-sm: 0 1px 3px rgba(44,36,23,0.06);\n  --shadow-md: 0 4px 12px rgba(44,36,23,0.08);\n  --shadow-lg: 0 8px 32px rgba(44,36,23,0.12);\n}\n\nbody {\n  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, sans-serif;\n  background: var(--bg-primary);\n  color: var(--text-primary);\n  height: 100vh;\n  overflow: hidden;\n  -webkit-font-smoothing: antialiased;\n}\n\n/* Titlebar (macOS drag region) */\n.titlebar {\n  height: 38px;\n  -webkit-app-region: drag;\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  z-index: 100;\n  background: var(--bg-sidebar);\n}\n\n/* ==================== Layout ==================== */\n\n.app-container {\n  display: flex;\n  height: 100vh;\n  padding-top: 38px;\n}\n\n/* ==================== Sidebar ==================== */\n\n.sidebar {\n  width: 260px;\n  background: var(--bg-sidebar);\n  border-right: 1px solid var(--border);\n  display: flex;\n  flex-direction: column;\n  flex-shrink: 0;\n}\n\n.sidebar-header {\n  padding: 16px 20px;\n  border-bottom: 1px solid var(--border);\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n}\n\n.app-title {\n  font-size: 18px;\n  font-weight: 700;\n  color: var(--text-primary);\n  letter-spacing: -0.3px;\n}\n\n.new-chat-btn {\n  width: 30px;\n  height: 30px;\n  border-radius: 8px;\n  border: 1px solid var(--border);\n  background: var(--bg-chat);\n  color: var(--text-secondary);\n  font-size: 18px;\n  font-weight: 400;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  transition: all 0.15s;\n  -webkit-app-region: no-drag;\n}\n\n.new-chat-btn:hover {\n  border-color: var(--accent);\n  color: var(--accent);\n  box-shadow: var(--shadow-sm);\n}\n\n.workspace-section {\n  padding: 12px 16px;\n}\n\n.workspace-current {\n  margin-top: 8px;\n  padding: 6px 10px;\n  background: var(--bg-secondary);\n  border: 1px solid var(--border-light);\n  border-radius: 10px;\n  font-size: 11px;\n  color: var(--text-muted);\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n  word-break: break-all;\n  line-height: 1.35;\n}\n\n.workspace-btn {\n  width: 100%;\n  padding: 10px 14px;\n  background: var(--bg-chat);\n  border: 1px solid var(--border);\n  border-radius: var(--radius-sm);\n  color: var(--text-primary);\n  font-size: 13px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  transition: all 0.15s;\n  text-align: left;\n  box-shadow: var(--shadow-sm);\n}\n\n.workspace-btn:hover {\n  border-color: var(--accent);\n  box-shadow: var(--shadow-md);\n}\n\n.workspace-btn .icon {\n  font-size: 16px;\n}\n\n#workspace-label {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  flex: 1;\n}\n\n.sidebar-section {\n  padding: 8px 16px;\n}\n\n.section-label {\n  display: block;\n  font-size: 11px;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n  color: var(--text-muted);\n  margin-bottom: 6px;\n}\n\n.section-label-row {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  margin-bottom: 6px;\n}\n\n.section-label-row .section-label {\n  margin-bottom: 0;\n}\n\n.sidebar-icon-btn {\n  background: none;\n  border: none;\n  font-size: 16px;\n  color: var(--text-muted);\n  cursor: pointer;\n  padding: 2px 4px;\n  border-radius: 4px;\n  transition: all 0.15s;\n}\n\n.sidebar-icon-btn:hover {\n  color: var(--text-secondary);\n  background: var(--border-light);\n}\n\n.sidebar-select {\n  width: 100%;\n  padding: 8px 10px;\n  background: var(--bg-chat);\n  border: 1px solid var(--border);\n  border-radius: var(--radius-sm);\n  color: var(--text-primary);\n  font-size: 13px;\n  cursor: pointer;\n  outline: none;\n}\n\n.sidebar-select:focus {\n  border-color: var(--accent);\n}\n\n.conversations-list {\n  flex: 1;\n  overflow: hidden;\n  display: flex;\n  flex-direction: column;\n}\n\n.conversations-scroll {\n  flex: 1;\n  overflow-y: auto;\n  padding: 4px 0;\n}\n\n.empty-state {\n  padding: 20px 16px;\n  color: var(--text-muted);\n  font-size: 13px;\n  text-align: center;\n}\n\n.sidebar-footer {\n  padding: 12px 16px;\n  border-top: 1px solid var(--border);\n  display: flex;\n  gap: 8px;\n}\n\n.sidebar-btn-text {\n  flex: 1;\n  padding: 8px 10px;\n  border-radius: 8px;\n  border: 1px solid var(--border);\n  background: var(--bg-chat);\n  color: var(--text-secondary);\n  font-size: 12px;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.15s;\n}\n\n.sidebar-btn-text:hover {\n  border-color: var(--accent);\n  color: var(--accent);\n  box-shadow: var(--shadow-sm);\n}\n\n.sidebar-btn-icon {\n  background: none;\n  border: none;\n  font-size: 20px;\n  cursor: pointer;\n  padding: 4px;\n  border-radius: 6px;\n  transition: background 0.15s;\n}\n\n.sidebar-btn-icon:hover {\n  background: var(--border-light);\n}\n\n/* ==================== Conversation Items ==================== */\n\n.conversation-item {\n  padding: 10px 16px;\n  cursor: pointer;\n  border-bottom: 1px solid var(--border-light);\n  transition: background 0.1s;\n  position: relative;\n}\n\n.conversation-item:hover {\n  background: var(--bg-secondary);\n}\n\n.conversation-item.active {\n  background: var(--bg-message-user);\n}\n\n.conv-main {\n  margin-bottom: 4px;\n}\n\n.conv-workspace {\n  font-size: 13px;\n  font-weight: 600;\n  color: var(--text-primary);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  margin-bottom: 2px;\n}\n\n.conv-preview {\n  font-size: 12px;\n  color: var(--text-muted);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  line-height: 1.4;\n}\n\n.conv-meta {\n  display: flex;\n  gap: 8px;\n  align-items: center;\n}\n\n.conv-time, .conv-turns {\n  font-size: 11px;\n  color: var(--text-muted);\n}\n\n.conv-delete-btn {\n  position: absolute;\n  top: 8px;\n  right: 8px;\n  background: none;\n  border: none;\n  color: var(--text-muted);\n  font-size: 12px;\n  cursor: pointer;\n  padding: 2px 5px;\n  border-radius: 4px;\n  opacity: 0;\n  transition: all 0.15s;\n}\n\n.conversation-item:hover .conv-delete-btn {\n  opacity: 1;\n}\n\n.conv-delete-btn:hover {\n  background: var(--error);\n  color: white;\n}\n\n/* ==================== Chat Area ==================== */\n\n.chat-area {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  background: var(--bg-chat);\n  min-width: 0;\n  min-height: 0;\n}\n\n.messages-container {\n  flex: 1;\n  overflow-y: auto;\n  padding: 20px 0;\n  scroll-behavior: auto;\n  min-height: 0;\n  overscroll-behavior: contain;\n}\n\n/* Welcome message */\n.welcome-message {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  padding: 40px;\n  text-align: center;\n}\n\n.welcome-message h2 {\n  font-size: 26px;\n  font-weight: 700;\n  margin-bottom: 12px;\n  color: var(--text-primary);\n}\n\n.welcome-message p {\n  font-size: 15px;\n  color: var(--text-secondary);\n  margin-bottom: 32px;\n  max-width: 400px;\n}\n\n.feature-cards {\n  display: flex;\n  gap: 14px;\n  flex-wrap: wrap;\n  justify-content: center;\n}\n\n.feature-card {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 12px 18px;\n  background: var(--bg-secondary);\n  border: 1px solid var(--border-light);\n  border-radius: var(--radius);\n  font-size: 13px;\n  color: var(--text-secondary);\n  box-shadow: var(--shadow-sm);\n}\n\n.feature-icon {\n  font-size: 18px;\n}\n\n/* ==================== Messages ==================== */\n\n.message {\n  padding: 6px 24px;\n  max-width: 800px;\n  margin: 0 auto;\n  width: 100%;\n}\n\n/* User message - right aligned bubble */\n.message-user {\n  display: flex;\n  justify-content: flex-end;\n  padding: 8px 24px;\n}\n\n.message-user .bubble {\n  background: var(--bg-message-user);\n  padding: 12px 16px;\n  border-radius: 18px 18px 4px 18px;\n  max-width: 75%;\n  font-size: 14.5px;\n  line-height: 1.55;\n  box-shadow: var(--shadow-sm);\n}\n\n/* Agent message - left aligned bubble */\n.message-agent {\n  display: flex;\n  justify-content: flex-start;\n  padding: 8px 24px;\n}\n\n.message-agent .bubble {\n  background: var(--bg-message-agent);\n  border: 1px solid var(--border-light);\n  padding: 14px 18px;\n  border-radius: 4px 18px 18px 18px;\n  max-width: 85%;\n  font-size: 14.5px;\n  line-height: 1.65;\n  box-shadow: var(--shadow-sm);\n}\n\n.message-agent .bubble .agent-label {\n  font-size: 11px;\n  font-weight: 600;\n  color: var(--accent);\n  margin-bottom: 6px;\n  text-transform: uppercase;\n  letter-spacing: 0.3px;\n}\n\n.message-agent .bubble .agent-content {\n  white-space: pre-wrap;\n  word-break: break-word;\n}\n\n.message-agent .bubble .agent-content.markdown {\n  white-space: normal;\n}\n\n.message-agent .bubble .agent-content.markdown pre {\n  background: rgba(255, 255, 255, 0.65);\n  border: 1px solid var(--border-light);\n  border-radius: 10px;\n  padding: 10px 12px;\n  overflow-x: auto;\n  margin: 10px 0;\n}\n\n.message-agent .bubble .agent-content.markdown code {\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n  font-size: 0.92em;\n  background: rgba(255, 255, 255, 0.65);\n  border: 1px solid var(--border-light);\n  border-radius: 6px;\n  padding: 1px 6px;\n}\n\n.message-agent .bubble .agent-content.markdown pre code {\n  background: transparent;\n  border: none;\n  padding: 0;\n}\n\n.message-agent .bubble .agent-content.markdown a {\n  color: var(--accent);\n  text-decoration: none;\n  border-bottom: 1px solid rgba(181, 136, 90, 0.35);\n}\n\n.message-agent .bubble .agent-content.markdown a:hover {\n  border-bottom-color: rgba(181, 136, 90, 0.8);\n}\n\n.message-agent .bubble .agent-content.markdown ul,\n.message-agent .bubble .agent-content.markdown ol {\n  padding-left: 20px;\n  margin: 8px 0;\n}\n\n.message-agent .bubble .agent-content.markdown li {\n  margin: 4px 0;\n}\n\n.message-agent .bubble .agent-content.markdown h1,\n.message-agent .bubble .agent-content.markdown h2,\n.message-agent .bubble .agent-content.markdown h3 {\n  margin: 14px 0 8px;\n  line-height: 1.25;\n}\n\n.message-agent .bubble .agent-content.markdown blockquote {\n  border-left: 3px solid var(--border);\n  padding-left: 12px;\n  color: var(--text-secondary);\n  margin: 10px 0;\n}\n\n/* Tool message - bordered card */\n.message-tool {\n  padding: 4px 24px;\n  max-width: 800px;\n  margin: 0 auto;\n  width: 100%;\n}\n\n.tool-card {\n  display: flex;\n  flex-direction: column;\n  gap: 0;\n  padding: 0;\n  background: var(--bg-tool);\n  border: 1.5px solid #c5ddc5;\n  border-radius: var(--radius-sm);\n  font-size: 13px;\n  box-shadow: var(--shadow-sm);\n  transition: border-color 0.3s;\n  overflow: hidden;\n}\n\n.tool-card.tool-success {\n  border-color: #a8d4a8;\n}\n\n.tool-card.tool-error {\n  border-color: #e8b4b4;\n  background: #fef8f8;\n}\n\n.tool-card.tool-running {\n  border-color: #dcc88e;\n  background: #fefcf4;\n}\n\n.tool-dot {\n  width: 8px;\n  height: 8px;\n  border-radius: 50%;\n  flex-shrink: 0;\n}\n\n.tool-dot-running { background: var(--warning); animation: pulse 1.5s infinite; }\n.tool-dot-success { background: var(--success); }\n.tool-dot-error { background: var(--error); }\n\n@keyframes pulse {\n  0%, 100% { opacity: 1; }\n  50% { opacity: 0.4; }\n}\n\n.tool-name {\n  color: var(--text-primary);\n  font-weight: 600;\n  font-size: 13px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n}\n\n.tool-header {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  padding: 10px 14px;\n}\n\n.tool-status-label {\n  margin-left: auto;\n  font-size: 11px;\n  color: var(--text-muted);\n  font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n.tool-details {\n  border-top: 1px solid var(--border-light);\n  padding: 6px 14px 8px;\n}\n\n.tool-params-toggle {\n  cursor: pointer;\n  font-size: 11px;\n  font-weight: 500;\n  color: var(--text-muted);\n  font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n  user-select: none;\n}\n\n.tool-params-toggle:hover {\n  color: var(--text-secondary);\n}\n\n.tool-params-content {\n  margin-top: 6px;\n  padding: 8px 10px;\n  background: rgba(255,255,255,0.6);\n  border-radius: 6px;\n  font-size: 11px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n  color: var(--text-secondary);\n  line-height: 1.5;\n  overflow-x: auto;\n  white-space: pre-wrap;\n  word-break: break-word;\n  max-height: 200px;\n  overflow-y: auto;\n}\n\n.tool-result-area {\n  padding: 0 0 10px 0;\n}\n\n/* Human-in-loop inline UI */\n.hil-card {\n  margin-top: 10px;\n  padding: 10px 12px;\n  border: 1px solid rgba(0,0,0,0.10);\n  border-radius: 12px;\n  background: rgba(255, 255, 255, 0.7);\n}\n.hil-title {\n  font-weight: 650;\n  font-size: 13px;\n  color: #3c3a36;\n  margin-bottom: 6px;\n}\n.hil-instruction {\n  font-size: 13px;\n  color: #3c3a36;\n  white-space: pre-wrap;\n  line-height: 1.4;\n  margin-bottom: 10px;\n}\n.hil-actions {\n  display: flex;\n  gap: 10px;\n  align-items: flex-end;\n}\n.hil-input {\n  flex: 1;\n  width: 100%;\n  resize: vertical;\n  padding: 8px 10px;\n  border-radius: 10px;\n  border: 1px solid rgba(0,0,0,0.12);\n  background: #fff;\n  font-size: 13px;\n  line-height: 1.35;\n}\n.hil-send {\n  height: 34px;\n}\n.hil-meta {\n  margin-top: 8px;\n  font-size: 12px;\n  color: rgba(60,58,54,0.7);\n}\n.hil-meta code {\n  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  font-size: 12px;\n}\n\n/* Thinking message - subtle purple card */\n.message-thinking {\n  padding: 4px 24px;\n  max-width: 800px;\n  margin: 0 auto;\n  width: 100%;\n}\n\n.thinking-card {\n  background: var(--bg-thinking);\n  border: 1px solid #ddd6ee;\n  border-radius: var(--radius-sm);\n  padding: 10px 14px;\n  font-size: 13px;\n  color: var(--text-secondary);\n  box-shadow: var(--shadow-sm);\n}\n\n.thinking-card summary {\n  cursor: pointer;\n  font-weight: 600;\n  font-size: 12px;\n  color: #7c6aa0;\n  letter-spacing: 0.3px;\n}\n\n.thinking-card .thinking-content {\n  margin-top: 8px;\n  white-space: pre-wrap;\n  word-break: break-word;\n  line-height: 1.55;\n  max-height: 300px;\n  overflow-y: auto;\n}\n\n/* System message - centered, muted */\n.message-system {\n  text-align: center;\n  padding: 6px 24px;\n  font-size: 12px;\n  color: var(--text-muted);\n}\n\n/* Error message */\n.message-error {\n  padding: 6px 24px;\n  max-width: 800px;\n  margin: 0 auto;\n}\n\n.error-card {\n  background: #fef2f2;\n  border: 1px solid #fecaca;\n  border-radius: var(--radius-sm);\n  padding: 10px 14px;\n  font-size: 13px;\n  color: var(--error);\n}\n\n/* Loading animation */\n.typing-indicator {\n  display: flex;\n  gap: 5px;\n  padding: 10px 24px;\n  max-width: 800px;\n  margin: 0 auto;\n  align-items: center;\n}\n\n.typing-dot {\n  width: 7px;\n  height: 7px;\n  border-radius: 50%;\n  background: var(--text-muted);\n  animation: typing 1.4s infinite;\n}\n\n.typing-dot:nth-child(2) { animation-delay: 0.2s; }\n.typing-dot:nth-child(3) { animation-delay: 0.4s; }\n\n@keyframes typing {\n  0%, 60%, 100% { opacity: 0.3; transform: scale(1); }\n  30% { opacity: 1; transform: scale(1.2); }\n}\n\n/* ==================== Input Area ==================== */\n\n.input-area {\n  padding: 12px 24px 20px;\n  max-width: 800px;\n  margin: 0 auto;\n  width: 100%;\n}\n\n.input-wrapper {\n  display: flex;\n  align-items: flex-end;\n  gap: 8px;\n  background: var(--bg-input);\n  border: 1.5px solid var(--border);\n  border-radius: 22px;\n  padding: 8px 16px;\n  transition: border-color 0.15s, box-shadow 0.15s;\n  box-shadow: var(--shadow-sm);\n}\n\n.input-wrapper:focus-within {\n  border-color: var(--accent);\n  box-shadow: 0 0 0 3px rgba(181,136,90,0.12);\n}\n\n#user-input {\n  flex: 1;\n  background: none;\n  border: none;\n  color: var(--text-primary);\n  font-size: 14.5px;\n  font-family: inherit;\n  resize: none;\n  outline: none;\n  max-height: 200px;\n  line-height: 1.5;\n  padding: 4px 0;\n}\n\n#user-input::placeholder {\n  color: var(--text-muted);\n}\n\n#user-input:disabled {\n  opacity: 0.5;\n}\n\n.send-btn, .stop-btn {\n  width: 34px;\n  height: 34px;\n  border-radius: 50%;\n  border: none;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-size: 16px;\n  font-weight: 700;\n  transition: all 0.15s;\n  flex-shrink: 0;\n}\n\n.send-btn {\n  background: var(--accent);\n  color: white;\n}\n\n.send-btn:hover:not(:disabled) {\n  background: var(--accent-hover);\n  transform: scale(1.05);\n}\n\n.send-btn:disabled {\n  opacity: 0.3;\n  cursor: not-allowed;\n}\n\n.stop-btn {\n  background: var(--error);\n  color: white;\n}\n\n.stop-btn:hover {\n  opacity: 0.85;\n}\n\n.input-footer {\n  padding: 6px 8px 0;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 10px;\n}\n\n.status-text {\n  font-size: 12px;\n  color: var(--text-muted);\n}\n\n.auto-scroll-btn {\n  padding: 6px 10px;\n  border-radius: 10px;\n  border: 1px solid var(--border);\n  background: var(--bg-secondary);\n  color: var(--text-secondary);\n  font-size: 12px;\n  font-weight: 700;\n  cursor: pointer;\n  transition: all 0.15s;\n}\n\n.auto-scroll-btn:hover {\n  border-color: var(--accent);\n  color: var(--accent);\n  box-shadow: var(--shadow-sm);\n}\n\n.auto-scroll-btn.off {\n  background: #f7efe4;\n  color: var(--text-muted);\n  border-color: var(--border-light);\n}\n\n.resume-btn {\n  padding: 6px 10px;\n  border-radius: 10px;\n  border: 1px solid var(--border);\n  background: var(--bg-secondary);\n  color: var(--text-secondary);\n  font-size: 12px;\n  font-weight: 700;\n  cursor: pointer;\n  transition: all 0.15s;\n}\n\n.resume-btn:hover:not(:disabled) {\n  border-color: var(--accent);\n  color: var(--accent);\n  box-shadow: var(--shadow-sm);\n}\n\n.resume-btn:disabled {\n  opacity: 0.4;\n  cursor: not-allowed;\n}\n\n/* ==================== Modal Overlay ==================== */\n\n.modal-overlay {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(44, 36, 23, 0.4);\n  backdrop-filter: blur(4px);\n  z-index: 1000;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  animation: fadeIn 0.15s ease;\n}\n\n@keyframes fadeIn {\n  from { opacity: 0; }\n  to { opacity: 1; }\n}\n\n.modal-container {\n  background: var(--bg-chat);\n  border-radius: 16px;\n  width: 560px;\n  max-width: 90vw;\n  max-height: 85vh;\n  display: flex;\n  flex-direction: column;\n  box-shadow: var(--shadow-lg);\n  animation: slideUp 0.2s ease;\n  overflow: hidden;\n}\n\n@keyframes slideUp {\n  from { transform: translateY(20px); opacity: 0; }\n  to { transform: translateY(0); opacity: 1; }\n}\n\n.modal-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 20px 24px 12px;\n}\n\n.modal-title {\n  font-size: 18px;\n  font-weight: 700;\n  color: var(--text-primary);\n}\n\n.modal-close-btn {\n  background: none;\n  border: none;\n  font-size: 18px;\n  color: var(--text-muted);\n  cursor: pointer;\n  padding: 4px 8px;\n  border-radius: 6px;\n  transition: all 0.15s;\n}\n\n.modal-close-btn:hover {\n  background: var(--bg-secondary);\n  color: var(--text-primary);\n}\n\n/* Tabs */\n.modal-tabs {\n  display: flex;\n  gap: 2px;\n  padding: 0 24px;\n  border-bottom: 1px solid var(--border-light);\n}\n\n.modal-tab {\n  background: none;\n  border: none;\n  padding: 10px 16px;\n  font-size: 13px;\n  font-weight: 500;\n  color: var(--text-muted);\n  cursor: pointer;\n  border-bottom: 2px solid transparent;\n  transition: all 0.15s;\n  margin-bottom: -1px;\n}\n\n.modal-tab:hover {\n  color: var(--text-secondary);\n}\n\n.modal-tab.active {\n  color: var(--accent);\n  border-bottom-color: var(--accent);\n}\n\n.modal-body {\n  flex: 1;\n  overflow-y: auto;\n  padding: 20px 24px;\n}\n\n.tab-content {\n  display: none;\n}\n\n.tab-content.active {\n  display: block;\n}\n\n.modal-footer {\n  padding: 16px 24px;\n  border-top: 1px solid var(--border-light);\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 12px;\n}\n\n.modal-description {\n  font-size: 13px;\n  color: var(--text-secondary);\n  margin-bottom: 16px;\n  line-height: 1.5;\n}\n\n.modal-description code {\n  background: var(--bg-secondary);\n  padding: 2px 6px;\n  border-radius: 4px;\n  font-size: 12px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n}\n\n/* ==================== Form Elements ==================== */\n\n.form-group {\n  margin-bottom: 16px;\n}\n\n.form-label {\n  display: block;\n  font-size: 13px;\n  font-weight: 600;\n  color: var(--text-primary);\n  margin-bottom: 6px;\n}\n\n.form-hint {\n  font-weight: 400;\n  color: var(--text-muted);\n  font-size: 11px;\n}\n\n.form-hint-block {\n  margin-top: 8px;\n  font-size: 12px;\n  color: var(--text-muted);\n  line-height: 1.5;\n}\n\n.form-hint-block code {\n  background: var(--bg-secondary);\n  padding: 1px 5px;\n  border-radius: 3px;\n  font-size: 11px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n}\n\n.form-input {\n  width: 100%;\n  padding: 9px 12px;\n  background: var(--bg-input);\n  border: 1px solid var(--border);\n  border-radius: 8px;\n  color: var(--text-primary);\n  font-size: 13px;\n  font-family: inherit;\n  outline: none;\n  transition: border-color 0.15s;\n}\n\n.form-input:focus {\n  border-color: var(--accent);\n}\n\n.form-textarea {\n  width: 100%;\n  padding: 9px 12px;\n  background: var(--bg-input);\n  border: 1px solid var(--border);\n  border-radius: 8px;\n  color: var(--text-primary);\n  font-size: 13px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n  outline: none;\n  resize: vertical;\n  line-height: 1.5;\n  transition: border-color 0.15s;\n}\n\n.form-textarea:focus {\n  border-color: var(--accent);\n}\n\n.form-row {\n  display: flex;\n  gap: 12px;\n}\n\n.model-slot-toolbar {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  margin-bottom: 12px;\n  flex-wrap: wrap;\n}\n\n.model-slot-list {\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n}\n\n.model-slot-empty {\n  padding: 12px 14px;\n  border: 1px dashed var(--border);\n  border-radius: 10px;\n  color: var(--text-muted);\n  font-size: 12px;\n  background: var(--bg-secondary);\n}\n\n.model-entry-card {\n  border: 1px solid var(--border);\n  border-radius: 12px;\n  background: var(--bg-secondary);\n  padding: 14px;\n  box-shadow: var(--shadow-sm);\n}\n\n.model-entry-topbar {\n  display: flex;\n  gap: 10px;\n  align-items: center;\n  margin-bottom: 10px;\n  flex-wrap: wrap;\n}\n\n.model-entry-topbar .form-group {\n  margin-bottom: 0;\n  min-width: 150px;\n}\n\n.model-entry-actions {\n  margin-left: auto;\n}\n\n.model-entry-preview {\n  margin-top: 6px;\n  font-size: 11px;\n  color: var(--text-muted);\n  line-height: 1.45;\n}\n\n.model-entry-preview code {\n  background: rgba(255, 255, 255, 0.75);\n  border: 1px solid var(--border-light);\n  border-radius: 5px;\n  padding: 1px 5px;\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n}\n\n.model-entry-custom-source {\n  margin-top: 10px;\n}\n\n.form-half {\n  flex: 1;\n}\n\n.form-divider {\n  height: 1px;\n  background: var(--border-light);\n  margin: 20px 0;\n}\n\n.password-wrapper {\n  position: relative;\n  display: flex;\n  align-items: center;\n}\n\n.password-wrapper .form-input {\n  padding-right: 40px;\n}\n\n.toggle-password-btn {\n  position: absolute;\n  right: 8px;\n  background: none;\n  border: none;\n  font-size: 16px;\n  cursor: pointer;\n  padding: 4px;\n  opacity: 0.5;\n  transition: opacity 0.15s;\n}\n\n.toggle-password-btn:hover {\n  opacity: 1;\n}\n\n.config-path {\n  font-size: 12px;\n  color: var(--text-muted);\n  font-family: 'SF Mono', 'Fira Code', 'Menlo', monospace;\n  word-break: break-all;\n  background: var(--bg-secondary);\n  padding: 8px 10px;\n  border-radius: 6px;\n}\n\n/* Buttons */\n.btn-primary {\n  padding: 9px 20px;\n  background: var(--accent);\n  color: white;\n  border: none;\n  border-radius: 8px;\n  font-size: 13px;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.15s;\n  display: flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.btn-primary:hover {\n  background: var(--accent-hover);\n  box-shadow: var(--shadow-sm);\n}\n\n.btn-secondary {\n  padding: 9px 14px;\n  background: var(--bg-secondary);\n  color: var(--text-secondary);\n  border: 1px solid var(--border);\n  border-radius: 8px;\n  font-size: 12px;\n  font-weight: 700;\n  cursor: pointer;\n  transition: all 0.15s;\n}\n\n.btn-secondary:hover {\n  border-color: var(--accent);\n  color: var(--accent);\n  box-shadow: var(--shadow-sm);\n}\n\n.settings-status {\n  font-size: 12px;\n  color: var(--text-muted);\n}\n\n/* ==================== Skills List ==================== */\n\n.skills-toolbar {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin-bottom: 16px;\n}\n\n.skills-list {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n}\n\n.skill-item {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 12px 14px;\n  background: var(--bg-secondary);\n  border: 1px solid var(--border-light);\n  border-radius: var(--radius-sm);\n  transition: box-shadow 0.15s;\n}\n\n.skill-item:hover {\n  box-shadow: var(--shadow-sm);\n}\n\n.skill-info {\n  flex: 1;\n  min-width: 0;\n}\n\n.skill-name {\n  font-size: 14px;\n  font-weight: 600;\n  color: var(--text-primary);\n  margin-bottom: 2px;\n}\n\n.skill-desc {\n  display: flex;\n  align-items: baseline;\n  gap: 6px;\n  margin-bottom: 4px;\n}\n\n.desc-text {\n  flex: 1;\n  min-width: 0;\n  font-size: 12px;\n  color: var(--text-muted);\n}\n\n.desc-text.truncated {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.desc-text.expanded {\n  white-space: normal;\n  overflow: visible;\n  text-overflow: clip;\n}\n\n.desc-toggle {\n  display: inline-block;\n  font-size: 11px;\n  color: var(--accent);\n  cursor: pointer;\n  user-select: none;\n  margin-left: 6px;\n}\n\n.desc-toggle:hover {\n  color: var(--accent-hover);\n}\n\n.skill-badge {\n  display: inline-block;\n  font-size: 10px;\n  font-weight: 600;\n  color: var(--success);\n  background: rgba(90, 154, 106, 0.1);\n  padding: 2px 6px;\n  border-radius: 4px;\n}\n\n.skill-badge.warn {\n  color: var(--warning);\n  background: rgba(200, 148, 62, 0.1);\n}\n\n.skill-delete-btn {\n  background: none;\n  border: none;\n  color: var(--text-muted);\n  font-size: 14px;\n  cursor: pointer;\n  padding: 4px 8px;\n  border-radius: 4px;\n  transition: all 0.15s;\n  flex-shrink: 0;\n}\n\n.skill-delete-btn:hover {\n  background: var(--error);\n  color: white;\n}\n\n/* ==================== Scrollbar ==================== */\n\n::-webkit-scrollbar {\n  width: 5px;\n}\n\n::-webkit-scrollbar-track {\n  background: transparent;\n}\n\n::-webkit-scrollbar-thumb {\n  background: var(--border);\n  border-radius: 3px;\n}\n\n::-webkit-scrollbar-thumb:hover {\n  background: var(--text-muted);\n}\n"
  },
  {
    "path": "desktop_app/src/test_e.js",
    "content": "const electron = require('electron');\nconsole.log('type:', typeof electron);\nconsole.log('app type:', typeof electron.app);\nif (typeof electron === 'string') {\n  console.log('electron is a string (path):', electron);\n} else {\n  console.log('keys:', Object.keys(electron).slice(0, 10));\n}\nprocess.exit(0);\n"
  },
  {
    "path": "docker/entrypoint.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nAPP_ROOT=\"/app\"\nDEFAULT_WORKSPACE=\"/workspace\"\n\nmkdir -p /root/mla_v3\n\nif [[ -n \"${HOST_PWD:-}\" && -d \"/workspace${HOST_PWD}\" ]]; then\n  export WORKSPACE_ROOT=\"${WORKSPACE_ROOT:-/workspace${HOST_PWD}}\"\nelif [[ -d \"${DEFAULT_WORKSPACE}\" ]]; then\n  export WORKSPACE_ROOT=\"${WORKSPACE_ROOT:-${DEFAULT_WORKSPACE}}\"\nelse\n  mkdir -p \"${DEFAULT_WORKSPACE}\"\n  export WORKSPACE_ROOT=\"${WORKSPACE_ROOT:-${DEFAULT_WORKSPACE}}\"\nfi\n\nexport MLA_USER_DATA_ROOT=\"${MLA_USER_DATA_ROOT:-/root/mla_v3}\"\nexport WEB_UI_USERS_FILE=\"${WEB_UI_USERS_FILE:-/root/mla_v3/web_ui_users.yaml}\"\nexport WEB_UI_USER_DATA_ROOT=\"${WEB_UI_USER_DATA_ROOT:-/root/mla_v3/web_users}\"\nexport PORT=\"${PORT:-4242}\"\n\ncd \"${APP_ROOT}\"\n\nmode=\"${1:-webui}\"\nshift || true\n\ncase \"${mode}\" in\n  webui)\n    echo \"[docker] starting webui on 0.0.0.0:${PORT}\"\n    echo \"[docker] workspace root: ${WORKSPACE_ROOT}\"\n    exec python web_ui/server/server.py \"$@\"\n    ;;\n  cli)\n    echo \"[docker] starting cli in workspace: ${WORKSPACE_ROOT}\"\n    cd \"${WORKSPACE_ROOT}\"\n    exec python /app/start.py --cli \"$@\"\n    ;;\n  bash|sh)\n    exec \"${mode}\" \"$@\"\n    ;;\n  *)\n    exec \"${mode}\" \"$@\"\n    ;;\nesac\n"
  },
  {
    "path": "docs/CHEAPCLAW_GUIDE.md",
    "content": "# CheapClaw Guide\n\n适用实现：\n- 服务入口：[apps/cheapclaw/cheapclaw_service.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/apps/cheapclaw/cheapclaw_service.py)\n- 面板辅助：[apps/cheapclaw/tool_runtime_helpers.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/apps/cheapclaw/tool_runtime_helpers.py)\n- Supervisor 提示词：[apps/cheapclaw/assets/agent_library/CheapClawSupervisor/general_prompts.yaml](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/apps/cheapclaw/assets/agent_library/CheapClawSupervisor/general_prompts.yaml)\n- Worker 提示词：[apps/cheapclaw/assets/agent_library/CheapClawWorkerGeneral/general_prompts.yaml](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/apps/cheapclaw/assets/agent_library/CheapClawWorkerGeneral/general_prompts.yaml)\n\n## 1. 定位\n\nCheapClaw 是基于 `infiagent` SDK 的独立应用层。\n\n职责边界：\n- CheapClaw 负责：社交消息入口、消息面板、消息与 task 绑定、主调度 agent、watchdog、计划任务、outbox 发送\n- MLA/InfiAgent 负责：task runtime、agent system 装载、tool 调用、share/stack/history 持久化、fresh/resume/add_message\n\n这意味着：\n- CheapClaw 不需要嵌进框架内核\n- CheapClaw 可以单独复制到另一个项目中使用\n- 框架只需要暴露 SDK 和动态 `tools_dir`\n\n## 2. 目录和状态\n\nCheapClaw 运行在 `<user_data_root>/cheapclaw` 下，核心文件：\n\n- `panel/panel.json`\n- `panel/backups/*.json`\n- `plans.json`\n- `channels/<channel>/<conversation>/social_history.jsonl`\n- `outbox/*.json`\n- `task_skills/<task_slug>/...`\n- `runtime/state.json`\n- `tasks/<channel>/<conversation>/<task_slug>/...`\n\n`panel.json` 是调度单一事实来源。conversation 记录至少包含：\n- 渠道\n- 联系人/群\n- 最近消息摘要\n- pending_events\n- linked_tasks\n- `message_task_bindings`\n- `message_history_path`\n- `share_context_path`\n- `stack_path`\n- `log_path`\n- 最新 `thinking / final_output`\n- watchdog 观测结果\n\n## 3. 主 agent 决策语义\n\nSupervisor 不自己做业务任务，只做路由和派工。\n\n处理 dirty conversation 时必须按顺序判断：\n1. 这次触发来自哪里：新消息、plan_tick、watchdog_tick、task_completed、系统状态变更\n2. 是否可直接回复，无需 worker\n3. 如果需要 worker，属于哪一类：\n   - `append_to_running_task`\n   - `continue_existing_task`\n   - `fork_new_task`\n   - `brand_new_task`\n4. 把这次触发的 `message_id` 绑定到选定的 `task_id`\n5. 发送用户回执\n6. 更新面板，清理对应 dirty / pending_events\n\n一个 `task_id` 可以绑定多条用户消息。\n这表示“同一个工作在持续演进”，而不是每来一句话都要起新 task。\n\n## 4. CheapClaw 自定义工具\n\nSupervisor/Worker 通过动态 `tools_library` 使用 CheapClaw 工具，主要包括：\n- `cheapclaw_read_panel`\n- `cheapclaw_update_panel`\n- `cheapclaw_read_social_history`\n- `cheapclaw_send_message`\n- `cheapclaw_send_file`\n- `cheapclaw_start_task`\n- `cheapclaw_add_task_message`\n- `cheapclaw_get_task_status`\n- `cheapclaw_list_agent_systems`\n- `cheapclaw_schedule_plan`\n- `cheapclaw_cancel_plan`\n- `cheapclaw_reset_task`\n- `cheapclaw_generate_task_id`\n- `cheapclaw_list_conversation_tasks`\n- `cheapclaw_list_global_skills`\n- `cheapclaw_reveal_skills`\n\n这些工具不再写进框架源码，也不靠 `template_assets.py` 生成。\n它们就是真实存在的 Python 文件，位于：\n- [apps/cheapclaw/tools_library](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/apps/cheapclaw/tools_library)\n\n## 5. skills overlay 机制\n\nCheapClaw 支持“主技能库 + task overlay skills”。\n\n规则：\n- 全局主技能库仍默认来自 SDK runtime 的 `skills_dir`\n- Supervisor 可以用 `cheapclaw_reveal_skills` 把某些 skills 暴露给某个 task\n- 每个 task 的 overlay skills 存在 `task_skills/<task_slug>/`\n- Worker 只默认看到 overlay 中允许的 skills\n- 如果 worker 发现技能不够，可以：\n  1. `cheapclaw_list_global_skills`\n  2. `cheapclaw_reveal_skills`\n  3. `fresh` 当前 task\n\n## 6. 渠道接入\n\n### Telegram\n当前实现：轮询 `getUpdates`。\n\n需要：\n- `bot_token`\n- 可选 `allowed_chats`\n\n群聊规则：\n- 只处理提到了 bot 的消息\n- 私聊默认直接接收\n- 识别 mention 时会同时检查：\n  - 文本里的 `@bot_username`\n  - Telegram `entities/caption_entities`\n  - `text_mention`\n  - 回复 bot 消息\n- 如果群里仍然收不到 `@bot` 消息，优先检查 BotFather 的隐私模式是否已关闭：`/setprivacy -> Disable`\n\n### Feishu\n当前实现：webhook 接收 `im.message.receive_v1`，发送走开放平台消息接口。\n\n需要：\n- `app_id`\n- `app_secret`\n- `verify_token`\n- 可选 `encrypt_key`\n\n### WhatsApp Cloud API\n当前实现：webhook 接收 + Graph API 发送文本。\n\n需要：\n- `access_token`\n- `phone_number_id`\n- `verify_token`\n- 可选 `api_version`\n\n## 7. 运行命令\n\n初始化：\n```bash\npython apps/cheapclaw/cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --bootstrap\n```\n\n查看面板：\n```bash\npython apps/cheapclaw/cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --show-panel\n```\n\n单次执行：\n```bash\npython apps/cheapclaw/cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --run-once\n```\n\n常驻轮询：\n```bash\npython apps/cheapclaw/cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --run-loop\n```\n\nWebhook：\n```bash\npython apps/cheapclaw/cheapclaw_service.py \\\n  --user-data-root /abs/path/to/user_root \\\n  --llm-config-path /abs/path/to/llm_config.yaml \\\n  --serve-webhooks --host 0.0.0.0 --port 8787\n```\n\n看板：\n- 启动 HTTP 服务后，浏览器打开 `http://127.0.0.1:8787/dashboard`\n- 面板 JSON API：`http://127.0.0.1:8787/api/panel`\n\n## 8. Panel 同步与 watchdog\n\nCheapClaw 不默认依赖 `final_output` hook 更新 panel。\n\n当前同步机制：\n1. 每个 cycle 读取 task snapshot\n2. `task_snapshot()` 同时读取：\n   - `share_context.current.agents_status`\n   - `share_context.history[*].agents_status`\n   - 进程级 running 状态\n3. 把 `last_thinking / last_final_output / pid_alive / share_context_path / stack_path / log_path` 回填到 panel\n4. 若发现 task 新完成，会向 conversation 添加 `task_completed` 事件并重新标记 `dirty`\n\n结果：\n- 即使 worker 结束后 `current` 被清空，只要 `history` 中有完成态，panel 仍能回填\n- CheapClaw 不只看 share 文件，也看进程级运行状态\n- watchdog 主要负责“可疑状态观测”，不是唯一的 panel 同步来源\n\n默认 watchdog 周期：\n- `10800` 秒，也就是 3 小时\n\n## 9. 外移到独立项目\n\n如果要把 CheapClaw 放到一个独立项目：\n1. 安装你的 MLA 包\n2. 复制 `cheapclaw/` 文件夹\n3. 保留以下内容：\n   - `cheapclaw_service.py`\n   - `tool_runtime_helpers.py`\n   - `assets/`\n   - `tools_library/`\n   - `skills/`\n4. 用独立项目自己的 `user_data_root` 运行\n\n当前实现已经把导入方式改成“本目录自举”，不会依赖仓库内 `apps.cheapclaw` 包路径。\n\n## 10. 验证\n\n当前已覆盖：\n- 面板初始化\n- 社交消息入面板\n- `message_id -> task_id` 绑定\n- 动态 `tools_library` 注册\n- skills overlay\n- 后台 task 启动\n- `add_message` 时间戳追加\n- `reset_task`\n- 独立目录导入 `cheapclaw_service.py`\n- 独立目录导入 CheapClaw custom tool\n\n对应测试文件：\n- [tests/test_cheapclaw_service.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/tests/test_cheapclaw_service.py)\n"
  },
  {
    "path": "docs/CHEAPCLAW_IMPLEMENTATION_PLAN.md",
    "content": "# CheapClaw Implementation Plan\n\n本文件是 CheapClaw 的实现前设计文档。\n\n目标：\n- 基于当前 `infiagent` SDK 和 task runtime，构建一个独立的社交消息编排服务\n- 主 agent 只做调度，不做具体业务任务\n- 主服务负责事件接入、面板状态、串行触发、后台任务守护、计划任务和容错\n\n约束：\n- 尽量把 CheapClaw 实现为一个独立应用，不强耦合当前框架目录\n- 优先复用现有 SDK、task runtime、skills、custom tools\n- 只有在必须时才做小范围框架改动，如 skills 遮掩\n\n## 1. 外部参考与结论\n\n参考 OpenClaw 官方文档，确认以下模式可借鉴：\n\n- 单一长生命周期 Gateway 统一接入多个消息渠道\n- 群消息默认按 mention 触发，而不是吃掉所有群消息\n- group / DM 使用不同 session 键\n- 多渠道共用统一事件层和状态层\n\n参考链接：\n- [OpenClaw Gateway Architecture](https://docs.openclaw.ai/architecture)\n- [OpenClaw Integrations](https://docs.openclaw.ai/)\n- [OpenClaw Groups](https://docs.openclaw.ai/channels/groups)\n- [OpenClaw Group Messages](https://docs.openclaw.ai/group-messages)\n- [OpenClaw Feishu](https://docs.openclaw.ai/channels/feishu)\n\n从这些资料推导出的结论：\n- CheapClaw 的核心不应是“再造一个 agent”\n- 应该是“消息网关 + 面板状态机 + 主服务 + 主 agent + worker tasks”\n- 主 agent 不常驻，常驻的是主服务\n\n## 2. 当前仓库已有能力\n\n当前仓库已经具备的关键能力：\n\n1. 基于 `task_id` 启动和恢复任务\n2. 判断某个 `task_id` 是否正在运行\n3. 对已有任务 `fresh`\n4. 对已有任务 `add_message`\n5. 启动后台任务\n6. 获取 `share_context` / `stack` 路径\n7. SDK 已支持：\n   - `run`\n   - `fresh`\n   - `add_message`\n   - `start_background_task`\n   - `task_share_context_path`\n   - `list_task_ids`\n8. `user_data_root` 已统一控制 `conversation/share/stack/runtime`\n9. 自定义工具可以放在 `tools_library` 中，不必改框架 builtin registry\n10. `skills_dir` 可通过 SDK / runtime env 指向任意目录\n\n关键位置：\n- [infiagent/sdk.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/infiagent/sdk.py)\n- [utils/task_runtime.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/utils/task_runtime.py)\n- [utils/runtime_control.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/utils/runtime_control.py)\n- [core/hierarchy_manager.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/core/hierarchy_manager.py)\n- [tool_server_lite/registry.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/tool_server_lite/registry.py)\n- [utils/skill_loader.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/utils/skill_loader.py)\n- [tool_server_lite/tools/skill_tools.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/tool_server_lite/tools/skill_tools.py)\n\n## 3. 当前仓库缺失能力\n\nCheapClaw 还缺这些核心模块：\n\n1. 多社交渠道 gateway 层\n2. 消息面板状态层\n3. 主服务调度器\n4. 主 agent 专用工具集\n5. 计划任务 / watchdog 层\n6. `reset_task` 类工具\n7. worker task 完成后的统一回流机制\n\n## 4. 顶层架构\n\n建议拆成 4 层：\n\n1. `Channel Gateway`\n2. `CheapClaw Service`\n3. `Main Agent`\n4. `Worker Tasks`\n\n### 4.1 Channel Gateway\n\n职责：\n- 接入 WhatsApp / Telegram / 飞书\n- 统一事件格式\n- 群聊 mention 过滤\n- 消息发送\n- 附件下载与发送\n- 去重\n\n不做：\n- 任务理解\n- task 路由决策\n- agent 调度\n\n### 4.2 CheapClaw Service\n\n职责：\n- 接收 gateway 事件\n- 更新消息面板\n- 保证主 agent 串行运行\n- 触发主 agent\n- 接收 worker task 完成事件\n- 定时巡检和 watchdog\n- 守护进程自恢复\n\n这是系统核心。\n\n### 4.3 Main Agent\n\n主 agent 是调度者，不是执行者。\n\n只负责：\n- 理解新消息\n- 判断直接回复 / 新建任务 / 续任务 / 追加消息 / resume / fresh / reset\n- 发送回执\n- 更新消息面板\n\n不负责：\n- 直接长时间做任务\n- 直接产出业务文件\n- 长期占用运行资源\n\n### 4.4 Worker Tasks\n\nWorker task 继续复用当前 `task_id` 体系：\n- 独立 workspace\n- 独立 `share_context`\n- 独立 `stack`\n- 独立 `actions`\n- 可选择不同 `agent_system`\n- 可选择不同 `skills_dir`\n\n## 5. 消息面板状态层\n\n消息面板应成为 CheapClaw 的单一事实来源。\n\n建议位置：\n- `<cheapclaw_root>/panel/panel.json`\n- `<cheapclaw_root>/panel/backups/*.json`\n\n其中 `cheapclaw_root` 建议为：\n- `<user_data_root>/cheapclaw`\n\n### 5.1 面板必须包含的字段\n\n你本轮补充后的最终字段，建议如下：\n\n```json\n{\n  \"version\": 1,\n  \"channels\": {\n    \"telegram\": {\n      \"conversations\": {\n        \"group_123\": {\n          \"channel\": \"telegram\",\n          \"conversation_id\": \"group_123\",\n          \"conversation_type\": \"group\",\n          \"display_name\": \"ML Group\",\n          \"trigger_policy\": {\n            \"require_mention\": true\n          },\n          \"message_history_path\": \"/abs/path/to/social_history.jsonl\",\n          \"messages\": [],\n          \"linked_tasks\": [\n            {\n              \"task_id\": \"/abs/path/to/task\",\n              \"agent_system\": \"OpenCowork\",\n              \"agent_name\": \"alpha_agent\",\n              \"status\": \"running\",\n              \"share_context_path\": \"/abs/path/to/share_context.json\",\n              \"stack_path\": \"/abs/path/to/stack.json\",\n              \"log_path\": \"/abs/path/to/runtime/launched_tasks/xxx.log\",\n              \"skills_dir\": \"/abs/path/to/task_skills\",\n              \"last_thinking\": \"\",\n              \"last_thinking_at\": \"\",\n              \"last_final_output\": \"\",\n              \"last_final_output_at\": \"\",\n              \"last_action_at\": \"\",\n              \"last_log_at\": \"\",\n              \"fresh_retry_count\": 0,\n              \"last_watchdog_note\": \"\"\n            }\n          ],\n          \"pending_events\": [],\n          \"dirty\": false,\n          \"last_snapshot_path\": \"/abs/path/to/panel/backups/xxx.json\",\n          \"updated_at\": \"\"\n        }\n      }\n    }\n  },\n  \"service_state\": {\n    \"main_agent_task_id\": \"/abs/path/to/cheapclaw/supervisor_task\",\n    \"main_agent_running\": false,\n    \"main_agent_run_id\": \"\",\n    \"main_agent_last_started_at\": \"\",\n    \"main_agent_last_finished_at\": \"\",\n    \"main_agent_dirty\": false,\n    \"watchdog_last_run_at\": \"\",\n    \"last_backup_path\": \"\"\n  }\n}\n```\n\n### 5.2 还需要的派生字段\n\n为了减少主 agent 重复计算，建议面板还维护这些派生字段：\n\n- `running_task_count`\n- `has_stale_running_tasks`\n- `latest_user_message_at`\n- `latest_bot_message_at`\n- `unread_event_count`\n- `last_reply_summary`\n- `conversation_tags`\n\n这些不是事实字段，但有利于主 agent 快速判断。\n\n### 5.3 share 文件地址\n\n你补的这个字段必须保留，而且不止一个：\n\n- `share_context_path`\n- `stack_path`\n- `message_history_path`\n- `log_path`\n\n这样主 agent 不需要自己推导文件位置。\n\n## 6. 主 agent 的动态输入策略\n\n### 6.1 消息面板内容不要固化进 system prompt\n\n结论：\n- 不建议把完整消息面板直接固化到 system prompt\n- 应把“面板 schema / 角色边界 / 决策原则”固化进 system prompt\n- 动态面板内容应在每次触发时作为任务输入的一部分提供\n\n原因：\n\n1. 面板变化频繁\n2. system prompt 过大容易污染所有轮次\n3. 面板是状态数据，不是长期规则\n4. 未来需要按 dirty conversations 局部注入，而不是全量注入\n\n### 6.2 推荐注入方式\n\n主 agent 每次触发时，任务输入中包含：\n\n1. 本次触发原因\n2. dirty conversation 列表\n3. 每个 conversation 的摘要\n4. 面板路径\n5. 若需要，最近一版 snapshot 路径\n\n建议格式：\n\n```text\n触发类型: social_message_update\n当前时区: Asia/Shanghai\n面板路径: /abs/path/to/panel.json\n本次 dirty conversations:\n- telegram/group_123\n- feishu/ou_xxx\n\n请先读取面板，再对每个 dirty conversation 判断：\n1. 直接聊天回复\n2. 在已有 task_id 上追加消息\n3. 恢复已有 task\n4. 在已有 task_id 上新建连续任务\n5. 新建 task_id\n6. 仅回执，不启动任务\n```\n\n## 7. 主 agent 专用工具\n\n主 agent 需要专用工具，但这些工具不必都加到框架 builtin。\n绝大多数可以做成 `tools_library` 自定义工具，然后仅暴露给 CheapClaw 专用 agent system。\n\n建议工具集合：\n\n### 7.1 必需工具\n\n1. `cheapclaw_read_panel`\n- 读消息面板\n- 支持：\n  - `only_dirty`\n  - `channel`\n  - `conversation_id`\n\n2. `cheapclaw_update_panel`\n- 更新 conversation 状态\n- 能做：\n  - 标记 dirty / clear dirty\n  - 写 `last_thinking`\n  - 写 `last_final_output`\n  - 绑定 task\n  - 更新 task status\n  - 写 `share_context_path`\n  - 写 `log_path`\n\n3. `cheapclaw_read_social_history`\n- 读某个 conversation 的社交历史\n- 默认最近 30 或 50 条\n- 支持：\n  - `limit`\n  - `only_mentions_to_bot`\n  - `from_message_id`\n  - `before_timestamp`\n  - `after_timestamp`\n\n4. `cheapclaw_send_message`\n- 发送消息到社交平台\n- 参数：\n  - `channel`\n  - `conversation_id`\n  - `message`\n  - `attachments`\n\n5. `cheapclaw_start_task`\n- 主 agent 专用任务启动工具\n- 包装现有 `start_background_task`\n- 但要把 conversation 绑定一起做掉，防止遗漏\n\n6. `cheapclaw_add_task_message`\n- 包装现有 `add_message`\n- 自动附加当前时区时间\n\n7. `cheapclaw_get_task_status`\n- 聚合：\n  - running\n  - share_context_path\n  - stack_path\n  - log_path\n  - latest_thinking\n  - latest_action_at\n  - latest_log_at\n\n8. `cheapclaw_list_agent_systems`\n- 查询当前可用 agent_system 列表\n\n9. `cheapclaw_schedule_plan`\n- 设置计划任务\n\n10. `cheapclaw_cancel_plan`\n- 取消计划任务\n\n11. `cheapclaw_reset_task`\n- 重置 task 状态\n\n### 7.2 可选工具\n\n1. `cheapclaw_generate_task_id`\n- 按规则生成新 task_id\n\n2. `cheapclaw_list_conversation_tasks`\n- 查询某个 conversation 已关联 task\n\n3. `cheapclaw_reveal_skills`\n- 为某个 task 暴露新的 skill 到 task 专属 skills overlay\n\n4. `cheapclaw_list_global_skills`\n- 看全局 skill 库，供主 agent 选择允许给某个 task 的 skills\n\n## 8. `start_background_task` 是否够用\n\n现有工具已经有基础：\n- [tool_server_lite/tools/task_tools.py](/Users/chenglin/Desktop/research/agent_framwork/vscode_version/MLA_V3/tool_server_lite/tools/task_tools.py)\n\n但参数不够贴合 CheapClaw 业务。\n\n现有问题：\n\n1. 不带 `channel / conversation_id / display_name`\n2. 不会自动绑定 panel 中的 linked task\n3. 不会自动写 `share_context_path / log_path`\n4. 不会自动生成规范 task_id\n5. 不会附带 task 专属 `skills_dir`\n\n结论：\n- 不直接给主 agent 用 `start_background_task`\n- 应新增 `cheapclaw_start_task`\n- 这个工具内部可以复用现有 SDK `start_background_task`\n\n## 9. task_id 设计\n\n### 9.1 不建议把原始群名直接写入路径\n\n建议路径：\n\n```text\n<cheapclaw_root>/tasks/<channel>/<conversation_key>/<task_slug>\n```\n\n例如：\n\n```text\n/root/cheapclaw/tasks/telegram/group_123/report_revision\n/root/cheapclaw/tasks/feishu/ou_xxx/slides_update\n```\n\n### 9.2 conversation_key 与 display_name 分离\n\n建议：\n- `conversation_key` 用稳定 ID\n- `display_name` 只放面板里展示\n\n否则群改名会导致路径漂移。\n\n### 9.3 连续任务与新任务的判断\n\n主 agent 在决定任务时，不只是判断“新 task 还是旧 task 恢复”。\n\n应区分为 3 类：\n\n1. `append_to_running_task`\n- 同一工作正在进行\n- 只需给运行中的 task 追加消息\n\n2. `continue_existing_task`\n- 同一工作，但当前未运行\n- 恢复已有 task_id\n\n3. `fork_new_task`\n- 与历史 task 有关，但应独立新建 task_id\n- 例如：\n  - 不同 deliverable\n  - 不同 agent_system\n  - 风险隔离\n  - 长实验分支\n\n因此主 agent 的决策集合应为：\n\n- 直接聊天回复\n- 在已有运行中 task 上追加消息\n- 恢复已有 task\n- 在已有工作上下文旁边新建一个新 task_id\n- 全新 task_id\n- 仅回执\n\n## 10. 主 agent 串行运行\n\n你提到“主 agent 只有一个，为什么会有同一？”\n\n这里的“同一主 agent 同时只有一个 run”指的是：\n\n- 虽然主 agent 的 task_id 固定只有一个\n- 但可能会被多个事件同时触发\n  - 新社交消息\n  - worker task 完成\n  - watchdog tick\n  - 计划任务 tick\n\n如果不加串行锁，主服务可能在前一个主 agent run 还没结束时又拉起一个新的同 task_id run。\n\n因此必须有：\n\n- `main_agent_running` 锁\n- `main_agent_dirty` 合并标记\n\n策略：\n- 如果主 agent 正在运行，新事件只写面板并标 dirty\n- 当前 run 结束后，如果 dirty 仍为 true，立刻再跑一次\n\n## 11. 群历史消息读取\n\n这里不应该把全量历史都塞给主 agent。\n\n建议工具：\n- `cheapclaw_read_social_history`\n\n默认策略：\n- 默认最近 30 条\n- 群聊默认只取与 bot 相关的 30 条\n- 可配置 `limit=50`\n\n支持参数：\n\n- `limit`\n- `only_mentions_to_bot`\n- `include_bot_replies`\n- `before_timestamp`\n- `after_timestamp`\n- `from_message_id`\n- `to_message_id`\n\n这比让主 agent 直接扫全 JSON 历史更稳。\n\n## 12. task 专属 skills 库\n\n### 12.1 可以做到，而且第一版不必改框架\n\n现有框架已经支持：\n- 通过 SDK / env 指定 `skills_dir`\n- `SkillLoader` 从当前 `skills_dir` 扫描 `<available_skills>`\n- `load_skill` 从当前 `skills_dir` 复制 skill 到 task workspace\n\n因此可以做：\n\n1. 保留全局 skill 主库，例如 `~/.agent/skills`\n2. 为每个 task 创建一个 overlay skills 目录，例如：\n\n```text\n<cheapclaw_root>/task_skills/<task_hash>/\n```\n\n3. 这个 overlay 初始只包含被主 agent 允许的 skills\n4. 启动 task 时，把 `skills_dir` 指向这个 overlay\n\n这样：\n- 子 agent 在 prompt 中只会看到被允许的 skills\n- `load_skill` 也只会从该 overlay 中加载\n\n### 12.2 “遮掩再揭开”怎么做\n\n如果你希望子 agent 知道还有更多 skill，但默认被遮住，不建议直接让它浏览全局根目录。\n\n更稳的方案：\n\n新增两个 CheapClaw 工具：\n\n1. `cheapclaw_list_global_skills`\n- 查看主库中的全部 skill 元数据\n\n2. `cheapclaw_reveal_skills`\n- 把指定 skill 从全局库复制或软链到该 task 的 overlay 中\n\n这样实现“遮掩再揭开”，而不需要放开对全局目录的任意探索。\n\n### 12.3 是否需要框架改动\n\n第一版不需要。\n\n因为：\n- `skills_dir` 已可通过 SDK 配置\n- 每个 worker task 启动时可传不同 `skills_dir`\n\n只有当你要求：\n- 同一个正在运行的 task 进程里，动态切换 `skills_dir`\n- 并让 `<available_skills>` 自动刷新\n\n这时才需要配合 `fresh` 或扩展 runtime 接口。\n\n## 13. Watchdog 策略\n\n### 13.1 不做“规则直接执行处置”\n\n你这轮修正是合理的：\n- watchdog 不应自己直接决定 `fresh` / `reset`\n- watchdog 负责提供观察结果和风险信号\n- 主 agent 使用 watchdog skill / 工具进行探索，再决定怎么处置\n\n这是比硬编码阈值更稳的策略。\n\n### 13.2 Watchdog 的输出\n\n建议 watchdog 每次 tick 更新面板中的观测字段：\n\n- `running`\n- `pid_alive`\n- `last_thinking_at`\n- `last_action_at`\n- `last_log_at`\n- `last_panel_update_at`\n- `watchdog_observation`\n- `watchdog_suspected_state`\n\n其中 `watchdog_suspected_state` 不是最终裁决，只是提示：\n\n- `healthy`\n- `quiet_but_alive`\n- `possibly_stalled`\n- `process_dead`\n- `loop_suspected`\n\n### 13.3 主 agent 如何使用 watchdog\n\n建议把 watchdog 逻辑封装为 skill 或专用工具：\n- 定时触发时，主 agent 收到一个 `watchdog_tick`\n- 读取面板上的运行观测\n- 若需要，再调用：\n  - task 状态读取工具\n  - 日志路径工具\n  - `file_read` 看日志尾部\n  - `task_share_context_path`\n  - `fresh`\n  - `reset_task`\n\n### 13.4 thinking 停滞不要直接等同卡死\n\n这是重要原则。\n\n不能写死：\n- 1 小时没更新 thinking 就等于卡死\n\n因为可能：\n- 长时间跑实验\n- 阻塞型工具在工作\n- 外部命令无输出但正常\n\n因此：\n- watchdog 只更新观测数据和怀疑等级\n- 决策留给主 agent\n\n## 14. task 状态重置\n\n当前框架没有正式的 `reset_task` 工具。\n\n第一版必须补。\n\n建议语义：\n\n```json\n{\n  \"task_id\": \"/abs/path/to/task\",\n  \"preserve_history\": true,\n  \"kill_background_processes\": true,\n  \"reason\": \"watchdog/manual/main-agent-decision\"\n}\n```\n\n行为：\n- 清空 current\n- 清空 stack\n- 可选保留 history\n- 可选终止当前 task 关联后台命令\n- 写 reset 元数据到 share_context 或 panel\n\n## 15. 主 agent 专用 agent_system\n\n主 agent 必须单独写一个 agent system。\n\n建议：\n- `CheapClawSupervisor`\n\n特点：\n- 只给 orchestration 工具\n- 不给或默认不暴露：\n  - `human_in_loop`\n  - 业务重工具\n  - 可能阻塞的命令工具\n\n### 15.1 主 agent 不需要等待长工具\n\n主 agent 应遵循：\n- 立即派工\n- 立即回执\n- 由 worker task 继续做任务\n\n因此主 agent 只应调用：\n- 面板工具\n- 消息发送工具\n- 启任务工具\n- 续任务工具\n- 计划工具\n- task 状态工具\n\n### 15.2 worker agent system 也应单独配置\n\nCheapClaw 后台 worker 至少需要独立 agent systems：\n\n1. `CheapClawSupervisor`\n2. `CheapClawWorkerGeneral`\n3. 后续按需求扩展：\n   - `CheapClawResearchWorker`\n   - `CheapClawOpsWorker`\n   - `CheapClawWriterWorker`\n\n## 16. 可以放在 `tools_library` 吗\n\n结论：\n- 可以，而且应该优先这样做\n\n现有框架支持：\n- 从 `tools_library/<tool_name>/<tool_file>.py` 加载自定义工具\n\n因此 CheapClaw 大多数新工具：\n- 不需要加进框架 builtin\n- 直接实现为自定义工具即可\n\n只需要：\n- 把工具放到 CheapClaw 自己的 `tools_library`\n- 在 CheapClaw 专用 agent_system 里配置暴露哪些工具\n\n## 17. 是否能基于当前 SDK 独立写出 CheapClaw\n\n结论：\n- 可以，大部分能力已经足够\n- CheapClaw 应尽量作为“基于 SDK 的独立应用”\n\n已经足够的部分：\n- 启动 task\n- 追加消息\n- fresh / resume\n- 指定 `agent_system`\n- 指定 `skills_dir`\n- 指定 `user_data_root`\n\n可能需要的小范围框架改动：\n\n1. 更方便读取和聚合 task 运行时摘要\n2. 更标准地获取 `latest_thinking / final_output / log_path`\n3. 增加 `reset_task`\n4. 如有需要，开放“上下文重建/状态摘要”接口供 CheapClaw 直接调用\n\n但第一版不需要大改 framework。\n\n## 18. 主服务应该放在哪里\n\n最终目标：\n- CheapClaw 可以在 `pip install mla-agent` 后，作为独立应用运行\n\n所以开发期也建议按独立应用组织。\n\n第一版建议在当前仓库先放一个单独入口：\n\n- `apps/cheapclaw/cheapclaw_service.py`\n\n如果你坚持单文件实现，第一版可以这样做。\n\n但这只是入口单文件，不表示所有逻辑都永远不拆。\n\n建议后续允许拆出：\n- `panel_store.py`\n- `gateway_adapters.py`\n- `scheduler.py`\n- `main_agent_runner.py`\n\n## 19. 实现阶段计划\n\n### Phase 1: 设计与状态层\n\n产出：\n- 消息面板 schema\n- plans schema\n- task 绑定规则\n- CheapClaw root 布局\n\n实现：\n- `apps/cheapclaw/cheapclaw_service.py`\n- 先只实现 panel 读写、备份、锁\n\n### Phase 2: 主 agent 专用工具\n\n实现：\n- `cheapclaw_read_panel`\n- `cheapclaw_update_panel`\n- `cheapclaw_read_social_history`\n- `cheapclaw_send_message`\n- `cheapclaw_start_task`\n- `cheapclaw_add_task_message`\n- `cheapclaw_get_task_status`\n- `cheapclaw_list_agent_systems`\n- `cheapclaw_schedule_plan`\n- `cheapclaw_cancel_plan`\n- `cheapclaw_reset_task`\n\n这些优先做成自定义工具。\n\n### Phase 3: 主 agent system\n\n实现：\n- `CheapClawSupervisor` agent_system\n- supervisor 专用 prompt\n- 仅暴露 orchestration 工具\n\n### Phase 4: 主服务触发器\n\n实现：\n- dirty conversation 合并\n- 主 agent 串行锁\n- 事件到主 agent 的触发\n- worker 完成回流触发\n\n### Phase 5: task-specific skills\n\n实现：\n- overlay skills 目录\n- 启动 task 时传 `skills_dir`\n- `cheapclaw_list_global_skills`\n- `cheapclaw_reveal_skills`\n\n### Phase 6: watchdog 与 scheduler\n\n实现：\n- main-agent tick\n- task tick\n- watchdog 观测写入 panel\n- 主 agent 使用 watchdog skill 判断是否处置\n\n### Phase 7: 渠道接入\n\n建议先做顺序：\n\n1. Telegram\n2. 飞书\n3. WhatsApp\n\n原因：\n- Telegram 和飞书开发/调试成本更低\n- WhatsApp 风险更高，登录会话更脆弱\n\n## 20. 当前明确采纳的设计决策\n\n根据你本轮意见，以下内容确定采纳：\n\n1. 面板中增加 `share_context_path`\n2. task 绑定工具要能一起写 panel，避免遗漏\n3. 群历史读取支持截断，默认只读最近有限条\n4. 主 agent 决定是：\n   - 旧 task 追加\n   - 旧 task 恢复\n   - 旧工作分叉出新 task\n   - 全新 task\n5. 追加消息时应附带当前时区时间\n6. watchdog 不直接硬编码处置，而是提供观测给主 agent\n7. 主 agent 与 worker 使用单独 agent_system\n8. 新工具优先做在 `tools_library`\n9. CheapClaw 优先作为基于 SDK 的独立应用\n\n## 21. 当前仍需确认的问题\n\n这些问题不阻碍 Phase 1 开始，但在接入渠道前要定：\n\n1. CheapClaw 首发先接哪个渠道\n2. 附件发送是否为 MVP 必须能力\n3. 是否允许主 agent 自动 `reset_task`\n4. 任务命名中的 `task_slug` 是否需要中文保留\n5. panel 是否采用单文件 JSON 还是 conversation 分片 JSONL\n\n当前建议：\n- MVP 用单文件 `panel.json` + backups\n- 后续量大再拆分片存储\n\n## 22. 推荐的下一步\n\n后续实现顺序建议严格按这个文档推进：\n\n1. 先做 panel store 和 CheapClaw root\n2. 再做主 agent 专用工具\n3. 再做 `CheapClawSupervisor` agent_system\n4. 再做主服务触发串行逻辑\n5. 最后才接具体社交渠道\n\n不要反过来先接消息平台，否则会在状态层未定型时把问题放大。\n"
  },
  {
    "path": "docs/CLI_GUIDE.md",
    "content": "# MLA CLI 完整使用指南 💻\n\n交互式命令行界面 (CLI) 完整教程。\n\n---\n\n## 📋 目录\n\n- [启动 CLI](#启动-cli)\n- [基础操作](#基础操作)\n- [智能体切换](#智能体切换)\n- [人机交互 HIL](#人机交互-hil)\n- [工具执行确认](#工具执行确认)\n- [任务管理](#任务管理)\n- [CLI 命令](#cli-命令)\n\n---\n\n## 🚀 启动 CLI\n\n### 方式 1: 本地安装\n\n```bash\ncd /your/workspace\nmla-agent --cli\n```\n\n### 方式 2: Docker\n\n```bash\ncd /your/workspace\ndocker run -it --rm \\\n  -v $(pwd):/workspace \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mla:latest cli\n```\n\n### 启动参数\n\n```bash\nmla-agent --cli \\\n  --task_id /custom/path \\        # 自定义工作空间\n  --agent_system Researcher \\     # 智能体系统\n  --auto-mode true               # 工具自动执行\n```\n\n---\n\n## 📝 基础操作\n\n### 直接输入任务\n\n```bash\n[alpha_agent] > 列出当前目录的文件\n```\n\nCLI 会使用当前默认智能体（`alpha_agent`）执行任务。\n\n### 多行输入\n\n在任务描述中间按 Enter 不会提交，继续输入即可。完成后按 Enter 提交。\n\n### 查看执行过程\n\n```bash\n[alpha_agent] > 分析 data.csv 文件\n\n# 你会看到：\n🤖 [alpha_agent] 初始规划: ...\n🔧 调用工具: file_read\n   参数: {\"paths\": [\"data.csv\"]}\n✅ 工具执行成功\n📊 [alpha_agent] 分析结果: ...\n```\n\n---\n\n## 🤖 智能体切换\n\n### 方法 1: 切换并执行\n\n```bash\n[alpha_agent] > @coder_agent 编写一个快速排序算法\n\n# 输出：\n✅ 已切换到: coder_agent\n🤖 [coder_agent] 开始任务: 编写一个快速排序算法\n```\n\n### 方法 2: 仅切换默认智能体\n\n```bash\n[alpha_agent] > @coder_agent\n✅ 已切换到: coder_agent\n\n[coder_agent] > 现在所有任务都使用 coder_agent\n```\n\n### 查看可用智能体\n\n```bash\n[alpha_agent] > /agents\n\n📋 可用 Agents:\n  1. alpha_agent (当前)\n  2. data_collection_agent\n  3. coder_agent\n  4. data_to_figures_agent\n  5. material_to_document_agent\n  6. get_idea_and_experiment_plan\n  7. web_search_agent\n```\n\n---\n\n## 🔔 人机交互（HIL）\n\n当智能体需要人工输入时，CLI 会自动检测并提示。\n\n### 触发场景\n\n```bash\n[alpha_agent] > 请用户确认后再继续\n\n# 智能体内部调用 human_in_loop 工具\n```\n\n### 提示界面\n\n```\n🔔🔔🔔 检测到 HIL 任务！按回车处理... 🔔🔔🔔\n================================================================================\n🔔 人类交互任务（HIL）\n================================================================================\n📝 任务 ID：upload_file_20250127\n📋 指令：请上传数据文件到 upload/ 目录，完成后确认...\n================================================================================\n💡 输入你的响应（任何文本）\n   输入 /skip 跳过此任务\n================================================================================\n\n[alpha_agent] HIL 响应 > 文件已上传\n✅ HIL 任务已响应\n```\n\n### 响应方式\n\n- **确认完成**：输入任何文本（如\"已完成\"、\"done\"等）\n- **跳过任务**：输入 `/skip`\n- **提供详细说明**：输入多行文本\n\n---\n\n## ⚠️ 工具执行确认\n\n在手动模式（`--auto-mode false`）下，每个工具执行需要确认。\n\n### 启动手动模式\n\n```bash\nmla-agent --cli --auto-mode false\n```\n\n### 确认界面\n\n```\n⚠️⚠️⚠️ 检测到工具执行请求！按回车确认... ⚠️⚠️⚠️\n================================================================================\n⚠️  工具执行确认请求\n================================================================================\n🔧 工具名称：python_run\n📝 确认 ID：confirm_12345\n📋 参数：\n     code: import pandas as pd...\n     timeout: 300\n================================================================================\n💡 选择操作：\n   yes / y - 批准执行\n   no / n  - 拒绝执行\n================================================================================\n\n[alpha_agent] 确认 [yes/no] > yes\n✅ 已批准执行工具：python_run\n```\n\n### 使用场景\n\n**自动模式（默认）：** 适用于可信任务\n```bash\n[alpha_agent] > 分析数据并生成图表\n# 自动执行所有工具，无需确认\n```\n\n**手动模式：** 适用于敏感操作\n```bash\n# 启动时指定\nmla-agent --cli --auto-mode false\n\n[alpha_agent] > 删除旧文件\n# 每个文件操作都需要你确认\n```\n\n---\n\n## 📋 CLI 命令\n\n### 系统命令\n\n| 命令 | 功能 | 示例 |\n|------|------|------|\n| `/help` | 显示帮助 | `/help` |\n| `/agents` | 列出可用智能体 | `/agents` |\n| `/quit` | 退出 CLI | `/quit` 或 `/exit` |\n| `/resume` | 恢复中断任务 | `/resume` |\n| `Ctrl+C` | 中断当前任务 | - |\n| `Ctrl+D` | 立即退出 | - |\n\n### /help 输出\n\n```\n💡 MLA CLI 使用帮助\n================================================================================\n基础操作:\n  直接输入任务             - 使用默认 Agent 执行\n  @agent_name 任务        - 切换并执行任务\n  @agent_name            - 仅切换默认 Agent\n\n系统命令:\n  /help                  - 显示此帮助\n  /agents                - 列出所有可用 Agents\n  /resume                - 恢复中断的任务\n  /quit 或 /exit         - 退出 CLI\n  Ctrl+C                 - 中断当前任务（保持在 CLI）\n  Ctrl+D                 - 立即退出 CLI\n\n人机交互:\n  - 当出现 🔔 HIL 提示时，按回车进入响应模式\n  - 输入响应内容完成任务\n\n工具确认:\n  - 手动模式下，工具执行需要确认\n  - 输入 yes/y 批准，no/n 拒绝\n================================================================================\n```\n\n---\n\n## 🔄 任务管理\n\n### 中断任务\n\n```bash\n[alpha_agent] > 写一篇很长的论文...\n# 任务正在执行...\n\n# 按 Ctrl+C\n⚠️  正在中断任务...\n✅ 任务已中断\n\n💡 输入相同内容可续跑，输入新内容开始新任务\n```\n\n### 恢复任务\n\n**方式 1: 输入相同任务描述**\n```bash\n[alpha_agent] > 写一篇很长的论文...\nℹ️  检测到相同任务，将续跑\n▶️  从断点继续...\n```\n\n**方式 2: 使用 /resume 命令**\n```bash\n[alpha_agent] > /resume\n\n📋 发现中断的任务\n================================================================================\n🤖 Agent: alpha_agent\n📝 任务: 写一篇很长的论文...\n⏸️  中断于: 2025-12-27 19:30:15\n📊 栈深度: 2\n================================================================================\n\n是否恢复此任务？ [y/N]: y\n▶️  恢复任务...\n```\n\n---\n\n## 🎨 界面特性\n\n### Rich 终端 UI\n\nCLI 使用 `prompt_toolkit` 和 `rich` 提供：\n\n- ✨ **语法高亮**\n- 🎨 **彩色输出**\n- 📊 **格式化表格**\n- 🔔 **音频提醒**（HIL 任务）\n- ⌨️ **历史记录**（上下键）\n- 📝 **自动补全**（智能体名称）\n\n### 启动画面\n\n```\n================================================================================\n🤖 MLA Agent - 交互式 CLI 模式\n================================================================================\n📂 工作目录: /Users/username/project\n🤖 默认Agent: alpha_agent\n📋 可用Agents: alpha_agent, coder_agent, data_collection_agent...\n────────────────────────────────────────────────────────────────────────────────\n💡 使用说明:\n  • 直接输入任务（使用默认 Agent）\n  • @agent_name 任务（切换并使用指定 Agent）\n  • 🔔 HIL 任务出现时会自动提示，输入响应内容即可\n  • Ctrl+C 中断任务 | /resume 恢复 | /quit 退出 | /help 帮助\n────────────────────────────────────────────────────────────────────────────────\n```\n\n---\n\n## 💡 使用技巧\n\n### 1. 快速文件操作\n\n```bash\n[alpha_agent] > 读取 file1.txt, file2.txt, file3.txt 的内容\n\n# 智能体会使用批量读取，一次调用读取多个文件\n```\n\n### 2. 链式任务\n\n```bash\n[alpha_agent] > 先收集关于 Transformer 的论文，然后总结，最后写成综述\n\n# 智能体会自动拆分为多个步骤执行\n```\n\n### 3. 使用子智能体\n\n```bash\n[alpha_agent] > @data_collection_agent 收集最近的 NLP 论文\n# data_collection_agent 会自动调用 web_search_agent\n\n[alpha_agent] > @coder_agent 实现论文中的算法\n# coder_agent 会自动处理代码执行环境\n```\n\n### 4. 查看工作空间\n\n```bash\n[alpha_agent] > 查看 upload 目录有什么文件\n\n# 智能体会列出文件并说明每个文件的用途\n```\n\n---\n\n## 🐛 故障排除\n\n### CLI 无法启动\n\n```bash\n# 直接启动 CLI（当前版本无需单独启动工具服务器）\nmla-agent --cli\n```\n\n### 智能体无响应\n\n```bash\n# Ctrl+C 中断\n# 检查配置\nmla-agent --config-show\n\n# 检查 API key 是否有效\n```\n\n### 历史对话混乱\n\n```bash\n# 强制开始新任务\nmla-agent --cli --force-new\n\n# 或清理历史\nrm ~/.mla_v3/conversations/*_stack.json\nrm ~/.mla_v3/conversations/*_share_context.json\n```\n\n---\n\n## 📊 高级功能\n\n### 自定义智能体系统\n\n```bash\n# 使用自定义 agent_system\nmla-agent --cli --agent_system MyCustomSystem\n\n# 需要先创建配置目录\n# config/agent_library/MyCustomSystem/\n```\n\n### JSONL 输出模式\n\n```bash\n# 用于 IDE 集成\nmla-agent --jsonl --task_id /workspace --user_input \"任务\"\n\n# 输出 JSON Lines 格式\n{\"type\":\"start\",...}\n{\"type\":\"token\",\"text\":\"...\"}\n{\"type\":\"result\",...}\n```\n\n### 批量任务执行\n\n```bash\n# 脚本化执行多个任务\nfor task in \"任务1\" \"任务2\" \"任务3\"; do\n  mla-agent --task_id ~/project --user_input \"$task\"\ndone\n```\n\n---\n\n## 🎓 最佳实践\n\n### 1. 任务描述清晰\n\n```bash\n# ✅ 好的任务描述\n[alpha_agent] > 收集 2023-2024 年关于 Transformer 的 10 篇高引论文\n\n# ❌ 模糊的任务描述\n[alpha_agent] > 找点论文\n```\n\n### 2. 使用合适的智能体\n\n```bash\n# 文献收集 → data_collection_agent\n# 代码开发 → coder_agent\n# 数据可视化 → data_to_figures_agent\n# 论文撰写 → material_to_document_agent\n# 综合任务 → alpha_agent（自动编排）\n```\n\n### 3. 利用历史记忆\n\n```bash\n# 第一次对话\n[alpha_agent] > 收集机器学习论文\n# ... 智能体收集了 10 篇论文\n\n# 第二次对话（几天后，同一工作空间）\n[alpha_agent] > 总结之前收集的论文\n# ✅ 智能体会记住并使用之前收集的论文\n```\n\n### 4. 工作空间管理\n\n```bash\n# 不同项目使用不同目录\ncd ~/project_a && mla-agent --cli  # 项目 A\ncd ~/project_b && mla-agent --cli  # 项目 B\n\n# 对话历史自动隔离\n```\n\n---\n\n## 🎬 实际案例\n\n### 案例 1: 学术论文写作\n\n```bash\ncd ~/my_paper\nmla-agent --cli\n\n[alpha_agent] > 写一篇关于深度强化学习的综述论文\n\n# 智能体会自动：\n# 1. 调用 data_collection_agent 收集文献\n# 2. 调用 get_idea_and_experiment_plan 设计结构\n# 3. 调用 material_to_document_agent 撰写论文\n# 4. 生成 LaTeX 文件到 upload/\n```\n\n### 案例 2: 数据分析\n\n```bash\ncd ~/data_project\nmla-agent --cli\n\n[alpha_agent] > @data_to_figures_agent\n[data_to_figures_agent] > 分析 sales_data.csv 并生成月度趋势图\n\n# 智能体会：\n# 1. 读取 CSV 文件\n# 2. 分析数据\n# 3. 生成 matplotlib 图表\n# 4. 保存为 PNG（300 DPI）\n```\n\n### 案例 3: 代码开发\n\n```bash\ncd ~/code_project\nmla-agent --cli\n\n[alpha_agent] > @coder_agent\n[coder_agent] > 实现二叉树的三种遍历方法并编写测试\n\n# 智能体会：\n# 1. 编写代码\n# 2. 创建虚拟环境\n# 3. 运行测试\n# 4. 调试错误\n```\n\n---\n\n## 📚 快捷键\n\n| 快捷键 | 功能 |\n|--------|------|\n| `Enter` | 提交当前输入 |\n| `Ctrl+C` | 中断当前任务 |\n| `Ctrl+D` | 退出 CLI |\n| `↑` / `↓` | 浏览历史命令 |\n| `Tab` | 自动补全（智能体名称） |\n\n---\n\n## 🎯 性能优化\n\n### 减少 Token 消耗\n\n```bash\n# ✅ 批量操作\n[alpha_agent] > 读取所有 txt 文件并总结\n\n# ❌ 多次单独操作\n[alpha_agent] > 读取 file1.txt\n[alpha_agent] > 读取 file2.txt\n[alpha_agent] > 读取 file3.txt\n```\n\n### 利用文件系统\n\n```bash\n# ✅ 使用文件传递数据\n[alpha_agent] > 将分析结果保存到 result.txt\n[alpha_agent] > 基于 result.txt 生成报告\n\n# ❌ 直接在对话中返回大量数据\n```\n\n---\n\n## 📖 相关文档\n\n- [Docker 使用指南](DOCKER_GUIDE.md)\n- [配置文件说明](../config/agent_library/Researcher/)\n- Runtime tools are executed in-process via direct-tools; no standalone Tool Server is required.\n- [主 README](../README.md)\n\n---\n\n**掌握 CLI，高效使用 MLA！** 💻\n"
  },
  {
    "path": "docs/DOCKER_GUIDE.md",
    "content": "# MLA Docker 完整使用指南 🐳\n\n**无需安装 Python，仅需 Docker！**\n\n---\n\n## 📋 目录\n\n- [简介](#简介)\n- [安装 Docker](#安装-docker)\n- [快速开始](#快速开始)\n- [配置管理](#配置管理)\n- [数据持久化](#数据持久化)\n- [常见问题](#常见问题)\n- [高级使用](#高级使用)\n\n---\n\n## 📖 简介\n\nMLA Docker 版本特点：\n\n- ✅ **零依赖**：无需安装 Python 和依赖包\n- ✅ **开箱即用**：一行命令启动\n- ✅ **完整功能**：CLI、direct-tools、Config Web 全包含\n- ✅ **跨平台**：Mac、Linux、Windows 统一体验\n- ✅ **数据持久**：对话历史保存在宿主机\n\n---\n\n## 🔧 安装 Docker\n\n### Mac\n\n下载并安装 [Docker Desktop for Mac](https://www.docker.com/products/docker-desktop)\n\n**M 系列芯片用户需安装 Rosetta 2：**\n```bash\nsoftwareupdate --install-rosetta --agree-to-license\n```\n\n### Windows\n\n下载并安装 [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop)\n\n### Linux\n\n```bash\n# Ubuntu/Debian\ncurl -fsSL https://get.docker.com -o get-docker.sh\nsudo sh get-docker.sh\n\n# 添加当前用户到 docker 组\nsudo usermod -aG docker $USER\n```\n\n**验证安装：**\n```bash\ndocker --version\ndocker ps\n```\n\n---\n\n## 🚀 快速开始\n\n### 步骤 1: 拉取镜像\n\n```bash\ndocker pull chenglinhku/mlav3:latest\n```\n\n### 步骤 2: 选择启动模式\n\n#### 方式 A: Web UI 模式（推荐）\n\n```bash\n# 进入你的工作目录\ncd /path/to/your/project\n\n# 后台启动 Web UI\ndocker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 \\\n  -p 9641:9641 \\\n  -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui && docker logs -f mla\n```\n\n然后在浏览器打开：`http://localhost:4242`\n\n#### 方式 B: CLI 模式\n\n```bash\n# 进入你的工作目录\ncd /path/to/your/project\n\n# 交互式启动 CLI\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 \\\n  -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli\n```\n\n### 步骤 3: 配置 API Key\n\n**方式 A: 通过 Web 界面（推荐）**\n\n1. 容器启动后，打开浏览器：`http://localhost:9641`\n2. 点击左侧 `run_env_config/llm_config.yaml`\n3. 编辑配置文件，填入 API Key\n4. 点击\"💾 保存文件\"\n\n<p align=\"center\">\n  <img src=\"../assets/config_web_screen_shot.png\" alt=\"配置管理界面\" width=\"800\">\n</p>\n\n**方式 B: 首次启动交互式配置**\n\n容器启动时会提示：\n```\n是否现在配置 API key? [y/N]: y\n请输入你的 OpenRouter API Key: sk-or-v1-xxxxx\n✅ API key 已配置！\n```\n\n### 步骤 4: 开始使用\n\n```bash\n[alpha_agent] > 列出当前目录的文件\n[alpha_agent] > @coder_agent 编写一个 hello world 程序\n```\n\n---\n\n## ⚙️ 配置管理\n\n### Web 配置界面\n\n**访问地址：** `http://localhost:9641`\n\n**功能：**\n- 📁 树形目录显示所有配置文件\n- ✏️ 在线编辑 YAML 配置\n- ⚡ 快速配置 API Key 和 Base URL\n- 💾 实时保存，自动生效\n- 🔄 一键重新加载\n- 🔒 自动 YAML 格式验证\n\n**可编辑的配置：**\n- `llm_config.yaml` - LLM 配置\n- `general_prompts.yaml` - 通用提示词\n- `level_0_tools.yaml` - 工具定义\n- `level_1/2/3_agents.yaml` - 各层级智能体\n\n### 命令行配置\n\n```bash\n# 进入容器配置\ndocker run -it --rm \\\n  -v mla-config:/mla_config \\\n  chenglinhku/mlav3:latest \\\n  /bin/bash\n\n# 在容器内\nmla-agent --config-show\nmla-agent --config-set api_key \"your-key\"\n```\n\n---\n\n## 💾 数据持久化\n\n### 数据存储位置\n\n| 数据类型 | 存储位置 | 说明 |\n|---------|---------|------|\n| 对话历史 | `~/.mla_v3/` | 宿主机本地 |\n| 配置文件 | Docker volume `mla-config` | 持久化 |\n| 工作文件 | 当前目录 | 实时同步 |\n\n### 生命周期\n\n| 操作 | 对话历史 | 配置文件 | 工作文件 |\n|------|---------|---------|---------|\n| 停止容器 | ✅ 保留 | ✅ 保留 | ✅ 保留 |\n| 删除镜像 | ✅ 保留 | ✅ 保留 | ✅ 保留 |\n| 删除 volume | ✅ 保留 | ❌ 丢失 | ✅ 保留 |\n\n### 备份和恢复\n\n**备份配置：**\n```bash\ndocker run --rm \\\n  -v mla-config:/data \\\n  -v $(pwd):/backup \\\n  alpine tar czf /backup/mla-config-backup.tar.gz -C /data .\n```\n\n**恢复配置：**\n```bash\ndocker run --rm \\\n  -v mla-config:/data \\\n  -v $(pwd):/backup \\\n  alpine tar xzf /backup/mla-config-backup.tar.gz -C /data\n```\n\n**备份对话历史：**\n```bash\ntar czf mla-conversations-backup.tar.gz ~/.mla_v3\n```\n\n---\n\n## 🎯 使用场景\n\n### 场景 1: 日常研究工作\n\n**使用 Web UI：**\n\n```bash\ncd ~/my_research\ndocker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui && docker logs -f mla\n\n# 打开浏览器: http://localhost:4242\n```\n\n**使用 CLI：**\n\n```bash\ncd ~/my_research\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli\n\n[alpha_agent] > 写一篇关于 Transformer 的综述论文\n```\n\n### 场景 2: 多项目管理\n\n```bash\n# 项目 A - Web UI\ncd ~/project_a\ndocker run -d --name mla-project-a \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 4242:4242 -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest webui\n# 对话历史独立：~/.mla_v3/conversations/{hash_a}_*\n\n# 项目 B - CLI（新终端）\ncd ~/project_b  \ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli\n# 对话历史独立：~/.mla_v3/conversations/{hash_b}_*\n```\n\n### 场景 3: CI/CD 集成\n\n```yaml\n# GitHub Actions\njobs:\n  generate-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Run MLA\n        run: |\n          docker run --rm \\\n            -e HOST_PWD=${{ github.workspace }} \\\n            -v ${{ github.workspace }}:/workspace${{ github.workspace }} \\\n            -e OPENROUTER_API_KEY=${{ secrets.API_KEY }} \\\n            chenglinhku/mlav3:latest \\\n            task --task_id ${{ github.workspace }} --user_input \"生成文档\"\n```\n\n### 场景 4: 服务器部署\n\n```bash\n# 使用 Web UI 后台运行长时间任务\ndocker run -d --name mla-research \\\n  -e HOST_PWD=/data/research \\\n  -v /data/research:/workspace/data/research \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 4242:4242 -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest webui\n\n# 查看日志\ndocker logs -f mla-research\n\n# 访问 Web UI\n# http://your-server-ip:4242\n```\n\n---\n\n## 🐛 常见问题\n\n### Q1: CLI 无法启动\n\n**症状：** 容器内 CLI 启动失败或直接退出\n\n**解决：**\n```bash\n# 查看镜像内帮助\ndocker run --rm chenglinhku/mlav3:latest mla-agent --help\n\n# 交互式启动 CLI\ndocker run -it --rm chenglinhku/mlav3:latest cli\n```\n\n### Q2: 配置不生效\n\n**症状：** 修改配置后仍然提示 API key 错误\n\n**解决：**\n```bash\n# 检查配置是否正确保存\ndocker run --rm -v mla-config:/mla_config chenglinhku/mlav3:latest \\\n  cat /mla_config/llm_config.yaml\n\n# 重新配置\ndocker run -it --rm -v mla-config:/mla_config chenglinhku/mlav3:latest \\\n  mla-agent --config-set api_key \"your-key\"\n```\n\n### Q3: 权限错误\n\n**症状：** 容器创建的文件无法在宿主机访问\n\n**解决（Linux）：**\n```bash\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -u $(id -u):$(id -g) \\\n  chenglinhku/mlav3:latest cli\n```\n\n### Q4: Web UI 界面无法访问\n\n**症状：** `http://localhost:4242` 无法打开（Web UI）或 `http://localhost:9641` 无法打开（配置界面）\n\n**解决：**\n```bash\n# 确保端口已暴露\ndocker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v mla-config:/mla_config \\\n  -p 4242:4242 \\  # ← Web UI 端口\n  -p 9641:9641 \\  # ← 配置管理端口\n  chenglinhku/mlav3:latest webui\n\n# 检查端口是否被占用\nlsof -i:4242  # Mac/Linux\nlsof -i:9641  # Mac/Linux\nnetstat -ano | findstr 4242  # Windows\nnetstat -ano | findstr 9641  # Windows\n```\n\n### Q5: 中文显示乱码\n\n**症状：** CLI 中中文显示为问号或方块\n\n**解决：**\n```bash\ndocker run -it --rm \\\n  -e LANG=C.UTF-8 \\\n  -e LC_ALL=C.UTF-8 \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  chenglinhku/mlav3:latest cli\n```\n\n---\n\n## 🌍 跨平台使用\n\n### Mac / Linux - CLI 模式\n\n```bash\ndocker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli\n```\n\n### Mac / Linux - Web UI 模式\n\n```bash\ndocker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui && docker logs -f mla\n```\n\n### Windows PowerShell - CLI 模式\n\n```powershell\ndocker run -it --rm `\n  -e HOST_PWD=\"${PWD}\" `\n  -v \"${PWD}:/workspace${PWD}\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  -v mla-config:/mla_config `\n  -p 8002:8002 -p 9641:9641 `\n  chenglinhku/mlav3:latest cli\n```\n\n### Windows PowerShell - Web UI 模式\n\n```powershell\ndocker run -d --name mla `\n  -e HOST_PWD=\"${PWD}\" `\n  -v \"${PWD}:/workspace${PWD}\" `\n  -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n  -v mla-config:/mla_config `\n  -p 8002:8002 -p 9641:9641 -p 4242:4242 `\n  chenglinhku/mlav3:latest webui; docker logs -f mla\n```\n\n### Windows CMD\n\n```cmd\ndocker run -it --rm ^\n  -e HOST_PWD=%cd% ^\n  -v %cd%:/workspace%cd% ^\n  -v %USERPROFILE%\\.mla_v3:/root/mla_v3 ^\n  -v mla-config:/mla_config ^\n  -p 8002:8002 -p 9641:9641 ^\n  chenglinhku/mlav3:latest cli\n```\n\n---\n\n## 💡 便捷使用技巧\n\n### 创建别名\n\n**Mac/Linux (~/.zshrc 或 ~/.bashrc)：**\n```bash\n# CLI 模式\nalias mla-cli='docker run -it --rm \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli'\n\n# Web UI 模式\nalias mla-web='docker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui && docker logs -f mla'\n\n# 使用\ncd ~/my_project\nmla-cli  # CLI 模式\n# 或\nmla-web  # Web UI 模式 (http://localhost:4242)\n```\n\n**Windows PowerShell ($PROFILE)：**\n```powershell\nfunction mla-cli {\n    docker run -it --rm `\n      -e HOST_PWD=\"${PWD}\" `\n      -v \"${PWD}:/workspace${PWD}\" `\n      -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n      -v mla-config:/mla_config `\n      -p 8002:8002 -p 9641:9641 `\n      chenglinhku/mlav3:latest cli\n}\n\nfunction mla-web {\n    docker run -d --name mla `\n      -e HOST_PWD=\"${PWD}\" `\n      -v \"${PWD}:/workspace${PWD}\" `\n      -v \"${HOME}\\.mla_v3:/root/mla_v3\" `\n      -v mla-config:/mla_config `\n      -p 8002:8002 -p 9641:9641 -p 4242:4242 `\n      chenglinhku/mlav3:latest webui; docker logs -f mla\n}\n```\n\n### 创建启动脚本\n\n**mla-cli.sh (Mac/Linux):**\n```bash\n#!/bin/bash\ndocker run -it --rm \\\n  -e HOST_PWD=\"$(pwd)\" \\\n  -v \"$(pwd)\":/workspace\"$(pwd)\" \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 \\\n  chenglinhku/mlav3:latest cli\n```\n\n**mla-web.sh (Mac/Linux):**\n```bash\n#!/bin/bash\ndocker run -d --name mla \\\n  -e HOST_PWD=\"$(pwd)\" \\\n  -v \"$(pwd)\":/workspace\"$(pwd)\" \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 8002:8002 -p 9641:9641 -p 4242:4242 \\\n  chenglinhku/mlav3:latest webui && docker logs -f mla\n```\n\n```bash\nchmod +x mla-cli.sh mla-web.sh\n./mla-cli.sh  # CLI 模式\n# 或\n./mla-web.sh  # Web UI 模式\n```\n\n---\n\n## 🔄 更新镜像\n\n### 检查更新\n\n```bash\n# 查看本地镜像信息\ndocker images chenglinhku/mlav3:latest\n\n# 拉取最新版本\ndocker pull chenglinhku/mlav3:latest\n\n# 如果有运行中的容器，需要重启\ndocker stop mla\ndocker rm mla\n# 然后重新启动\n```\n\n### 清理旧镜像\n\n```bash\n# 删除旧版本\ndocker image prune -a\n\n# 或指定删除旧镜像名\ndocker rmi chenglinhku/mla:latest  # 旧镜像名\ndocker rmi chenglinhku/mlav3:old-version\n```\n\n---\n\n## 📊 资源管理\n\n### 查看容器资源使用\n\n```bash\ndocker stats\n```\n\n### 限制资源\n\n```bash\ndocker run -it --rm \\\n  --memory=\"4g\" \\\n  --cpus=\"2\" \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  chenglinhku/mlav3:latest cli\n```\n\n### 清理所有数据\n\n```bash\n# 删除所有容器\ndocker container prune\n\n# 删除未使用的镜像\ndocker image prune -a\n\n# 删除 volume（配置会丢失！）\ndocker volume rm mla-config\n\n# 清理对话历史（宿主机）\nrm -rf ~/.mla_v3/conversations/*\n```\n\n---\n\n## 🌐 网络配置\n\n### 使用代理\n\n```bash\ndocker run -it --rm \\\n  -e HTTP_PROXY=http://proxy.example.com:8080 \\\n  -e HTTPS_PROXY=http://proxy.example.com:8080 \\\n  -e NO_PROXY=localhost,127.0.0.1 \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  chenglinhku/mlav3:latest cli\n```\n\n### 访问宿主机服务\n\n```bash\n# 容器内访问宿主机\n# Mac/Windows: host.docker.internal\n# Linux: 172.17.0.1\n\ndocker run -it --rm \\\n  --add-host=host.docker.internal:host-gateway \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  chenglinhku/mlav3:latest cli\n```\n\n---\n\n## 🔐 安全最佳实践\n\n### 1. 不要在镜像中硬编码密钥\n\n```bash\n# ❌ 错误\n# 将包含密钥的配置文件打包到镜像\n\n# ✅ 正确\n# 使用 volume 或环境变量传递密钥\n```\n\n### 2. 使用 .env 文件\n\n```bash\n# 创建 .env\necho \"OPENROUTER_API_KEY=your-key\" > .env\n\n# 使用（需要 docker-compose）\ndocker-compose run --rm mla-agent\n```\n\n### 3. 配置文件权限\n\n```bash\n# 只读挂载配置\n-v $(pwd)/config.yaml:/app/config.yaml:ro\n```\n\n---\n\n## 📝 与本地安装对比\n\n| 特性 | 本地安装 | Docker |\n|------|---------|---------|\n| 需要 Python | ✅ | ❌ |\n| 安装复杂度 | 中 | 低 |\n| 启动速度 | 快 | 快 |\n| 性能 | 100% | 95-100% |\n| 环境隔离 | 需要 venv | 自动 |\n| 跨平台 | 需适配 | 一致 |\n| 更新 | pip install | docker pull |\n| 配置方式 | CLI/文件 | CLI/文件/**Web** |\n| 界面 | CLI | **CLI + Web UI** |\n\n---\n\n## 🌐 Web UI 模式\n\n新版 Docker 镜像 (`chenglinhku/mlav3:latest`) 包含完整的 Web UI 功能：\n\n### 特性\n\n- ✅ **可视化界面**：直观的对话界面\n- ✅ **多任务管理**：支持多个项目的任务切换\n- ✅ **实时监控**：查看 agent 执行状态\n- ✅ **文件浏览**：直接浏览和编辑工作空间文件\n- ✅ **配置管理**：Web 界面配置 API key 和模型\n- ✅ **历史记录**：查看所有对话历史\n\n### 端口说明\n\n| 端口 | 用途 | 必需 |\n|------|------|------|\n| 4242 | Web UI 主界面 | Web UI 模式 ✅ |\n| 9641 | 配置管理界面 | 推荐 ✅ |\n| XXXX | Agent 开发端口 | 可选 |\n\n### 快速启动 Web UI\n\n```bash\ncd ~/my_project\ndocker run -d --name mla \\\n  -e HOST_PWD=$(pwd) \\\n  -v $(pwd):/workspace$(pwd) \\\n  -v ~/.mla_v3:/root/mla_v3 \\\n  -v mla-config:/mla_config \\\n  -p 4242:4242 -p 9641:9641 -p 8002:8002 \\\n  chenglinhku/mlav3:latest webui\n\n# 查看日志\ndocker logs -f mla\n\n# 访问界面\n# Web UI: http://localhost:4242\n# 配置管理: http://localhost:9641\n```\n\n### Web UI vs CLI\n\n| 特性 | Web UI | CLI |\n|------|--------|-----|\n| 界面 | 图形化 | 命令行 |\n| 多任务 | ✅ 可视化切换 | 需要多终端 |\n| 文件管理 | ✅ 集成浏览器 | 需要外部工具 |\n| 历史查看 | ✅ 完整展示 | 限制 |\n| 配置管理 | ✅ Web 界面 | CLI 命令 |\n| 适合场景 | 日常使用、演示 | 脚本、CI/CD |\n\n---\n\n## 🎓 学习资源\n\n- [CLI 详细教程](CLI_GUIDE.md)\n- [配置文件说明](../config/agent_library/Researcher/)\n- Runtime tools are executed in-process via direct-tools; no standalone Tool Server is required.\n- [主 README](../README.md)\n\n---\n\n**开始使用 Docker 版 MLA V3，支持 CLI 和 Web UI 双模式！** 🐳\n"
  },
  {
    "path": "docs/EVENT_SCHEMA.md",
    "content": "# Agent 事件系统 (Event System) - v2\n\n本文档旨在说明 `infiAgent` 项目中经过规范化重构后的事件驱动架构，为二次开发和系统集成提供指导。\n\n## 1. 设计哲学\n\n为了将核心的Agent业务逻辑与外部的展示、日志、监控等功能解耦，我们引入了一套事件系统。其核心思想遵循**观察者模式**：\n\n-   **事件生产者 (Producer)**：`AgentExecutor` 在其执行的关键节点，只负责生产并“分发”携带结构化数据的事件，它不关心事件如何被消费。\n-   **事件消费者 (Consumer/Handler)**：可以有多个事件处理器，它们“订阅”事件流。每个处理器根据自己的职责，对感兴趣的事件进行处理。例如，`ConsoleLogHandler` 负责将事件格式化后打印到控制台，而 `JsonlStreamHandler` 则负责将事件序列化为JSONL格式，供外部工具使用。\n\n这种设计使得添加新的输出渠道（如HTTP SSE、WebSocket、文件日志等）变得非常简单，只需实现一个新的事件处理器并注册即可，无需修改`AgentExecutor`的任何代码。\n\n## 2. 事件命名与划分规范\n\n为了保证事件的清晰性和可扩展性，我们遵循以下规范：\n\n### A. 事件命名 (`event_type`)\n\n所有事件的 `event_type` 字符串都遵循 **`phase.domain.action`** 的三段式命名格式：\n\n-   `phase`: 描述事件发生在Agent生命周期的哪个主要阶段。\n    -   `prepare`: 任务执行前（循环开始前）的准备阶段。\n    -   `run`: Agent的核心执行循环阶段。\n    -   `agent`: 贯穿整个生命周期的Agent自身事件。\n    -   `system`: 非业务逻辑的系统级事件，如CLI打印或严重错误。\n-   `domain`: 事件所属的业务领域。\n    -   `model`: 模型选择。\n    -   `history`: 对话历史加载。\n    -   `llm`: 大语言模型交互。\n    -   `tool`: 工具执行。\n    -   `thinking`: Agent的自我反思/规划。\n-   `action`: 具体的动作。\n    -   `start`, `end`, `fail`, `select`, `load` 等。\n\n**示例**: `prepare.model.select` 表示在“准备阶段”，关于“模型领域”的“选择”事件。\n\n### B. 事件类别\n\n我们将事件明确划分为两大类：\n\n-   **核心生命周期事件**: 代表关键状态转变，携带结构化数据，是程序化消费的主要对象。\n-   **系统/展示事件**: 主要用于CLI展示或表示非业务逻辑的系统状态（如错误），通常不被外部业务系统消费。\n\n---\n\n## 3. 当前事件清单\n\n所有事件均定义在 `core/events.py` 中。\n\n### 核心生命周期事件\n\n| `event_type` 字符串         | 事件类 (Event Class)      | 触发时机                                          | 主要数据字段 (`payload`)                                  |\n| --------------------------- | ------------------------- | ------------------------------------------------- | --------------------------------------------------------- |\n| **Agent Lifecycle**         |                           |                                                   |                                                           |\n| `agent.start`               | `AgentStartEvent`         | Agent的 `run` 方法被调用时。                      | `agent_name`, `task_input`                                |\n| `agent.end`                 | `AgentEndEvent`           | Agent任务结束（成功、失败或超时）。               | `status` (字符串), `result` (最终产出或错误信息)        |\n| **Prepare Phase**           |                           |                                                   |                                                           |\n| `prepare.model.select`      | `ModelSelectionEvent`     | 在初始化时选择最终要使用的LLM。                   | `requested_model`, `final_model`, `is_fallback`           |\n| `prepare.history.load`      | `HistoryLoadEvent`        | 从存储中成功加载历史记录后。                      | `start_turn`, `action_history_len`, `pending_tool_count`  |\n| **Run Phase**               |                           |                                                   |                                                           |\n| `run.llm.start`             | `LlmCallStartEvent`       | 即将向LLM发起请求时。                             | `model`, `system_prompt`                                  |\n| `run.llm.end`               | `LlmCallEndEvent`         | 收到LLM的响应后。                                 | `llm_output`, `tool_calls` (列表)                         |\n| `run.tool.start`            | `ToolCallStartEvent`      | 即将执行一个工具时。                              | `tool_name`, `arguments`                                  |\n| `run.tool.end`              | `ToolCallEndEvent`        | 工具执行完毕后。                                  | `tool_name`, `status`, `result`                           |\n| `run.thinking.start`        | `ThinkingStartEvent`      | Agent开始思考/规划时。                            | `agent_name`, `is_initial` (是否初次规划), `is_forced` (是否强制) |\n| `run.thinking.end`          | `ThinkingEndEvent`        | 思考/规划成功结束。                               | `agent_name`, `result` (思考结果文本)                     |\n| `run.thinking.fail`         | `ThinkingFailEvent`       | 思考/规划过程中发生错误。                         | `agent_name`, `error_message`                             |\n\n### 系统与展示事件\n\n| `event_type` 字符串       | 事件类 (Event Class)    | 触发时机                                               | 主要数据字段 (`payload`)                                  |\n| ------------------------- | ----------------------- | ------------------------------------------------------ | --------------------------------------------------------- |\n| `system.error`            | `ErrorEvent`            | 发生导致任务中断的严重错误时。                         | `error_display` (格式化后的完整错误信息字符串)          |\n| `system.cli_display`      | `CliDisplayEvent`       | 需要在控制台打印任何非关键的状态信息时。               | `message` (要打印的字符串), `style` (`info`, `warning`等) |\n\n---\n\n## 4. 如何拓展新事件\n\n在为系统添加新功能时，请遵循以下准则来决定是否以及如何添加新事件：\n\n### 步骤1: 判断事件类型\n\n首先问自己：**“这个新事件所代表的信息，除了给CLI用户看之外，是否有可能被其他系统（如Web UI、监控、测试）以编程方式利用？”**\n\n-   **如果答案是“是”**:\n    -   这应该是一个**核心生命周期事件**。\n    -   在 `core/events.py` 中，创建一个新的 `dataclass` 继承自 `AgentEvent`。\n    -   遵循 `phase.domain.action` 的规范为 `event_type` 命名。\n    -   为它定义清晰、结构化的字段。\n    -   **示例**: 假设我们要引入一个“上下文压缩”的详细事件，供UI展示压缩细节。可以创建一个 `ContextCompressionEvent`，`event_type` 为 `run.context.compress`，并包含 `original_tokens`, `compressed_tokens`, `summary` 等字段。\n\n-   **如果答案是“否”**:\n    -   这应该是一个**CLI展示事件**。\n    -   **不要创建新的事件类！** 直接在需要打印信息的地方，分发一个 `CliDisplayEvent` 即可。\n    -   **示例**: 如果想在开始压缩前打印一条消息，只需在 `_compress_action_history_if_needed` 方法中调用:\n        ```python\n        self.event_emitter.dispatch(\n            CliDisplayEvent(message=\"正在准备压缩历史记录...\")\n        )\n        ```\n\n### 步骤2: 更新事件处理器\n\n-   **如果添加了新的核心生命周期事件**:\n    -   **必须** 更新 `ConsoleLogHandler` (`core/event_handlers.py`)，添加一个对应的 `_print_...` 方法来在CLI中友好地展示它（方法名将 `.` 替换为 `_`）。\n    -   **必须** 考虑是否需要更新 `JsonlStreamHandler`。根据新的实现，`JsonlStreamHandler`会自动序列化所有非系统事件，因此通常无需修改，除非需要特殊处理。\n\n-   **如果只是分发了新的`CliDisplayEvent`**:\n    -   **无需任何操作**。现有的 `ConsoleLogHandler` 会自动处理它，而 `JsonlStreamHandler` 会自动忽略它。这就是该设计的优势所在。\n\n遵循以上准则，可以确保我们的事件系统在不断迭代的过程中，始终保持清晰、解耦和易于维护。"
  },
  {
    "path": "docs/SDK_GUIDE.md",
    "content": "# InfiAgent SDK Guide\n\n适用版本：建议使用 `infiagent 3.2.1+`\n\n这份文档按当前代码实现编写，目标是让你在 `pip install infiagent` 之后，只靠这份文档就能理解：\n\n- `task_id` 到底是什么\n- `user_data_root`、`skills_dir`、`tools_dir` 各自控制什么\n- 默认目录里哪些内容会自动生成，哪些不会\n- 怎么把默认配置复制到你自己的项目目录\n- SDK 的同步 / 异步接口分别怎么用\n- 怎么接入自己的动态工具（外挂 tool）\n\n核心结论先说：\n\n1. `infiagent(...)` 负责定义一个 SDK 实例的运行时默认配置。\n2. 真正执行任务时，必须显式提供 `task_id`。\n3. `task_id` 不是一个抽象字符串，它就是这个任务的工作目录绝对路径。\n4. `user_data_root` 控制配置、agent system、运行状态、日志、share context 等目录。\n5. `skills` 默认是全局目录 `~/.agent/skills`，不跟随 `user_data_root`，除非你显式覆盖。\n6. `tools_library` 默认只会创建目录，不会像 `agent_library` 和 `skills` 那样自动复制内置工具进去。\n\n参考代码：\n\n- SDK 入口：`infiagent/sdk.py`\n- 用户目录与默认资源：`utils/user_paths.py`\n- 配置加载：`utils/config_loader.py`\n- 后台任务启动 / fresh / resume：`utils/task_runtime.py`\n- 动态工具注册：`tool_server_lite/registry.py`\n\n## 1. 安装\n\n推荐直接从 PyPI 安装：\n\n```bash\npython -m pip install -U infiagent\n```\n\n确认版本：\n\n```bash\npython - <<'PY'\nimport importlib.metadata\nprint(importlib.metadata.version(\"infiagent\"))\nPY\n```\n\n如果你有多个 Python 环境，请始终用实际运行 SDK 的那个解释器安装，例如：\n\n```bash\n/opt/anaconda3/bin/python -m pip install -U infiagent\n```\n\n## 2. 第一次启动应该做什么\n\n安装完成后，最推荐做的一步不是直接跑任务，而是先让 SDK 打印运行时目录：\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent()\nruntime = agent.describe_runtime()\nprint(runtime)\n```\n\n这一步会做两件事：\n\n1. 打印当前实例实际使用的路径。\n2. 触发默认 runtime scaffold 的创建与内置资源的初始化。\n\n注意：\n\n- 仅仅执行 `agent = infiagent()` 构造函数，本身不会创建目录，也不会自动种资源。\n- 真正触发目录初始化的是 `describe_runtime()`、`run()`、`add_message()` 这类进入 runtime scope 的方法。\n\n## 3. 先分清两类目录\n\n### 3.1 `user_data_root`：SDK 的运行时根目录\n\n默认是：\n\n```text\n~/mla_v3\n```\n\n它下面通常会有：\n\n```text\n~/mla_v3/\n├── config/\n│   ├── llm_config.yaml\n│   └── app_config.json\n├── agent_library/\n├── tools_library/\n├── conversations/\n├── logs/\n└── runtime/\n```\n\n这些目录分别负责：\n\n- `config/`：LLM 配置、app runtime 配置\n- `agent_library/`：agent system YAML\n- `tools_library/`：你的自定义动态工具目录\n- `conversations/`：share context / stack / per-agent actions 持久化\n- `logs/`：普通日志目录\n- `runtime/`：后台任务、task events、运行态文件\n\n### 3.2 `task_id`：单个任务的工作目录\n\n`task_id` 不是逻辑 ID，不是 UUID，也不是数据库主键。\n\n当前 SDK 语义里：\n\n- `task_id` 就是任务工作目录的绝对路径\n- 同一个 `task_id` 代表同一个任务身份\n- 同一个 `task_id` 会复用同一份 workspace、share context、stack、历史动作和运行状态\n\n例如：\n\n```python\ntask_id=\"/path/to/my_agent_project/tasks/refactor_task\"\n```\n\n那么：\n\n- 这个目录本身是任务的工作空间\n- 任务生成的文件一般写到这里\n- `system-add.md` 放在这里\n- 当前 task 加载的 skills 会部署到这里的 `.skills/`\n\n### 3.3 `skills_dir`：全局 skills 源库\n\n默认是：\n\n```text\n~/.agent/skills/\n```\n\n它和 `user_data_root` 是两套目录：\n\n- `user_data_root` 管这个 SDK 实例的运行时\n- `skills_dir` 管全局可发现的 skill 源库\n\n默认情况下：\n\n- 发现 skill：从 `~/.agent/skills/` 扫描\n- 加载 skill：复制到 `<task_id>/.skills/<skill_name>/`\n\n## 4. 默认会自动生成什么，不会自动生成什么\n\n第一次真正进入 runtime scope 后，默认行为是：\n\n### 4.1 会自动创建 / 补齐\n\n- `~/mla_v3/config/llm_config.yaml`\n- `~/mla_v3/config/app_config.json`\n- `~/mla_v3/agent_library/`\n- `~/mla_v3/tools_library/`\n- `~/mla_v3/conversations/`\n- `~/mla_v3/logs/`\n- `~/mla_v3/runtime/`\n- `~/.agent/skills/`\n\n### 4.2 会自动种进去的内置资源\n\n- `agent_library` 中的内置 agent systems\n- `skills` 中的内置 skills\n- `llm_config.yaml` 的默认样例\n- `app_config.json` 的默认样例\n\n### 4.3 不会自动种进去的内容\n\n`tools_library` 默认只会创建空目录：\n\n```text\n~/mla_v3/tools_library/\n```\n\n不会自动复制内置 Python tool 文件进去。\n\n也就是说，下面这件事经常是空操作：\n\n```bash\ncp -R ~/mla_v3/tools_library/. /path/to/my_agent_project/runtime/tools_library/\n```\n\n因为默认安装后的 `~/mla_v3/tools_library/` 往往本来就是空的。\n\n## 5. `task_id` 的精确定义\n\n这是最重要的一节。\n\n### 5.1 `task_id` 是工作目录绝对路径\n\n推荐始终传绝对路径：\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent()\nresult = agent.run(\n    \"请分析这个目录并给出重构建议\",\n    task_id=\"/abs/path/to/tasks/refactor_task\",\n)\n```\n\nSDK 内部会对它做：\n\n- `expanduser()`\n- `resolve()`\n\n但你仍然应该自己按“绝对路径工作目录”来理解和设计。\n\n### 5.2 同一个 `task_id` 会复用什么\n\n同一个 `task_id` 会复用：\n\n- 同一个工作目录\n- 同一份 `share_context`\n- 同一份 `stack`\n- 同一组 per-agent `actions`\n- 同一段任务历史与 runtime metadata\n\n所以：\n\n- 同一 deliverable 的继续修改：优先复用旧 `task_id`\n- 对同一任务补充新要求：优先 `add_message(...)`\n- 已停止但仍是同一工作：可以 `start_background_task(task_id=旧 task_id, ...)`\n- 全新 deliverable / 并行分支 / 完全不同工作：新建新的 `task_id`\n\n### 5.3 `task_id` 对应的文件到底存在哪里\n\n任务工作目录是：\n\n```text\n<task_id>/\n```\n\n而 runtime metadata 不直接写在 `<task_id>/`，而是写到：\n\n```text\n<user_data_root>/conversations/\n```\n\n文件命名不是固定的 `share_context.json`、`stack.json`、`actions.json`，而是带 task hash 的形式：\n\n- `<hash>_<task-folder>_share_context.json`\n- `<hash>_<task-folder>_stack.json`\n- `<hash>_<task-folder>_<agent_id>_actions.json`\n\n因此，最稳妥的定位方式不是猜文件名，而是用 SDK：\n\n```python\npaths = agent.task_share_context_path(task_id=\"/abs/path/to/tasks/refactor_task\")\nprint(paths[\"share_context_path\"])\nprint(paths[\"stack_path\"])\n```\n\n### 5.4 `fresh()` 对停止任务的真实行为\n\n文档里最容易被误解的一点是：\n\n- 运行中的 task：`fresh()` 会发送 fresh 请求\n- 未运行的 task：不是“必然后台 resume”\n\n只有当这个 task 已经有：\n\n- 可恢复的 `stack`\n- 足够的 runtime metadata\n\n时，`fresh()` 才能在后台 resume。\n\n如果没有可恢复状态，`fresh()` 会返回错误，而不是自动创建一个新任务。\n\n## 6. 如何查看当前实例实际在用哪些路径\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent()\nruntime = agent.describe_runtime()\nprint(runtime)\n```\n\n返回里最常用的字段有：\n\n- `user_data_root`\n- `config_dir`\n- `llm_config_path`\n- `app_config_path`\n- `agent_library_dir`\n- `tools_dir`\n- `skills_dir`\n- `conversations_dir`\n- `logs_dir`\n- `runtime_dir`\n- `default_agent_system`\n- `default_agent_name`\n- `seed_builtin_resources`\n\n如果你想看当前有哪些 agent system：\n\n```python\nsystems = agent.list_agent_systems()\nprint(systems[\"agent_systems\"])\n```\n\n注意返回字段名是：\n\n```python\nagent_systems\n```\n\n不是 `systems`。\n\n## 7. 推荐的目录使用方式\n\n不要直接长期在默认的 `~/mla_v3` 里开发你的项目逻辑。\n\n更推荐的方式是：\n\n1. 用默认用户目录拿到标准样例和内置系统\n2. 复制到你自己的项目 runtime\n3. 让你的应用显式绑定自己的 `user_data_root`\n\n推荐项目结构：\n\n```text\nmy_agent_project/\n├── runtime/\n│   ├── config/\n│   │   ├── llm_config.yaml\n│   │   └── app_config.json\n│   ├── agent_library/\n│   │   └── MyAgentSystem/\n│   ├── tools_library/\n│   │   └── echo_text/\n│   │       └── echo_text.py\n│   ├── conversations/\n│   ├── logs/\n│   └── runtime/\n├── tasks/\n│   ├── task_a/\n│   └── task_b/\n├── hooks/\n│   └── my_hooks.py\n└── main.py\n```\n\n好处：\n\n- 配置和状态都跟你的项目一起管理\n- 不污染全局 `~/mla_v3`\n- 更容易迁移、打包、部署\n\n## 8. 把默认配置复制到你自己的目录\n\n### 8.1 先让默认资源种出来\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent()\nagent.describe_runtime()\n```\n\n### 8.2 创建你自己的 runtime\n\n```bash\nmkdir -p /path/to/my_agent_project/runtime/config\nmkdir -p /path/to/my_agent_project/runtime/agent_library\nmkdir -p /path/to/my_agent_project/runtime/tools_library\nmkdir -p /path/to/my_agent_project/tasks\n```\n\n### 8.3 复制标准配置和你要用的 agent system\n\n```bash\ncp ~/mla_v3/config/llm_config.yaml /path/to/my_agent_project/runtime/config/\ncp ~/mla_v3/config/app_config.json /path/to/my_agent_project/runtime/config/\ncp -R ~/mla_v3/agent_library/OpenCowork /path/to/my_agent_project/runtime/agent_library/MyAgentSystem\n```\n\n说明：\n\n- `tools_library` 不需要从 `~/mla_v3` 复制默认内容，因为默认情况下它本来就是空目录\n- 你只要自己在 `/path/to/my_agent_project/runtime/tools_library/` 里新增工具即可\n\n### 8.4 用你自己的 runtime 启动 SDK\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    default_agent_system=\"MyAgentSystem\",\n    default_agent_name=\"alpha_agent\",\n)\n```\n\n如果你的 runtime 已经包含：\n\n- `config/llm_config.yaml`\n- `config/app_config.json`\n- `agent_library/...`\n- `tools_library/...`\n\n通常就不需要再额外传：\n\n- `llm_config_path`\n- `agent_library_dir`\n- `tools_dir`\n\n## 9. 参考配置文件样例\n\n下面两份就是你最应该先准备好的配置。\n\n### 9.1 `llm_config.yaml` 参考样例\n\n这是一个和当前实现兼容的有效样例：\n\n```yaml\ntemperature: 0\nmax_tokens: 0\nmax_context_window: 500000\n\nbase_url: https://openrouter.ai/api/v1\napi_key: \"YOUR_API_KEY\"\n\ntimeout: 600\nstream_timeout: 30\nfirst_chunk_timeout: 30\n\ntool_choice:\n  execution: required\n  thinking: none\n  compressor: none\n  image_generation: none\n  read_figure: none\n\nmodels:\n  - name: openai/google/gemini-3-flash-preview\n    default: true\n\nfigure_models:\n  - google/gemini-3-pro-image-preview\n\ncompressor_models:\n  - openai/google/gemini-3-flash-preview\n\nthinking_models:\n  - openai/google/gemini-3-flash-preview\n\nread_figure_models:\n  - openai/google/gemini-3-flash-preview\n\nmultimodal: true\ncompressor_multimodal: true\n```\n\n你也可以用对象格式按模型单独覆盖 `base_url`、`api_key`、`tool_choice`：\n\n```yaml\nmodels:\n  - name: openai/qwen-plus\n    default: true\n    api_key: \"YOUR_DASHSCOPE_KEY\"\n    base_url: https://dashscope.aliyuncs.com/compatible-mode/v1\n    tool_choice: auto\n```\n\n当前实现支持的模型用途包括：\n\n- `models`：执行模型\n- `thinking_models`：thinking agent\n- `compressor_models`：压缩模型\n- `figure_models`：图像生成模型\n- `read_figure_models`：读图模型\n\n对应的 agent YAML 偏好字段包括：\n\n- `execution_model`\n- `thinking_model`\n- `compressor_model`\n- `image_generation_model`\n- `read_figure_model`\n\n### 9.2 `app_config.json` 参考样例\n\n```json\n{\n  \"runtime\": {\n    \"thinking_enabled\": true,\n    \"thinking_steps\": 30,\n    \"no_tool_retry_limit\": 7,\n    \"visible_skills\": [],\n    \"fresh_enabled\": false,\n    \"fresh_interval_sec\": 0\n  },\n  \"env\": {\n    \"command_mode\": \"direct\",\n    \"seed_builtin_resources\": true\n  },\n  \"context\": {\n    \"user_history_compress_threshold_tokens\": 1500,\n    \"user_history_recent_items\": 0,\n    \"structured_call_info_compress_threshold_agents\": 10,\n    \"structured_call_info_compress_threshold_tokens\": 2200\n  }\n}\n```\n\n这里最常改的是：\n\n- `runtime.thinking_enabled`\n- `runtime.thinking_steps`\n- `runtime.no_tool_retry_limit`\n- `runtime.visible_skills`\n- `runtime.fresh_enabled`\n- `runtime.fresh_interval_sec`\n- `context.user_history_recent_items`\n- `context.user_history_compress_threshold_tokens`\n\n如果你是 SDK 嵌入式使用，`mcp_servers=[...]` 更推荐直接在构造参数里传，而不是先写 `app_config.json`。\n\n## 10. 推荐的最小 agent system 改法\n\n最简单的方式不是从零写一套 YAML，而是先复制一个现成 system，再逐步改。\n\n例如基于 `OpenCowork`：\n\n```bash\ncp -R ~/mla_v3/agent_library/OpenCowork /path/to/my_agent_project/runtime/agent_library/MyAgentSystem\n```\n\n你最常改的是：\n\n- `general_prompts.yaml`\n- `level_0_tools.yaml`\n- `level_3_agents.yaml`\n\n### 10.1 `general_prompts.yaml`\n\n通常只需要改：\n\n- 系统角色\n- 工作流程\n- 输出要求\n\n### 10.2 `level_0_tools.yaml`\n\n这里定义工具的 schema，让 LLM 知道工具名、描述、参数。\n\n### 10.3 `level_3_agents.yaml`\n\n这里定义 LLM agent：\n\n- agent 名称\n- `available_tools`\n- 模型偏好\n- prompt 中注入的职责\n\n## 11. SDK 初始化参数总览\n\n最常用构造方式：\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    default_agent_system=\"MyAgentSystem\",\n    default_agent_name=\"alpha_agent\",\n    thinking_enabled=True,\n    thinking_steps=30,\n    no_tool_retry_limit=7,\n    user_history_recent_items=0,\n    max_turns=100000,\n)\n```\n\n主要参数如下：\n\n| 参数 | 作用 | 备注 |\n| --- | --- | --- |\n| `user_data_root` | 这套实例的 runtime 根目录 | 最推荐使用 |\n| `llm_config_path` | 指定 `llm_config.yaml` 路径 | 可覆盖 `user_data_root/config/llm_config.yaml` |\n| `library_dir` / `agent_library_dir` | 指向包含 `agent_library/` 的根目录 | 兼容旧参数，推荐优先用 `user_data_root` |\n| `skills_dir` | 指定 skills 源库目录 | 默认 `~/.agent/skills` |\n| `tools_dir` | 指定动态工具根目录 | 默认 `<user_data_root>/tools_library` |\n| `default_agent_system` | 默认 agent system 名称 | 默认 `OpenCowork` |\n| `default_agent_name` | 默认入口 agent 名称 | 默认 `alpha_agent` |\n| `thinking_enabled` | 是否启用 ThinkingAgent 模式 | `True`=Thinking 模式，`False`=ReAct 模式 |\n| `thinking_steps` | Thinking 模式下“思考后执行 N 步”的步数 | 兼容旧字段 `thinking_interval` / `action_window_steps` |\n| `no_tool_retry_limit` | Thinking 模式下，连续未调用工具的最大提醒次数 | 默认 `7` |\n| `visible_skills` | 限制当前实例对 agent 暴露的 skills 名单 | 留空表示暴露全部可见 skills |\n| `user_history_compress_threshold_tokens` | 历史任务压缩阈值 | 可按实例覆盖 |\n| `user_history_recent_items` | 注入 prompt 的最近历史任务条数 | `0` 表示保留旧行为：读取全部历史 |\n| `max_turns` | 单次 run 的最大轮次上限 | SDK 默认 `100000`，可按实例或单次 `run()` 覆盖 |\n| `fresh_enabled` | 是否启用定时 fresh | 可选 |\n| `fresh_interval_sec` | fresh 周期秒数 | 可选 |\n| `mcp_servers` | 直接注入 MCP 配置 | SDK 嵌入场景推荐 |\n| `tool_hooks` | 工具调用 hook | 见后文 |\n| `context_hooks` | 上下文构建 hook | 见后文 |\n| `llm_config` | 直接传完整 `llm_config.yaml` 对应的 dict | 与 `llm_config_path` 二选一 |\n| `model_profiles` | 直接传结构化模型配置，SDK 会自动落成兼容 YAML | 适合不想手写 `llm_config.yaml` 的集成 |\n| `seed_builtin_resources` | 是否自动种内置 agent systems / skills | 默认 `True` |\n| `direct_tools` | 是否使用进程内 direct tools | 默认 `True`，保持默认即可 |\n| `workspace` | 旧参数兼容保留 | 新语义下不要依赖它，显式传 `task_id` |\n\n## 12. 公共同步 API\n\n下面这些都是当前 SDK 已公开的方法。\n\n### 12.1 `run(...)`\n\n同步前台执行一个任务：\n\n```python\nresult = agent.run(\n    \"请分析这个目录并给出重构建议\",\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    collect_events=True,\n    include_trace=True,\n)\nprint(result)\n```\n\n要点：\n\n- `task_id` 必填\n- `agent_system`、`agent_name` 可覆盖实例默认值\n- `force_new=True` 会清空当前 task 的 current state 和 stack 后重新开始\n- 默认最大轮次上限是 `100000`，你也可以通过 `max_turns=` 显式覆盖\n- 如果这个 task 已在运行，会返回 `status=\"busy\"`，而不是强行并发重入\n- `collect_events=True` 时，返回值里会附带结构化 `events`\n- `include_trace=True` 时，返回值里会附带当前 task 的 `trace`\n- `raise_on_error=True` 时，`status=\"error\"` 不再只靠返回值判断，而会抛出 `InfiAgentRunError`\n- `stream_llm_tokens=True` 时，`on_event` / `collect_events` 会额外收到 execution / thinking 的 token 级事件；默认关闭\n- `stream_llm_tokens` 只控制 SDK 是否把 token 级事件向外透出；LLM 请求层自己的 `timeout` / `stream_timeout` / `first_chunk_timeout` 仍然由 `llm_config.yaml` 控制\n- 当 `thinking_enabled=False` 时，不会再有独立 `thinking_turns`；相应的 ReAct 反思轮会记录在 `model_outputs.execution_turns` 中，`debug_label` 为 `react_reflection`\n- 前台 `run()` 也支持按任务临时覆盖实例默认值，例如 `thinking_enabled=`、`thinking_steps=`、`no_tool_retry_limit=`、`visible_skills=`、`user_history_recent_items=`；这些显式参数优先级高于实例默认配置和 `app_config.json`\n\n也可以实时消费事件：\n\n```python\nfrom infiagent import InfiAgentRunError, infiagent\n\nagent = infiagent()\n\ndef on_event(event: dict):\n    print(event[\"event_type\"], event[\"payload\"])\n\ntry:\n    result = agent.run(\n        \"执行任务\",\n        task_id=\"/path/to/my_agent_project/tasks/demo_task\",\n        collect_events=True,\n        on_event=on_event,\n        stream_llm_tokens=True,\n        raise_on_error=True,\n    )\nexcept InfiAgentRunError as exc:\n    print(exc.result)\n    print(exc.events)\n```\n\n`events` 的结构是统一的：\n\n- `event_type`：例如 `run.tool.start`\n- `phase` / `domain` / `action`：拆分后的阶段字段\n- `payload`：该事件的结构化内容，例如 tool 参数、tool 结果、thinking 文本等\n\n如果打开 `stream_llm_tokens=True`，还会看到：\n\n- `run.thinking.token`\n- `run.thinking.reasoning_token`\n- `run.thinking.reset`\n- `run.llm.token`\n- `run.llm.reasoning_token`\n- `run.llm.reset`\n\n说明：\n\n- `*.token` / `*.reasoning_token` 事件的 `payload` 里会带 `attempt`\n- 如果某一轮流式输出中途失败并触发重试，SDK 会先发 `run.llm.reset` 或 `run.thinking.reset`\n- 你的消费端应在收到 `reset` 后清空当前正在拼接的那一段流式文本，再继续接收下一次尝试的 token\n\n当前 `run()` 返回值的主要内容块通常包括：\n\n- `status` / `output` / `error_information`：最终任务结果\n- `events`：如果你打开了 `collect_events=True`\n- `trace`：如果你打开了 `include_trace=True`\n- `last_execution_output`：最近一次主 execution model 的原生文本输出\n- `last_execution_reasoning_content`：最近一次主 execution model 的原生 reasoning / thinking 内容\n- `last_thinking_output`：最近一次 thinking model 的原生文本输出\n- `last_thinking_reasoning_content`：最近一次 thinking model 的原生 reasoning 内容\n- `model_outputs.execution_turns`：本次 run 期间每一轮主模型调用的完整记录\n- `model_outputs.thinking_turns`：本次 run 期间每一轮 thinking 调用的完整记录\n\n### 12.2 `fresh(...)`\n\n```python\nagent.fresh(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    reason=\"reload runtime config\",\n)\n```\n\n行为：\n\n- task 正在运行：发送定向 fresh 请求\n- task 未运行但可恢复：重载配置后后台 resume\n- task 未运行且不可恢复：返回 error\n\n当前 fresh 会覆盖这些配置源：\n\n- `app_config.json` 里的 runtime / context 配置\n- `llm_config.yaml`\n- `agent_library`\n- `tools_library`\n- skills loader 缓存\n- MCP servers\n- tool hooks / context hooks\n- visible skills\n\n运行中的任务会在安全点调用 `_perform_fresh()`，重建 `ConfigLoader`、`SimpleLLMClient`、`ContextBuilder`、`ToolExecutor`；未运行但仍可恢复的任务则通过 `resume_task_with_fresh()` 用当前配置后台恢复。\n\n### 12.3 `add_message(...)`\n\n```python\nagent.add_message(\n    \"补充要求：保留原目录结构，只允许做增量修改。\",\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    source=\"user\",\n    resume_if_needed=True,\n)\n```\n\n适合：\n\n- 对同一任务追加需求\n- 给运行中的 task 插入新消息\n- 已停止 task 先追加消息，再视情况后台恢复\n\n`resume_if_needed=True` 的当前语义是：\n\n- 如果 task 仍在运行：只追加消息，不额外拉起新进程\n- 如果 task 已停止但 stack 仍存在：按原有 resume 语义后台恢复\n- 如果 task 已停止且 stack 已空：把这条新消息当作新的任务输入，直接在同一个 `task_id` 上后台启动一轮新任务\n\n补充说明：\n\n- “原始 resume” 的核心前提仍然是 `stack` 非空\n- `add_message(..., resume_if_needed=True)` 比原始 resume 多一层运行态判断：如果 task 还在运行，它只会追加消息，不会再单独拉起恢复线程\n\n### 12.4 `start_background_task(...)`\n\n```python\nagent.start_background_task(\n    task_id=\"/path/to/my_agent_project/tasks/task_b\",\n    user_input=\"后台整理日志并生成总结\",\n    agent_system=\"MyAgentSystem\",\n    agent_name=\"alpha_agent\",\n    force_new=True,\n    max_turns=5000,\n)\n```\n\n特点：\n\n- 启动独立后台 Python 进程\n- `task_id` 对应的目录不存在时会自动创建\n- 日志写到 `<user_data_root>/runtime/launched_tasks/`\n\n`config=` 还支持在后台启动时临时覆盖运行时参数，常见键包括：\n\n- `llm_config_path`\n- `llm_config`\n- `model_profiles`\n- `user_data_root`\n- `agent_library_dir` / `library_dir`\n- `skills_dir`\n- `tools_dir`\n- `thinking_enabled`\n- `thinking_steps`\n- `no_tool_retry_limit`\n- `max_turns`\n- `fresh_enabled`\n- `fresh_interval_sec`\n- `user_history_compress_threshold_tokens`\n- `user_history_recent_items`\n- `structured_call_info_compress_threshold_agents`\n- `structured_call_info_compress_threshold_tokens`\n- `mcp_servers`\n- `tool_hooks`\n- `context_hooks`\n- `visible_skills`\n- `auto_mode`\n- `force_new`\n- `direct_tools`\n- `seed_builtin_resources`\n\n### 12.5 `task_share_context_path(...)`\n\n```python\npaths = agent.task_share_context_path(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\"\n)\nprint(paths[\"share_context_path\"])\nprint(paths[\"stack_path\"])\n```\n\n用来精确定位 runtime metadata 文件路径。\n\n### 12.6 `list_task_ids(...)`\n\n```python\ntasks = agent.list_task_ids()\nrunning_only = agent.list_task_ids(only_running=True)\nprint(tasks[\"tasks\"])\n```\n\n返回当前 `user_data_root/conversations` 下已知的任务列表。\n\n### 12.7 `describe_runtime(...)`\n\n```python\nruntime = agent.describe_runtime()\nprint(runtime)\n```\n\n这是最推荐的 runtime 自省入口。\n\n### 12.8 `list_agent_systems(...)`\n\n```python\nsystems = agent.list_agent_systems()\nfor item in systems[\"agent_systems\"]:\n    print(item[\"name\"], item[\"agent_names\"])\n```\n\n返回：\n\n- system 名称\n- 路径\n- 是否包含 `general_prompts.yaml`\n- 是否包含 `level_0_tools.yaml`\n- 该 system 下识别出的 agent 名称\n\n### 12.9 `task_snapshot(...)`\n\n```python\nsnapshot = agent.task_snapshot(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\"\n)\nprint(snapshot)\n```\n\n适合做 dashboard / watchdog / 外部调度：\n\n- 是否还在运行\n- 最新 instruction\n- 最新 thinking\n- 最近 final output\n- share_context / stack 路径\n\n### 12.10 `task_trace(...)`\n\n```python\ntrace = agent.task_trace(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\"\n)\nprint(trace[\"agent_traces\"][0][\"action_history_fact\"])\n```\n\n适合在 SDK 外部读取完整动作轨迹：\n\n- tool 参数\n- tool 执行结果\n- pending tools\n- 最新 thinking\n- 对应的 `_actions.json` 路径\n\n默认返回精简版，不包含 render history 和大块 system prompt。\n如果确实需要，也可以打开：\n\n```python\ntrace = agent.task_trace(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    include_render_history=True,\n    include_system_prompt=True,\n)\n```\n\n### 12.11 `reset_task(...)`\n\n```python\nagent.reset_task(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    reason=\"clear broken loop\",\n    preserve_history=True,\n    kill_background_processes=True,\n)\n```\n\n适合：\n\n- 清理损坏的 current state\n- 保留或丢弃旧 history\n- 停掉关联后台进程\n\n## 13. 异步 API：和同步版是否一致，会不会有坑\n\n当前 SDK 为所有主要同步方法都提供了 `_async` 版本：\n\n- `run_async`\n- `fresh_async`\n- `add_message_async`\n- `start_background_task_async`\n- `task_share_context_path_async`\n- `list_task_ids_async`\n- `describe_runtime_async`\n- `list_agent_systems_async`\n- `task_snapshot_async`\n- `task_trace_async`\n- `reset_task_async`\n\n### 13.1 语义是否一致\n\n一致。\n\n这些 async 方法不是另一套独立实现，而是用 `asyncio.to_thread(...)` 包装同步方法，所以：\n\n- 参数语义一致\n- 返回结构一致\n- 报错条件一致\n- 业务行为一致\n\n例如：\n\n```python\nruntime = await agent.describe_runtime_async()\ntasks = await agent.list_task_ids_async()\nresult = await agent.run_async(\n    \"分析这个目录\",\n    task_id=\"/path/to/my_agent_project/tasks/async_task\",\n    collect_events=True,\n    stream_llm_tokens=True,\n    raise_on_error=True,\n)\n```\n\n这里的 `stream_llm_tokens=True` 语义和同步版完全一致：\n\n- 它控制 SDK 事件里是否透出 token\n- 不负责覆盖 `llm_config.yaml` 中的超时参数\n\n### 13.2 async 版本的真实定位\n\n它的定位是：\n\n- 方便你在 `asyncio` 应用里调用 SDK\n- 避免在 event loop 里直接阻塞\n\n它不是：\n\n- 一套“天然支持高并发并行隔离”的运行时\n- 一套线程安全的多实例并发调度框架\n\n### 13.3 当前 async 版本的并发注意事项\n\n这点非常重要。\n\nSDK 内部会通过 `runtime_env_scope(...)` 临时切换环境变量来隔离：\n\n- `MLA_USER_DATA_ROOT`\n- `MLA_LLM_CONFIG_PATH`\n- `MLA_SKILLS_LIBRARY_DIR`\n- `MLA_TOOLS_LIBRARY_DIR`\n- hooks / MCP / runtime 参数等\n\n这些环境变量是进程级全局状态，不是线程局部状态。\n\n所以当前建议是：\n\n- 可以在 `asyncio` 项目里使用 `_async` 方法\n- 但不要在同一个 Python 进程里，让多个 SDK 调用无控制地并发重叠运行\n- 特别是不同 `user_data_root`、不同 `tools_dir`、不同 hooks 的实例，更不要并发重叠调用\n\n最稳的用法：\n\n1. 同一进程里串行调用 SDK\n2. 或者自己加一个 `asyncio.Lock()`\n3. 真要强隔离并发，就做进程隔离\n\n一个安全写法示例：\n\n```python\nimport asyncio\nfrom infiagent import infiagent\n\nagent = infiagent(user_data_root=\"/path/to/my_agent_project/runtime\")\nsdk_lock = asyncio.Lock()\n\nasync def safe_run(prompt: str, task_id: str):\n    async with sdk_lock:\n        return await agent.run_async(prompt, task_id=task_id)\n```\n\n## 14. 如何外挂自己的动态工具\n\n这是 `tools_library` 最重要的用法。\n\n### 14.1 动态工具目录规则\n\n默认动态工具根目录是：\n\n```text\n<user_data_root>/tools_library/\n```\n\n也可以显式覆盖：\n\n```python\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    tools_dir=\"/path/to/my_agent_project/runtime/tools_library\",\n)\n```\n\n当前加载规则是：\n\n1. `tools_library/` 下每个一级子目录代表一个工具\n2. 每个工具目录顶层必须且只能有一个 `.py` 文件作为主工具文件\n3. 这个 `.py` 文件里必须只有一个公开工具类候选\n4. 这个类需要实现 `execute(...)` 或 `execute_async(...)`\n5. 推荐继承 `BaseTool`，但加载器当前真正强制的是“公开类 + execute/execute_async”\n6. 工具名优先取类属性 `name`，没有则回退到文件名\n7. 工具名不能和内置工具重名\n\n推荐目录结构：\n\n```text\n/path/to/my_agent_project/runtime/tools_library/\n└── echo_text/\n    └── echo_text.py\n```\n\n注意：\n\n- 工具目录顶层有多个 `.py` 文件会加载失败\n- 其他资源文件可以放进去\n- 辅助代码更推荐放在子目录里，避免顶层多个 `.py`\n\n### 14.2 一个最小外挂 tool 示例\n\n文件：\n\n```text\n/path/to/my_agent_project/runtime/tools_library/echo_text/echo_text.py\n```\n\n内容：\n\n```python\nfrom pathlib import Path\nfrom tool_server_lite.tools.file_tools import BaseTool, get_abs_path\n\n\nclass EchoTextTool(BaseTool):\n    name = \"echo_text\"\n\n    def execute(self, task_id: str, parameters: dict) -> dict:\n        text = str(parameters.get(\"text\") or \"\")\n        output_path = str(parameters.get(\"output_path\") or \"\").strip()\n\n        if output_path:\n            abs_path = get_abs_path(task_id, output_path)\n            abs_path.parent.mkdir(parents=True, exist_ok=True)\n            abs_path.write_text(text, encoding=\"utf-8\")\n\n        return {\n            \"status\": \"success\",\n            \"output\": text,\n            \"error\": \"\"\n        }\n```\n\n这里要点是：\n\n- `task_id` 就是当前 task 的 workspace 根目录\n- 相对路径应通过 `get_abs_path(task_id, relative_path)` 转成绝对路径\n\n### 14.3 只把 `.py` 放进去还不够，还要在 agent system 里声明\n\n动态工具被 runtime registry 扫描到之后，还要在你的 agent system YAML 里把它声明出来，LLM 才知道这个工具存在。\n\n#### 在 `level_0_tools.yaml` 中声明工具 schema\n\n```yaml\ntools:\n  echo_text:\n    level: 0\n    type: tool_call_agent\n    name: \"echo_text\"\n    description: \"回显文本，并可选写入当前 task 工作目录中的文件。\"\n    parameters:\n      type: \"object\"\n      properties:\n        text:\n          type: \"string\"\n          description: \"要输出的文本。\"\n        output_path:\n          type: \"string\"\n          description: \"可选。相对于当前 task 工作目录的输出文件路径。\"\n      required: [\"text\"]\n```\n\n#### 在 `level_3_agents.yaml` 中让 agent 看见它\n\n如果你的 agent 使用显式 `available_tools`：\n\n```yaml\ntools:\n  alpha_agent:\n    level: 3\n    type: llm_call_agent\n    name: \"alpha_agent\"\n    available_tools:\n      - file_read\n      - file_write\n      - echo_text\n      - final_output\n    prompts:\n      agent_responsibility: |\n        你是一个通用 AI 助手。\n      agent_workflow: |\n        阅读任务后，选择合适工具完成工作。\n```\n\n如果你的 agent 用的是 `available_tool_level` 自动收集对应 level 的工具，那么只要：\n\n- 你的工具在 `level_0_tools.yaml` 中是 `level: 0`\n- 这个 agent 会自动包含 level 0 工具\n\n就不需要在 `available_tools` 里逐个列。\n\n### 14.4 新增外挂 tool 之后如何让运行中的任务看到它\n\n你新增工具之后：\n\n- 对新启动的 task：通常直接可见\n- 对已经在运行中的 task：需要 `fresh()`\n\n例如：\n\n```python\nagent.fresh(\n    task_id=\"/path/to/my_agent_project/tasks/refactor_task\",\n    reason=\"installed new custom tool echo_text\",\n)\n```\n\n### 14.5 最容易踩的坑\n\n如果你发现工具“写了但调用不到”，优先检查：\n\n1. 工具目录顶层是否只有一个 `.py`\n2. 工具类是否是公开类，且实现了 `execute` 或 `execute_async`\n3. 工具 `name` 是否和 YAML 里的 `name` / tool key 对得上\n4. 目标 agent 是否真的能看到这个工具\n5. 运行中的 task 是否已经 `fresh()`\n\n## 15. Skills 的用法\n\n默认 skills 主库：\n\n```text\n~/.agent/skills/\n```\n\nSDK 会先把可见 skills 作为 `<available_skills>` 注入 system prompt。\n\n真正使用 skill 时：\n\n1. LLM 调用 `load_skill`\n2. skill 从 `skills_dir` 复制到 `<task_id>/.skills/<skill_name>/`\n3. `SKILL.md` 的内容注入当前上下文\n\n所以要区分两件事：\n\n- “当前 task 看得见哪些 skill”\n- “当前 task 已经加载了哪些 skill”\n\n如果你想改 skill 源库目录：\n\n```python\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    skills_dir=\"/path/to/my_agent_project/skills\",\n)\n```\n\n## 16. Hooks：如何在 SDK 外层做集成\n\n### 16.1 Tool Hooks\n\n你可以在工具调用前后挂钩：\n\n```python\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    tool_hooks=[\n        {\n            \"name\": \"observe-final-output\",\n            \"callback\": \"/abs/path/to/my_hooks.py:on_tool_event\",\n            \"when\": \"after\",\n            \"tool_names\": [\"final_output\"],\n            \"include_arguments\": False,\n            \"include_result\": True,\n            \"result_filters\": {\"status\": \"success\"}\n        }\n    ],\n)\n```\n\n当前支持的主要字段：\n\n- `name`\n- `callback`\n- `when`: `before` / `after` / `both`\n- `tool_names`\n- `include_arguments`\n- `include_result`\n- `argument_filters`\n- `result_filters`\n\n`callback` 可以是：\n\n- `\"/abs/path/to/file.py:function_name\"`\n- `\"python.module:function_name\"`\n\n### 16.2 Context Hooks\n\n你也可以在上下文构建后改写最终 prompt：\n\n```python\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    context_hooks=[\n        {\n            \"name\": \"rewrite-context\",\n            \"callback\": \"/abs/path/to/my_hooks.py:on_context\",\n            \"when\": \"after_build\"\n        }\n    ],\n)\n```\n\n当前 callback 可以返回：\n\n- 一个字符串：直接替换 `context_text`\n- 一个 dict：例如 `{\"context_text\": \"...\"}`\n\n## 17. 一个完整起步示例\n\n```python\nfrom infiagent import infiagent\n\n\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    default_agent_system=\"MyAgentSystem\",\n    default_agent_name=\"alpha_agent\",\n    thinking_enabled=True,\n    thinking_steps=30,\n    no_tool_retry_limit=7,\n)\n\n\ntask_id = \"/path/to/my_agent_project/tasks/plan_task\"\n\nresult = agent.run(\n    \"先阅读项目，再生成一份改造计划\",\n    task_id=task_id,\n)\nprint(result)\n\nsnapshot = agent.task_snapshot(task_id=task_id)\nprint(snapshot[\"latest_thinking\"])\n\nagent.add_message(\n    \"补充要求：优先保留现有目录结构。\",\n    task_id=task_id,\n    source=\"user\",\n    resume_if_needed=True,\n)\n```\n\n### 17.1 结构化模型配置示例\n\n如果你不想手写 `llm_config.yaml`，可以直接传 `model_profiles`：\n\n```python\nfrom infiagent import infiagent\n\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    model_profiles={\n        \"mode\": \"unified\",\n        \"unified\": {\n            \"provider\": \"openrouter\",\n            \"model\": \"openai/qwen/qwen3.5-plus-02-15\",\n            \"base_url\": \"https://openrouter.ai/api/v1\",\n            \"api_key\": \"sk-or-...\",\n            \"tool_choice\": \"auto\",\n        },\n        \"temperature\": 0,\n        \"max_context_window\": 500000,\n        \"timeout\": 600,\n        \"stream_timeout\": 30,\n        \"first_chunk_timeout\": 30,\n    },\n)\n```\n\n也支持 split 模式：\n\n```python\nagent = infiagent(\n    user_data_root=\"/path/to/my_agent_project/runtime\",\n    model_profiles={\n        \"mode\": \"split\",\n        \"main\": {\n            \"provider\": \"openrouter\",\n            \"model\": \"openai/qwen/qwen3.5-plus-02-15\",\n            \"base_url\": \"https://openrouter.ai/api/v1\",\n            \"api_key\": \"sk-or-...\",\n        },\n        \"thinking\": {\n            \"provider\": \"google_official\",\n            \"model\": \"gemini-2.5-flash\",\n            \"api_key\": \"your-google-key\",\n        },\n        \"read_figure\": {\n            \"provider\": \"openai_official\",\n            \"model\": \"gpt-4.1-mini\",\n            \"api_key\": \"sk-...\",\n        },\n    },\n)\n```\n\n## 18. 最后几条建议\n\n1. 不要直接修改 `site-packages/infiagent/...`\n\n- 升级后会丢\n- 也不利于迁移和复用\n\n2. 不要把所有长期实验都堆在默认 `~/mla_v3`\n\n- 先用默认目录拿样例\n- 再复制到自己的 `runtime/`\n- 让项目代码显式绑定自己的 `user_data_root`\n\n3. 如果你是 SDK 嵌入式使用者，优先把“项目目录”和“task workspace”分开设计\n\n- `runtime/` 管框架配置和状态\n- `tasks/<task_name>/` 管单个任务的工作文件\n\n4. 如果你要在生产代码里使用 async 版本，请把它当作“async 友好的同步封装”，而不是并发隔离框架\n\n- 需要并发时，优先自己加锁\n- 真正强隔离时，优先进程隔离\n\n5. 如果安装后发现 `~/mla_v3/tools_library/` 是空的，这是正常现象\n\n- 默认不会自动复制内置 Python tool 到这里\n- 这个目录本来就是留给你放自定义动态工具的\n"
  },
  {
    "path": "infiagent/__init__.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom .sdk import InfiAgent, infiagent\nfrom core.runtime_exceptions import InfiAgentRunError\nfrom utils.llm_config_builder import build_llm_config_from_profiles\n\n__all__ = [\"InfiAgent\", \"InfiAgentRunError\", \"infiagent\", \"build_llm_config_from_profiles\"]\n"
  },
  {
    "path": "infiagent/sdk.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nInfiAgent Python SDK。\n\n设计原则：\n- 实例化阶段只负责配置运行时环境\n- 具体任务在 run(..., task_id=...) 阶段绑定\n- user_data_root 一旦指定，conversation/share/stack/runtime 都跟随该根目录\n- skills 仍保持独立目录语义，不强制跟随 user_data_root\n\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport json\nimport hashlib\nfrom copy import deepcopy\nfrom datetime import datetime\nfrom functools import partial\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, List, Optional, Tuple\nimport yaml\n\nfrom core.agent_executor import AgentExecutor\nfrom core.event_handlers import StructuredEventHandler\nfrom core.hierarchy_manager import get_hierarchy_manager\nfrom core.runtime_exceptions import InfiAgentRunError\nfrom core.state_cleaner import clean_before_start\nfrom utils.config_loader import ConfigLoader\nfrom utils.llm_config_builder import build_llm_config_from_profiles\nfrom utils.runtime_control import is_task_running, request_fresh\nfrom utils.task_runtime import (\n    append_task_message,\n    get_task_share_paths,\n    launch_task_process,\n    list_known_tasks,\n    reset_task_state,\n    resume_task_with_fresh,\n)\nfrom utils.user_paths import (\n    get_user_agent_library_root,\n    get_user_config_dir,\n    get_user_conversations_dir,\n    get_user_data_root,\n    get_user_llm_config_path,\n    get_user_logs_dir,\n    get_user_runtime_dir,\n    get_task_file_prefix,\n    get_user_data_root,\n    get_user_skills_library_root,\n    get_user_tools_library_root,\n    runtime_env_scope,\n)\n\n\ndef _normalize_path(path: Optional[str]) -> Optional[str]:\n    if not path:\n        return None\n    return str(Path(path).expanduser().resolve())\n\n\ndef _as_root_dir(path: Optional[str], expected_leaf: Optional[str] = None) -> Optional[str]:\n    normalized = _normalize_path(path)\n    if not normalized:\n        return None\n    p = Path(normalized)\n    if expected_leaf and p.name == expected_leaf:\n        return str(p.parent)\n    return normalized\n\n\ndef _materialize_inline_llm_config(\n    *,\n    user_data_root: Optional[str],\n    llm_config: Dict[str, Any],\n) -> str:\n    root = Path(user_data_root).expanduser().resolve() if user_data_root else get_user_data_root()\n    cfg_root = root / \"runtime\" / \"sdk_llm_configs\"\n    cfg_root.mkdir(parents=True, exist_ok=True)\n    raw = yaml.safe_dump(llm_config or {}, allow_unicode=True, sort_keys=False)\n    digest = hashlib.md5(raw.encode(\"utf-8\")).hexdigest()[:12]\n    path = cfg_root / f\"llm_config_{digest}.yaml\"\n    path.write_text(raw, encoding=\"utf-8\")\n    return str(path)\n\n\nclass InfiAgent:\n    def __init__(\n        self,\n        workspace: Optional[str] = None,\n        user_data_root: Optional[str] = None,\n        llm_config_path: Optional[str] = None,\n        llm_config: Optional[Dict[str, Any]] = None,\n        model_profiles: Optional[Dict[str, Any]] = None,\n        library_dir: Optional[str] = None,\n        agent_library_dir: Optional[str] = None,\n        skills_dir: Optional[str] = None,\n        tools_dir: Optional[str] = None,\n        default_agent_system: Optional[str] = None,\n        default_agent_name: Optional[str] = None,\n        action_window_steps: Optional[int] = None,\n        thinking_interval: Optional[int] = None,\n        thinking_enabled: Optional[bool] = None,\n        thinking_steps: Optional[int] = None,\n        no_tool_retry_limit: Optional[int] = None,\n        user_history_compress_threshold_tokens: Optional[int] = None,\n        user_history_recent_items: Optional[int] = None,\n        max_turns: Optional[int] = None,\n        fresh_enabled: Optional[bool] = None,\n        fresh_interval_sec: Optional[int] = None,\n        mcp_servers: Optional[List[Dict[str, Any]]] = None,\n        tool_hooks: Optional[List[Dict[str, Any]]] = None,\n        context_hooks: Optional[List[Dict[str, Any]]] = None,\n        visible_skills: Optional[List[str]] = None,\n        seed_builtin_resources: bool = True,\n        direct_tools: bool = True,\n    ):\n        if llm_config_path and (llm_config is not None or model_profiles is not None):\n            raise ValueError(\"llm_config_path 与 llm_config/model_profiles 只能二选一\")\n\n        self.default_agent_system = str(default_agent_system or \"OpenCowork\").strip() or \"OpenCowork\"\n        self.default_agent_name = str(default_agent_name or \"alpha_agent\").strip() or \"alpha_agent\"\n        self.direct_tools = bool(direct_tools)\n\n        # `workspace` 仅保留为兼容旧构造参数；新语义要求在 run(...) 时显式提供 task_id。\n        self.legacy_workspace = _normalize_path(workspace)\n\n        explicit_agent_library_root = _as_root_dir(agent_library_dir or library_dir, \"agent_library\")\n        resolved_user_data_root = _normalize_path(user_data_root) or explicit_agent_library_root\n        inline_llm_config = None\n        if model_profiles is not None:\n            inline_llm_config = build_llm_config_from_profiles(model_profiles)\n        elif llm_config is not None:\n            inline_llm_config = dict(llm_config)\n        resolved_llm_config_path = _normalize_path(llm_config_path)\n        if inline_llm_config is not None:\n            resolved_llm_config_path = _materialize_inline_llm_config(\n                user_data_root=resolved_user_data_root,\n                llm_config=inline_llm_config,\n            )\n\n        self.runtime_env_overrides: Dict[str, Any] = {}\n        if resolved_user_data_root:\n            self.runtime_env_overrides[\"MLA_USER_DATA_ROOT\"] = resolved_user_data_root\n        if resolved_llm_config_path:\n            self.runtime_env_overrides[\"MLA_LLM_CONFIG_PATH\"] = resolved_llm_config_path\n        if explicit_agent_library_root:\n            self.runtime_env_overrides[\"MLA_AGENT_LIBRARY_DIR\"] = explicit_agent_library_root\n        if skills_dir:\n            self.runtime_env_overrides[\"MLA_SKILLS_LIBRARY_DIR\"] = _normalize_path(skills_dir)\n        if tools_dir:\n            self.runtime_env_overrides[\"MLA_TOOLS_LIBRARY_DIR\"] = _normalize_path(tools_dir)\n        if action_window_steps is not None:\n            self.runtime_env_overrides[\"MLA_ACTION_WINDOW_STEPS\"] = str(max(1, int(action_window_steps)))\n        if thinking_interval is not None:\n            self.runtime_env_overrides[\"MLA_THINKING_INTERVAL\"] = str(max(1, int(thinking_interval)))\n        if thinking_enabled is not None:\n            self.runtime_env_overrides[\"MLA_THINKING_ENABLED\"] = \"true\" if thinking_enabled else \"false\"\n        if thinking_steps is not None:\n            self.runtime_env_overrides[\"MLA_THINKING_STEPS\"] = str(max(1, int(thinking_steps)))\n        if no_tool_retry_limit is not None:\n            self.runtime_env_overrides[\"MLA_NO_TOOL_RETRY_LIMIT\"] = str(max(1, int(no_tool_retry_limit)))\n        if user_history_compress_threshold_tokens is not None:\n            self.runtime_env_overrides[\"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\"] = str(max(0, int(user_history_compress_threshold_tokens)))\n        if user_history_recent_items is not None:\n            self.runtime_env_overrides[\"MLA_USER_HISTORY_RECENT_ITEMS\"] = str(max(0, int(user_history_recent_items)))\n        if max_turns is not None:\n            self.runtime_env_overrides[\"MLA_MAX_TURNS\"] = str(max(1, int(max_turns)))\n        if fresh_enabled is not None:\n            self.runtime_env_overrides[\"MLA_FRESH_ENABLED\"] = \"true\" if fresh_enabled else \"false\"\n        if fresh_interval_sec is not None:\n            self.runtime_env_overrides[\"MLA_FRESH_INTERVAL_SEC\"] = str(max(0, int(fresh_interval_sec)))\n        if mcp_servers is not None:\n            self.runtime_env_overrides[\"MLA_MCP_CONFIG_JSON\"] = json.dumps({\"servers\": mcp_servers}, ensure_ascii=False)\n        if tool_hooks is not None:\n            self.runtime_env_overrides[\"MLA_TOOL_HOOKS_JSON\"] = json.dumps(tool_hooks, ensure_ascii=False)\n        if context_hooks is not None:\n            self.runtime_env_overrides[\"MLA_CONTEXT_HOOKS_JSON\"] = json.dumps(context_hooks, ensure_ascii=False)\n        if visible_skills is not None:\n            self.runtime_env_overrides[\"MLA_VISIBLE_SKILLS_JSON\"] = json.dumps(visible_skills, ensure_ascii=False)\n        self.runtime_env_overrides[\"MLA_SEED_BUILTIN_RESOURCES\"] = \"true\" if seed_builtin_resources else \"false\"\n\n        self.user_data_root = resolved_user_data_root\n        self.llm_config_path = resolved_llm_config_path\n        self.inline_llm_config = inline_llm_config\n        self.model_profiles = deepcopy(model_profiles) if model_profiles is not None else None\n        self.agent_library_root = explicit_agent_library_root\n        self.skills_dir = _normalize_path(skills_dir)\n        self.tools_dir = _normalize_path(tools_dir)\n        self.action_window_steps = max(1, int(action_window_steps)) if action_window_steps is not None else None\n        self.thinking_interval = max(1, int(thinking_interval)) if thinking_interval is not None else None\n        self.thinking_enabled = bool(thinking_enabled) if thinking_enabled is not None else None\n        self.thinking_steps = max(1, int(thinking_steps)) if thinking_steps is not None else None\n        self.no_tool_retry_limit = max(1, int(no_tool_retry_limit)) if no_tool_retry_limit is not None else None\n        self.user_history_compress_threshold_tokens = max(0, int(user_history_compress_threshold_tokens)) if user_history_compress_threshold_tokens is not None else None\n        self.user_history_recent_items = max(0, int(user_history_recent_items)) if user_history_recent_items is not None else None\n        self.max_turns = max(1, int(max_turns)) if max_turns is not None else None\n        self.fresh_enabled = fresh_enabled if fresh_enabled is not None else None\n        self.fresh_interval_sec = max(0, int(fresh_interval_sec)) if fresh_interval_sec is not None else None\n        self.mcp_servers = mcp_servers\n        self.tool_hooks = tool_hooks\n        self.context_hooks = context_hooks\n        self.visible_skills = [str(item).strip() for item in visible_skills if str(item).strip()] if visible_skills is not None else None\n        self.seed_builtin_resources = bool(seed_builtin_resources)\n\n    def _runtime_scope(self, extra_overrides: Optional[Dict[str, Any]] = None):\n        merged = dict(self.runtime_env_overrides)\n        if extra_overrides:\n            merged.update(extra_overrides)\n        return runtime_env_scope(merged)\n\n    def _resolve_task_id(\n        self,\n        *,\n        task_id: Optional[str] = None,\n        workspace: Optional[str] = None,\n        required: bool = True,\n    ) -> Optional[str]:\n        raw_task_id = task_id or workspace\n        if not raw_task_id and not required:\n            return None\n        if not raw_task_id:\n            raise ValueError(\"必须显式提供 task_id。SDK 实例化阶段不再绑定 workspace。\")\n        return str(Path(raw_task_id).expanduser().resolve())\n\n    def _build_launch_config(self) -> Dict[str, Any]:\n        config: Dict[str, Any] = {}\n        if self.user_data_root:\n            config[\"user_data_root\"] = self.user_data_root\n        if self.llm_config_path:\n            config[\"llm_config_path\"] = self.llm_config_path\n        if self.agent_library_root:\n            config[\"agent_library_dir\"] = self.agent_library_root\n        if self.skills_dir:\n            config[\"skills_dir\"] = self.skills_dir\n        if self.tools_dir:\n            config[\"tools_dir\"] = self.tools_dir\n        if self.action_window_steps is not None:\n            config[\"action_window_steps\"] = self.action_window_steps\n        if self.thinking_interval is not None:\n            config[\"thinking_interval\"] = self.thinking_interval\n        if self.thinking_enabled is not None:\n            config[\"thinking_enabled\"] = self.thinking_enabled\n        if self.thinking_steps is not None:\n            config[\"thinking_steps\"] = self.thinking_steps\n        if self.no_tool_retry_limit is not None:\n            config[\"no_tool_retry_limit\"] = self.no_tool_retry_limit\n        if self.user_history_compress_threshold_tokens is not None:\n            config[\"user_history_compress_threshold_tokens\"] = self.user_history_compress_threshold_tokens\n        if self.user_history_recent_items is not None:\n            config[\"user_history_recent_items\"] = self.user_history_recent_items\n        if self.max_turns is not None:\n            config[\"max_turns\"] = self.max_turns\n        if self.fresh_enabled is not None:\n            config[\"fresh_enabled\"] = self.fresh_enabled\n        if self.fresh_interval_sec is not None:\n            config[\"fresh_interval_sec\"] = self.fresh_interval_sec\n        if self.mcp_servers is not None:\n            config[\"mcp_servers\"] = self.mcp_servers\n        if self.tool_hooks is not None:\n            config[\"tool_hooks\"] = self.tool_hooks\n        if self.context_hooks is not None:\n            config[\"context_hooks\"] = self.context_hooks\n        if self.visible_skills is not None:\n            config[\"visible_skills\"] = self.visible_skills\n        config[\"seed_builtin_resources\"] = self.seed_builtin_resources\n        return config\n\n    def _build_sdk_event_handler(\n        self,\n        *,\n        collect_events: bool = False,\n        on_event: Optional[Callable[[Dict[str, Any]], None]] = None,\n    ) -> Tuple[List[StructuredEventHandler], Optional[List[Dict[str, Any]]]]:\n        collected_events: Optional[List[Dict[str, Any]]] = [] if collect_events else None\n        if not collect_events and on_event is None:\n            return [], collected_events\n        return [\n            StructuredEventHandler(\n                callback=on_event,\n                collector=collected_events,\n            )\n        ], collected_events\n\n    def _attach_optional_run_artifacts(\n        self,\n        payload: Dict[str, Any],\n        *,\n        task_id: str,\n        collected_events: Optional[List[Dict[str, Any]]] = None,\n        collect_events: bool = False,\n        include_trace: bool = False,\n    ) -> Dict[str, Any]:\n        enriched = dict(payload)\n        if collect_events:\n            enriched[\"events\"] = list(collected_events or [])\n        if include_trace:\n            enriched[\"trace\"] = self.task_trace(task_id=task_id)\n        return enriched\n\n    def run(\n        self,\n        user_input: str,\n        *,\n        task_id: str,\n        agent_system: Optional[str] = None,\n        agent_name: Optional[str] = None,\n        force_new: bool = False,\n        workspace: Optional[str] = None,\n        collect_events: bool = False,\n        on_event: Optional[Callable[[Dict[str, Any]], None]] = None,\n        include_trace: bool = False,\n        raise_on_error: bool = False,\n        stream_llm_tokens: bool = False,\n        thinking_enabled: Optional[bool] = None,\n        thinking_steps: Optional[int] = None,\n        no_tool_retry_limit: Optional[int] = None,\n        visible_skills: Optional[List[str]] = None,\n        user_history_compress_threshold_tokens: Optional[int] = None,\n        user_history_recent_items: Optional[int] = None,\n        max_turns: Optional[int] = None,\n    ) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id, workspace=workspace)\n        target_agent_system = agent_system or self.default_agent_system\n        target_agent_name = agent_name or self.default_agent_name\n\n        extra_runtime_overrides: Dict[str, Any] = {}\n        if thinking_enabled is not None:\n            extra_runtime_overrides[\"MLA_THINKING_ENABLED\"] = \"true\" if thinking_enabled else \"false\"\n        if thinking_steps is not None:\n            extra_runtime_overrides[\"MLA_THINKING_STEPS\"] = str(max(1, int(thinking_steps)))\n        if no_tool_retry_limit is not None:\n            extra_runtime_overrides[\"MLA_NO_TOOL_RETRY_LIMIT\"] = str(max(1, int(no_tool_retry_limit)))\n        if visible_skills is not None:\n            extra_runtime_overrides[\"MLA_VISIBLE_SKILLS_JSON\"] = json.dumps(\n                [str(item).strip() for item in visible_skills if str(item).strip()],\n                ensure_ascii=False,\n            )\n        if user_history_compress_threshold_tokens is not None:\n            extra_runtime_overrides[\"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\"] = str(\n                max(0, int(user_history_compress_threshold_tokens))\n            )\n        if user_history_recent_items is not None:\n            extra_runtime_overrides[\"MLA_USER_HISTORY_RECENT_ITEMS\"] = str(\n                max(0, int(user_history_recent_items))\n            )\n        if max_turns is not None:\n            extra_runtime_overrides[\"MLA_MAX_TURNS\"] = str(max(1, int(max_turns)))\n\n        with self._runtime_scope(extra_runtime_overrides or None):\n            extra_event_handlers, collected_events = self._build_sdk_event_handler(\n                collect_events=collect_events,\n                on_event=on_event,\n            )\n            if is_task_running(target_task_id):\n                busy_result = {\n                    \"status\": \"busy\",\n                    \"task_id\": target_task_id,\n                    \"output\": \"\",\n                    \"error\": f\"任务已在运行: {target_task_id}\",\n                }\n                return self._attach_optional_run_artifacts(\n                    busy_result,\n                    task_id=target_task_id,\n                    collected_events=collected_events,\n                    collect_events=collect_events,\n                    include_trace=include_trace,\n                )\n            config_loader = ConfigLoader(target_agent_system)\n            hierarchy_manager = get_hierarchy_manager(target_task_id)\n\n            if force_new:\n                context = hierarchy_manager._load_context()\n                context[\"current\"] = {\n                    \"instructions\": [],\n                    \"hierarchy\": {},\n                    \"agents_status\": {},\n                    \"start_time\": datetime.now().isoformat(),\n                    \"last_updated\": datetime.now().isoformat(),\n                }\n                hierarchy_manager._save_context(context)\n                hierarchy_manager._save_stack([])\n            else:\n                clean_before_start(target_task_id, user_input)\n\n            hierarchy_manager.start_new_instruction(user_input)\n\n            agent_config = config_loader.get_tool_config(target_agent_name)\n            if agent_config.get(\"type\") != \"llm_call_agent\":\n                raise ValueError(f\"{target_agent_name} 不是一个 LLM Agent\")\n            agent = AgentExecutor(\n                agent_name=target_agent_name,\n                agent_config=agent_config,\n                config_loader=config_loader,\n                hierarchy_manager=hierarchy_manager,\n                direct_tools=self.direct_tools,\n                extra_event_handlers=extra_event_handlers,\n                exit_on_error=False,\n                raise_on_error=raise_on_error,\n                stream_llm_tokens=stream_llm_tokens,\n            )\n            try:\n                result = agent.run(target_task_id, user_input)\n            except InfiAgentRunError as exc:\n                exc.events = list(collected_events or exc.events or [])\n                if include_trace:\n                    exc.trace = self.task_trace(task_id=target_task_id)\n                raise\n\n            enriched_result = self._attach_optional_run_artifacts(\n                result,\n                task_id=target_task_id,\n                collected_events=collected_events,\n                collect_events=collect_events,\n                include_trace=include_trace,\n            )\n            if raise_on_error and enriched_result.get(\"status\") == \"error\":\n                raise InfiAgentRunError.from_result(\n                    enriched_result,\n                    task_id=target_task_id,\n                    agent_name=target_agent_name,\n                    stage=\"run\",\n                    events=enriched_result.get(\"events\"),\n                    trace=enriched_result.get(\"trace\"),\n                )\n            return enriched_result\n\n    def fresh(\n        self,\n        *,\n        task_id: str,\n        reason: str = \"\",\n    ) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id)\n        with self._runtime_scope():\n            if is_task_running(target_task_id):\n                request_fresh(reason=reason, task_id=target_task_id)\n                output = f\"已向运行中的任务发送 fresh 请求: {target_task_id}\"\n            else:\n                ok, msg = resume_task_with_fresh(\n                    task_id=target_task_id,\n                    reason=reason,\n                    fallback_agent_system=self.default_agent_system,\n                    direct_tools=self.direct_tools,\n                    env_overrides=self.runtime_env_overrides,\n                )\n                if not ok:\n                    return {\n                        \"status\": \"error\",\n                        \"task_id\": target_task_id,\n                        \"output\": \"\",\n                        \"error\": msg,\n                    }\n                output = msg\n            return {\n                \"status\": \"success\",\n                \"task_id\": target_task_id,\n                \"output\": output,\n            }\n\n    def add_message(\n        self,\n        message: str,\n        *,\n        task_id: str,\n        source: str = \"agent\",\n        resume_if_needed: bool = False,\n        agent_system: Optional[str] = None,\n    ) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id)\n        with self._runtime_scope():\n            ok, payload = append_task_message(\n                task_id=target_task_id,\n                message=message,\n                source=source,\n                resume_if_needed=resume_if_needed,\n                fallback_agent_system=agent_system or self.default_agent_system,\n                direct_tools=self.direct_tools,\n                env_overrides=self.runtime_env_overrides,\n            )\n            if not ok:\n                return {\n                    \"status\": \"error\",\n                    \"task_id\": target_task_id,\n                    \"output\": \"\",\n                    \"error\": payload.get(\"error\") or \"add_message failed\",\n                }\n            return {\n                \"status\": \"success\",\n                **payload,\n            }\n\n    def start_background_task(\n        self,\n        *,\n        task_id: str,\n        user_input: str,\n        agent_system: Optional[str] = None,\n        agent_name: Optional[str] = None,\n        force_new: bool = False,\n        direct_tools: Optional[bool] = None,\n        max_turns: Optional[int] = None,\n        config: Optional[Dict[str, Any]] = None,\n    ) -> Dict[str, Any]:\n        merged_config = self._build_launch_config()\n        if max_turns is not None:\n            merged_config[\"max_turns\"] = max(1, int(max_turns))\n        if config:\n            merged_config.update(config)\n        with self._runtime_scope():\n            ok, payload = launch_task_process(\n                task_id=self._resolve_task_id(task_id=task_id),\n                user_input=user_input,\n                agent_system=agent_system or self.default_agent_system,\n                agent_name=agent_name or self.default_agent_name,\n                force_new=force_new,\n                direct_tools=self.direct_tools if direct_tools is None else bool(direct_tools),\n                config=merged_config,\n            )\n        if not ok:\n            return {\"status\": \"error\", **payload}\n        return {\"status\": \"success\", **payload}\n\n    def task_share_context_path(self, *, task_id: str) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return {\n                \"status\": \"success\",\n                **get_task_share_paths(self._resolve_task_id(task_id=task_id)),\n            }\n\n    def list_task_ids(self, *, only_running: bool = False) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return {\n                \"status\": \"success\",\n                **list_known_tasks(only_running=only_running),\n            }\n\n    def describe_runtime(self) -> Dict[str, Any]:\n        with self._runtime_scope():\n            return {\n                \"status\": \"success\",\n                \"user_data_root\": str(get_user_data_root()),\n                \"config_dir\": str(get_user_config_dir()),\n                \"llm_config_path\": str(get_user_llm_config_path()),\n                \"agent_library_dir\": str(get_user_agent_library_root()),\n                \"skills_dir\": str(get_user_skills_library_root()),\n                \"tools_dir\": str(get_user_tools_library_root()),\n                \"conversations_dir\": str(get_user_conversations_dir()),\n                \"logs_dir\": str(get_user_logs_dir()),\n                \"runtime_dir\": str(get_user_runtime_dir()),\n                \"app_config_path\": str(get_user_config_dir() / \"app_config.json\"),\n                \"default_agent_system\": self.default_agent_system,\n                \"default_agent_name\": self.default_agent_name,\n                \"direct_tools\": self.direct_tools,\n                \"seed_builtin_resources\": self.seed_builtin_resources,\n                \"max_turns\": self.max_turns if self.max_turns is not None else 100000,\n            }\n\n    def list_agent_systems(self) -> Dict[str, Any]:\n        with self._runtime_scope():\n            root = get_user_agent_library_root()\n            systems = []\n            if root.exists():\n                for child in sorted(root.iterdir(), key=lambda item: item.name.lower()):\n                    if not child.is_dir() or child.name.startswith(\".\"):\n                        continue\n                    agent_names: List[str] = []\n                    agents_path = child / \"level_3_agents.yaml\"\n                    if agents_path.exists():\n                        try:\n                            payload = yaml.safe_load(agents_path.read_text(encoding=\"utf-8\")) or {}\n                            tools = payload.get(\"tools\", {}) if isinstance(payload, dict) else {}\n                            if isinstance(tools, dict):\n                                for name, config in tools.items():\n                                    if not isinstance(config, dict):\n                                        continue\n                                    if config.get(\"type\") == \"llm_call_agent\":\n                                        agent_names.append(str(config.get(\"name\") or name))\n                        except Exception:\n                            agent_names = []\n                    systems.append({\n                        \"name\": child.name,\n                        \"path\": str(child),\n                        \"has_general_prompts\": (child / \"general_prompts.yaml\").exists(),\n                        \"has_level_0_tools\": (child / \"level_0_tools.yaml\").exists(),\n                        \"agent_names\": sorted(set(agent_names)),\n                    })\n            return {\n                \"status\": \"success\",\n                \"agent_systems\": systems,\n            }\n\n    def task_snapshot(self, *, task_id: str) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id)\n        with self._runtime_scope():\n            paths = get_task_share_paths(target_task_id)\n            share_context_path = Path(paths[\"share_context_path\"])\n            data: Dict[str, Any] = {}\n            if share_context_path.exists():\n                try:\n                    data = json.loads(share_context_path.read_text(encoding=\"utf-8\"))\n                except Exception:\n                    data = {}\n\n            current = data.get(\"current\", {}) if isinstance(data, dict) else {}\n            runtime_meta = data.get(\"runtime\", {}) if isinstance(data, dict) else {}\n            history = data.get(\"history\", []) if isinstance(data, dict) else []\n            instructions = current.get(\"instructions\", []) if isinstance(current, dict) else []\n            agents_status = current.get(\"agents_status\", {}) if isinstance(current, dict) else {}\n\n            latest_thinking = \"\"\n            latest_thinking_at = \"\"\n            last_final_output = \"\"\n            last_final_output_at = \"\"\n\n            agent_infos: List[Dict[str, Any]] = []\n            if isinstance(agents_status, dict):\n                agent_infos.extend([item for item in agents_status.values() if isinstance(item, dict)])\n            if isinstance(history, list):\n                for entry in history:\n                    if not isinstance(entry, dict):\n                        continue\n                    archived_agents = entry.get(\"agents_status\", {})\n                    if isinstance(archived_agents, dict):\n                        agent_infos.extend([item for item in archived_agents.values() if isinstance(item, dict)])\n\n            for agent_info in agent_infos:\n                if not isinstance(agent_info, dict):\n                    continue\n                thinking_at = str(agent_info.get(\"thinking_updated_at\") or \"\")\n                if thinking_at >= latest_thinking_at and agent_info.get(\"latest_thinking\"):\n                    latest_thinking = str(agent_info.get(\"latest_thinking\") or \"\")\n                    latest_thinking_at = thinking_at\n                final_at = str(agent_info.get(\"end_time\") or \"\")\n                if final_at >= last_final_output_at and agent_info.get(\"final_output\"):\n                    last_final_output = str(agent_info.get(\"final_output\") or \"\")\n                    last_final_output_at = final_at\n\n            return {\n                \"status\": \"success\",\n                \"task_id\": target_task_id,\n                \"running\": is_task_running(target_task_id),\n                \"share_context_path\": paths[\"share_context_path\"],\n                \"stack_path\": paths[\"stack_path\"],\n                \"instruction_count\": len(instructions) if isinstance(instructions, list) else 0,\n                \"latest_instruction\": instructions[-1] if isinstance(instructions, list) and instructions else None,\n                \"history_count\": len(history) if isinstance(history, list) else 0,\n                \"last_updated\": str(current.get(\"last_updated\") or \"\"),\n                \"runtime\": runtime_meta if isinstance(runtime_meta, dict) else {},\n                \"latest_thinking\": latest_thinking,\n                \"latest_thinking_at\": latest_thinking_at,\n                \"last_final_output\": last_final_output,\n                \"last_final_output_at\": last_final_output_at,\n            }\n\n    def task_trace(\n        self,\n        *,\n        task_id: str,\n        include_render_history: bool = False,\n        include_system_prompt: bool = False,\n    ) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id)\n        with self._runtime_scope():\n            conversations_dir = get_user_conversations_dir()\n            prefix = get_task_file_prefix(target_task_id)\n            agent_traces: List[Dict[str, Any]] = []\n\n            for path in sorted(conversations_dir.glob(f\"{prefix}_*_actions.json\")):\n                try:\n                    data = json.loads(path.read_text(encoding=\"utf-8\"))\n                except Exception as e:\n                    agent_traces.append({\n                        \"path\": str(path),\n                        \"load_error\": str(e),\n                    })\n                    continue\n\n                trace_item = {\n                    \"path\": str(path),\n                    \"agent_id\": str(data.get(\"agent_id\") or \"\"),\n                    \"agent_name\": str(data.get(\"agent_name\") or \"\"),\n                    \"task_input\": str(data.get(\"task_input\") or \"\"),\n                    \"current_turn\": int(data.get(\"current_turn\") or 0),\n                    \"tool_call_counter\": int(data.get(\"tool_call_counter\") or 0),\n                    \"llm_turn_counter\": int(data.get(\"llm_turn_counter\") or 0),\n                    \"latest_thinking\": str(data.get(\"latest_thinking\") or \"\"),\n                    \"pending_tools\": data.get(\"pending_tools\") or [],\n                    \"action_history_fact\": data.get(\"action_history_fact\") or data.get(\"action_history\") or [],\n                    \"last_updated\": str(data.get(\"last_updated\") or \"\"),\n                }\n                if include_render_history:\n                    trace_item[\"action_history\"] = data.get(\"action_history\") or []\n                if include_system_prompt:\n                    trace_item[\"system_prompt\"] = str(data.get(\"system_prompt\") or \"\")\n                agent_traces.append(trace_item)\n\n            debug_path = conversations_dir / f\"{prefix}_llm_debug.jsonl\"\n            paths = get_task_share_paths(target_task_id)\n            return {\n                \"status\": \"success\",\n                \"task_id\": target_task_id,\n                \"share_context_path\": paths[\"share_context_path\"],\n                \"stack_path\": paths[\"stack_path\"],\n                \"agent_trace_count\": len(agent_traces),\n                \"agent_traces\": agent_traces,\n                \"llm_debug_path\": str(debug_path) if debug_path.exists() else \"\",\n            }\n\n    def reset_task(\n        self,\n        *,\n        task_id: str,\n        preserve_history: bool = True,\n        kill_background_processes: bool = True,\n        reason: str = \"\",\n    ) -> Dict[str, Any]:\n        target_task_id = self._resolve_task_id(task_id=task_id)\n        with self._runtime_scope():\n            ok, payload = reset_task_state(\n                task_id=target_task_id,\n                preserve_history=preserve_history,\n                kill_background_processes=kill_background_processes,\n                reason=reason,\n            )\n        if not ok:\n            return {\"status\": \"error\", \"task_id\": target_task_id, **payload}\n        return {\"status\": \"success\", **payload}\n\n    async def run_async(\n        self,\n        user_input: str,\n        *,\n        task_id: str,\n        agent_system: Optional[str] = None,\n        agent_name: Optional[str] = None,\n        force_new: bool = False,\n        workspace: Optional[str] = None,\n        collect_events: bool = False,\n        on_event: Optional[Callable[[Dict[str, Any]], None]] = None,\n        include_trace: bool = False,\n        raise_on_error: bool = False,\n        stream_llm_tokens: bool = False,\n        thinking_enabled: Optional[bool] = None,\n        thinking_steps: Optional[int] = None,\n        no_tool_retry_limit: Optional[int] = None,\n        visible_skills: Optional[List[str]] = None,\n        user_history_compress_threshold_tokens: Optional[int] = None,\n        user_history_recent_items: Optional[int] = None,\n        max_turns: Optional[int] = None,\n    ) -> Dict[str, Any]:\n        fn = partial(\n            self.run,\n            user_input,\n            task_id=task_id,\n            agent_system=agent_system,\n            agent_name=agent_name,\n            force_new=force_new,\n            workspace=workspace,\n            collect_events=collect_events,\n            on_event=on_event,\n            include_trace=include_trace,\n            raise_on_error=raise_on_error,\n            stream_llm_tokens=stream_llm_tokens,\n            thinking_enabled=thinking_enabled,\n            thinking_steps=thinking_steps,\n            no_tool_retry_limit=no_tool_retry_limit,\n            visible_skills=visible_skills,\n            user_history_compress_threshold_tokens=user_history_compress_threshold_tokens,\n            user_history_recent_items=user_history_recent_items,\n            max_turns=max_turns,\n        )\n        return await asyncio.to_thread(fn)\n\n    async def fresh_async(self, *, task_id: str, reason: str = \"\") -> Dict[str, Any]:\n        return await asyncio.to_thread(self.fresh, task_id=task_id, reason=reason)\n\n    async def add_message_async(\n        self,\n        message: str,\n        *,\n        task_id: str,\n        source: str = \"agent\",\n        resume_if_needed: bool = False,\n        agent_system: Optional[str] = None,\n    ) -> Dict[str, Any]:\n        return await asyncio.to_thread(\n            self.add_message,\n            message,\n            task_id=task_id,\n            source=source,\n            resume_if_needed=resume_if_needed,\n            agent_system=agent_system,\n        )\n\n    async def start_background_task_async(\n        self,\n        *,\n        task_id: str,\n        user_input: str,\n        agent_system: Optional[str] = None,\n        agent_name: Optional[str] = None,\n        force_new: bool = False,\n        direct_tools: Optional[bool] = None,\n        max_turns: Optional[int] = None,\n        config: Optional[Dict[str, Any]] = None,\n    ) -> Dict[str, Any]:\n        return await asyncio.to_thread(\n            self.start_background_task,\n            task_id=task_id,\n            user_input=user_input,\n            agent_system=agent_system,\n            agent_name=agent_name,\n            force_new=force_new,\n            direct_tools=direct_tools,\n            max_turns=max_turns,\n            config=config,\n        )\n\n    async def task_share_context_path_async(self, *, task_id: str) -> Dict[str, Any]:\n        return await asyncio.to_thread(self.task_share_context_path, task_id=task_id)\n\n    async def list_task_ids_async(self, *, only_running: bool = False) -> Dict[str, Any]:\n        return await asyncio.to_thread(self.list_task_ids, only_running=only_running)\n\n    async def describe_runtime_async(self) -> Dict[str, Any]:\n        return await asyncio.to_thread(self.describe_runtime)\n\n    async def list_agent_systems_async(self) -> Dict[str, Any]:\n        return await asyncio.to_thread(self.list_agent_systems)\n\n    async def task_snapshot_async(self, *, task_id: str) -> Dict[str, Any]:\n        return await asyncio.to_thread(self.task_snapshot, task_id=task_id)\n\n    async def task_trace_async(\n        self,\n        *,\n        task_id: str,\n        include_render_history: bool = False,\n        include_system_prompt: bool = False,\n    ) -> Dict[str, Any]:\n        return await asyncio.to_thread(\n            self.task_trace,\n            task_id=task_id,\n            include_render_history=include_render_history,\n            include_system_prompt=include_system_prompt,\n        )\n\n    async def reset_task_async(\n        self,\n        *,\n        task_id: str,\n        preserve_history: bool = True,\n        kill_background_processes: bool = True,\n        reason: str = \"\",\n    ) -> Dict[str, Any]:\n        return await asyncio.to_thread(\n            self.reset_task,\n            task_id=task_id,\n            preserve_history=preserve_history,\n            kill_background_processes=kill_background_processes,\n            reason=reason,\n        )\n\n\ndef infiagent(**kwargs) -> InfiAgent:\n    return InfiAgent(**kwargs)\n"
  },
  {
    "path": "marketplace_server/README.md",
    "content": "# Marketplace Server (FastAPI)\n\n该服务提供一个非常轻量的 “Skills + Agent Systems 市场”：\n\n- Skills 来源：仓库根目录 `skills_libraru/`\n- Agent Systems 来源：仓库根目录 `config/agent_library/`\n- 支持：列表、搜索、按下载量/更新时间排序、zip 下载\n\n## 运行\n\n```bash\npython3 -m venv .venv && source .venv/bin/activate\n# 默认无第三方依赖（兼容 CentOS7 的 Python 3.6+）\npython3 marketplace_server/app.py --host 0.0.0.0 --port 18080\n```\n\n## 部署到服务器（推荐：systemd + nginx）\n\n假设你把本仓库放到 `/opt/infiagent-market`（里面包含 `skills_libraru/` 与 `config/agent_library/`）：\n\n```bash\ncd /opt/infiagent-market\npython3 -m venv .venv\nsource .venv/bin/activate\n# 默认无第三方依赖（兼容 CentOS7 的 Python 3.6+）\n```\n\n- systemd：\n  - 复制 `marketplace_server/infiagent-market.service` 到 `/etc/systemd/system/`\n  - `systemctl daemon-reload && systemctl enable --now infiagent-market`\n- nginx：\n  - 复制 `marketplace_server/nginx_infiagent_market.conf` 到 `/etc/nginx/conf.d/`\n  - `nginx -t && systemctl reload nginx`\n\n然后在桌面端 Settings → Environment 填入市场地址，例如 `http://<你的服务器IP>`。\n\n## API\n\n- `GET /api/v1/health`\n- `GET /api/v1/index`\n- `GET /api/v1/skills/{name}/download`\n- `GET /api/v1/agent-systems/{name}/download`\n- `GET /admin`（上传管理界面）\n- `POST /api/v1/admin/upload-skill`（zip 上传）\n- `POST /api/v1/admin/upload-agent-system`（zip 上传）\n\n## 配置\n\n可选环境变量：\n\n- `MARKET_SKILLS_DIR`: skills 目录（默认 `../skills_libraru`）\n- `MARKET_AGENT_LIBRARY_DIR`: agent_library 目录（默认 `../config/agent_library`）\n- `MARKET_ADMIN_TOKEN`: 可选的管理 token。设置后访问管理页需要 `/admin?token=...` 或请求头 `X-Admin-Token: ...`。\n\n"
  },
  {
    "path": "marketplace_server/app.py",
    "content": "import io\nimport json\nimport os\nimport time\nimport zipfile\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Tuple\nfrom urllib.parse import parse_qs\n\n# NOTE:\n# This file is intentionally compatible with Python 3.6+ (CentOS 7 default).\n# Do NOT use FastAPI/Pydantic here, as modern versions require Python >= 3.8/3.9.\n# We provide a tiny WSGI app + a built-in server entrypoint.\n\n\nROOT = Path(__file__).resolve().parent\nDEFAULT_SKILLS_DIR = (ROOT.parent / \"skills\").resolve()\nDEFAULT_AGENT_LIB_DIR = (ROOT.parent / \"config\" / \"agent_library\").resolve()\n\n\ndef _env_path(name: str, default: Path) -> Path:\n    raw = os.environ.get(name, \"\").strip()\n    if not raw:\n        return default\n    return Path(raw).expanduser().resolve()\n\n\nSKILLS_DIR = _env_path(\"MARKET_SKILLS_DIR\", DEFAULT_SKILLS_DIR)\nAGENT_LIB_DIR = _env_path(\"MARKET_AGENT_LIBRARY_DIR\", DEFAULT_AGENT_LIB_DIR)\nSTATE_PATH = ROOT / \"state.json\"\n\n\ndef _mk_item(kind: str, name: str, description: str, updated_at: float, downloads: int) -> Dict[str, Any]:\n    return {\n        \"kind\": kind,\n        \"name\": name,\n        \"description\": description or \"\",\n        \"updated_at\": float(updated_at),\n        \"downloads\": int(downloads),\n    }\n\n\ndef _load_state() -> Dict[str, Any]:\n    try:\n        if not STATE_PATH.exists():\n            return {\"downloads\": {\"skills\": {}, \"agent_systems\": {}}}\n        return json.loads(STATE_PATH.read_text(\"utf-8\"))\n    except Exception:\n        return {\"downloads\": {\"skills\": {}, \"agent_systems\": {}}}\n\n\ndef _save_state(state: Dict[str, Any]) -> None:\n    tmp = STATE_PATH.with_suffix(\".tmp\")\n    tmp.write_text(json.dumps(state, ensure_ascii=False, indent=2) + \"\\n\", \"utf-8\")\n    tmp.replace(STATE_PATH)\n\n\ndef _inc_download(kind: str, name: str) -> int:\n    state = _load_state()\n    d = state.setdefault(\"downloads\", {}).setdefault(\"skills\" if kind == \"skill\" else \"agent_systems\", {})\n    d[name] = int(d.get(name, 0)) + 1\n    _save_state(state)\n    return int(d[name])\n\n\ndef _get_downloads(kind: str, name: str) -> int:\n    state = _load_state()\n    d = state.get(\"downloads\", {}).get(\"skills\" if kind == \"skill\" else \"agent_systems\", {})\n    return int(d.get(name, 0))\n\n\ndef _safe_frontmatter_description(skill_md: Path) -> str:\n    # Very small parser: look for YAML-like frontmatter block and \"description:\" line.\n    try:\n        text = skill_md.read_text(\"utf-8\", errors=\"ignore\")\n    except Exception:\n        return \"\"\n    if not text.startswith(\"---\"):\n        return \"\"\n    end = text.find(\"\\n---\", 3)\n    if end == -1:\n        return \"\"\n    fm = text[3:end]\n    for line in fm.splitlines():\n        if line.strip().startswith(\"description:\"):\n            return line.split(\"description:\", 1)[1].strip().strip('\"').strip(\"'\")\n    return \"\"\n\n\ndef _list_skills() -> List[Dict[str, Any]]:\n    items = []  # type: List[Dict[str, Any]]\n    if not SKILLS_DIR.exists():\n        return items\n    for d in sorted(SKILLS_DIR.iterdir()):\n        if not d.is_dir() or d.name.startswith(\".\"):\n            continue\n        desc = _safe_frontmatter_description(d / \"SKILL.md\")\n        try:\n            updated = max((p.stat().st_mtime for p in d.rglob(\"*\") if p.exists()), default=d.stat().st_mtime)\n        except Exception:\n            updated = time.time()\n        items.append(_mk_item(\"skill\", d.name, desc or \"\", float(updated), _get_downloads(\"skill\", d.name)))\n    return items\n\n\ndef _list_agent_systems() -> List[Dict[str, Any]]:\n    items = []  # type: List[Dict[str, Any]]\n    if not AGENT_LIB_DIR.exists():\n        return items\n    for d in sorted(AGENT_LIB_DIR.iterdir()):\n        if not d.is_dir() or d.name.startswith(\".\"):\n            continue\n        # Best-effort description:\n        # 1) extract alpha_agent.description from level_3_agents.yaml (more meaningful)\n        # 2) fallback to first comment line of general_prompts.yaml\n        desc = \"\"\n        l3 = d / \"level_3_agents.yaml\"\n        if l3.exists():\n            try:\n                text = l3.read_text(\"utf-8\", errors=\"ignore\").splitlines()\n                in_alpha = False\n                for line in text:\n                    if not in_alpha and line.startswith(\"  alpha_agent:\"):\n                        in_alpha = True\n                        continue\n                    if in_alpha:\n                        # next tool block\n                        if line.startswith(\"  \") and not line.startswith(\"    \"):\n                            break\n                        if \"description:\" in line:\n                            # naive parse: description: \"...\"\n                            parts = line.split(\"description:\", 1)\n                            if len(parts) == 2:\n                                desc = parts[1].strip().strip('\"').strip(\"'\")\n                                if desc:\n                                    break\n            except Exception:\n                desc = \"\"\n        if not desc:\n            gp = d / \"general_prompts.yaml\"\n            if gp.exists():\n                try:\n                    for raw in gp.read_text(\"utf-8\", errors=\"ignore\").splitlines():\n                        t = raw.strip()\n                        if t.startswith(\"#\"):\n                            desc = t.lstrip(\"#\").strip()\n                            if desc:\n                                break\n                except Exception:\n                    desc = \"\"\n        try:\n            updated = max((p.stat().st_mtime for p in d.rglob(\"*\") if p.exists()), default=d.stat().st_mtime)\n        except Exception:\n            updated = time.time()\n        items.append(_mk_item(\"agent_system\", d.name, desc or \"\", float(updated), _get_downloads(\"agent_system\", d.name)))\n    return items\n\n\ndef _apply_query(items: List[Dict[str, Any]], q: str) -> List[Dict[str, Any]]:\n    query = (q or \"\").strip().lower()\n    if not query:\n        return items\n    out = []\n    for it in items:\n        name = str(it.get(\"name\") or \"\").lower()\n        desc = str(it.get(\"description\") or \"\").lower()\n        if query in name or query in desc:\n            out.append(it)\n    return out\n\n\ndef _sort_items(items: List[Dict[str, Any]], sort_by: str, order: str) -> List[Dict[str, Any]]:\n    key = (sort_by or \"updated_at\").strip()\n    reverse = (order or \"desc\").strip().lower() != \"asc\"\n    if key == \"downloads\":\n        return sorted(items, key=lambda x: int(x.get(\"downloads\", 0)), reverse=reverse)\n    return sorted(items, key=lambda x: float(x.get(\"updated_at\", 0.0)), reverse=reverse)\n\n\ndef _zip_dir_to_bytes(dir_path: Path, top_folder_name: str) -> bytes:\n    buf = io.BytesIO()\n    with zipfile.ZipFile(buf, \"w\", compression=zipfile.ZIP_DEFLATED) as zf:\n        for p in dir_path.rglob(\"*\"):\n            if p.is_dir():\n                continue\n            rel = p.relative_to(dir_path)\n            arc = str(Path(top_folder_name) / rel)\n            zf.write(p, arcname=arc)\n    return buf.getvalue()\n\n\ndef _resolve_item_dir(kind: str, name: str) -> Path:\n    base = SKILLS_DIR if kind == \"skill\" else AGENT_LIB_DIR\n    p = (base / name).resolve()\n    if not p.exists() or not p.is_dir():\n        raise FileNotFoundError(\"%s not found: %s\" % (kind, name))\n    # Prevent path traversal\n    try:\n        p.relative_to(base.resolve())\n    except Exception:\n        raise ValueError(\"Invalid name\")\n    return p\n\n\ndef _json_response(start_response, status: str, data: Dict[str, Any]) -> List[bytes]:\n    body = (json.dumps(data, ensure_ascii=False) + \"\\n\").encode(\"utf-8\")\n    headers = [\n        (\"Content-Type\", \"application/json; charset=utf-8\"),\n        (\"Content-Length\", str(len(body))),\n        (\"Cache-Control\", \"no-store\"),\n    ]\n    start_response(status, headers)\n    return [body]\n\n\ndef _bytes_response(start_response, status: str, content_type: str, body: bytes, extra_headers: Optional[List[Tuple[str, str]]] = None) -> List[bytes]:\n    headers = [\n        (\"Content-Type\", content_type),\n        (\"Content-Length\", str(len(body))),\n        (\"Cache-Control\", \"no-store\"),\n    ]\n    if extra_headers:\n        headers.extend(extra_headers)\n    start_response(status, headers)\n    return [body]\n\n\ndef _not_found(start_response, msg: str) -> List[bytes]:\n    return _json_response(start_response, \"404 Not Found\", {\"ok\": False, \"error\": msg})\n\n\ndef _bad_request(start_response, msg: str) -> List[bytes]:\n    return _json_response(start_response, \"400 Bad Request\", {\"ok\": False, \"error\": msg})\n\n\ndef app(environ, start_response):\n    \"\"\"\n    WSGI callable.\n    Endpoints:\n      - GET /api/v1/health\n      - GET /api/v1/index?q=&sort=updated_at|downloads&order=asc|desc\n      - GET /api/v1/skills/<name>/download\n      - GET /api/v1/agent-systems/<name>/download\n    \"\"\"\n    method = environ.get(\"REQUEST_METHOD\", \"GET\").upper()\n    if method != \"GET\":\n        return _json_response(start_response, \"405 Method Not Allowed\", {\"ok\": False, \"error\": \"Only GET is supported\"})\n\n    path = environ.get(\"PATH_INFO\", \"\") or \"\"\n    qs = parse_qs(environ.get(\"QUERY_STRING\", \"\") or \"\")\n    q = (qs.get(\"q\", [\"\"])[0] or \"\")\n    sort = (qs.get(\"sort\", [\"updated_at\"])[0] or \"updated_at\")\n    order = (qs.get(\"order\", [\"desc\"])[0] or \"desc\")\n\n    if path == \"/api/v1/health\":\n        return _json_response(\n            start_response,\n            \"200 OK\",\n            {\"ok\": True, \"skills_dir\": str(SKILLS_DIR), \"agent_library_dir\": str(AGENT_LIB_DIR)},\n        )\n\n    if path == \"/api/v1/index\":\n        skills = _sort_items(_apply_query(_list_skills(), q), sort, order)\n        systems = _sort_items(_apply_query(_list_agent_systems(), q), sort, order)\n        return _json_response(start_response, \"200 OK\", {\"skills\": skills, \"agent_systems\": systems})\n\n    # Admin UI (upload)\n    if path == \"/admin\":\n        if not _check_admin(environ):\n            return _json_response(start_response, \"403 Forbidden\", {\"ok\": False, \"error\": \"admin token required\"})\n        # keep token in links if provided\n        qs2 = parse_qs(environ.get(\"QUERY_STRING\", \"\") or \"\")\n        token_q = (qs2.get(\"token\", [\"\"])[0] or \"\").strip()\n        token_hidden = '<input type=\"hidden\" name=\"token\" value=\"%s\"/>' % _escape_html(token_q) if token_q else \"\"\n        body = []\n        body.append('<div class=\"box\"><div class=\"muted\">Skills dir: <code>%s</code><br/>Agent systems dir: <code>%s</code></div></div>' % (_escape_html(str(SKILLS_DIR)), _escape_html(str(AGENT_LIB_DIR))))\n        if _admin_token_required() and not token_q:\n            body.append('<div class=\"box\"><b>提示</b>：已设置 <code>MARKET_ADMIN_TOKEN</code>，请用 <code>/admin?token=...</code> 打开管理页。</div>')\n        body.append(\"\"\"\n<div class=\"box\">\n  <h3>Upload Skill (zip)</h3>\n  <form method=\"POST\" action=\"/api/v1/admin/upload-skill\" enctype=\"multipart/form-data\">\n    %s\n    <div class=\"row\">\n      <input type=\"file\" name=\"file\" accept=\".zip\" required/>\n      <select name=\"strategy\">\n        <option value=\"overwrite\">overwrite</option>\n        <option value=\"keep_both\">keep_both</option>\n      </select>\n      <button type=\"submit\">Upload</button>\n    </div>\n  </form>\n</div>\n<div class=\"box\">\n  <h3>Upload Agent System (zip)</h3>\n  <form method=\"POST\" action=\"/api/v1/admin/upload-agent-system\" enctype=\"multipart/form-data\">\n    %s\n    <div class=\"row\">\n      <input type=\"file\" name=\"file\" accept=\".zip\" required/>\n      <select name=\"strategy\">\n        <option value=\"overwrite\">overwrite</option>\n        <option value=\"keep_both\">keep_both</option>\n      </select>\n      <button type=\"submit\">Upload</button>\n    </div>\n  </form>\n</div>\n\"\"\" % (token_hidden, token_hidden))\n\n        # Lists\n        skills = _list_skills()\n        systems = _list_agent_systems()\n        body.append('<div class=\"box\"><h3>Skills (%d)</h3>' % len(skills))\n        body.append('<table><tr><th>Name</th><th>Description</th><th>Downloads</th><th>Updated</th></tr>')\n        for it in _sort_items(skills, \"updated_at\", \"desc\"):\n            body.append(\"<tr><td><code>%s</code></td><td>%s</td><td>%s</td><td>%s</td></tr>\" % (\n                _escape_html(it.get(\"name\",\"\")),\n                _escape_html(it.get(\"description\",\"\")),\n                _escape_html(str(it.get(\"downloads\",\"\"))),\n                _escape_html(time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime(float(it.get(\"updated_at\",0.0))))),\n            ))\n        body.append(\"</table></div>\")\n        body.append('<div class=\"box\"><h3>Agent Systems (%d)</h3>' % len(systems))\n        body.append('<table><tr><th>Name</th><th>Description</th><th>Downloads</th><th>Updated</th></tr>')\n        for it in _sort_items(systems, \"updated_at\", \"desc\"):\n            body.append(\"<tr><td><code>%s</code></td><td>%s</td><td>%s</td><td>%s</td></tr>\" % (\n                _escape_html(it.get(\"name\",\"\")),\n                _escape_html(it.get(\"description\",\"\")),\n                _escape_html(str(it.get(\"downloads\",\"\"))),\n                _escape_html(time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime(float(it.get(\"updated_at\",0.0))))),\n            ))\n        body.append(\"</table></div>\")\n\n        page = _html_page(\"infiAgent Marketplace Admin\", \"\\n\".join(body))\n        return _bytes_response(start_response, \"200 OK\", \"text/html; charset=utf-8\", page)\n\n    if path in (\"/api/v1/admin/upload-skill\", \"/api/v1/admin/upload-agent-system\"):\n        if not _check_admin(environ):\n            return _json_response(start_response, \"403 Forbidden\", {\"ok\": False, \"error\": \"admin token required\"})\n        if method != \"POST\":\n            return _json_response(start_response, \"405 Method Not Allowed\", {\"ok\": False, \"error\": \"Only POST is supported\"})\n        try:\n            import cgi\n            fs = cgi.FieldStorage(fp=environ[\"wsgi.input\"], environ=environ, keep_blank_values=True)\n            f = fs[\"file\"] if \"file\" in fs else None\n            if not f or not getattr(f, \"file\", None):\n                return _bad_request(start_response, \"Missing file\")\n            strategy = (fs.getfirst(\"strategy\", \"overwrite\") or \"overwrite\").strip()\n            token_q = (fs.getfirst(\"token\", \"\") or \"\").strip()\n            # token in POST form also accepted\n            if os.environ.get(\"MARKET_ADMIN_TOKEN\", \"\").strip() and token_q:\n                # emulate query token check\n                if token_q != os.environ.get(\"MARKET_ADMIN_TOKEN\", \"\").strip():\n                    return _json_response(start_response, \"403 Forbidden\", {\"ok\": False, \"error\": \"invalid token\"})\n\n            zip_bytes = f.file.read()\n            kind = \"skill\" if path.endswith(\"upload-skill\") else \"agent_system\"\n            dest = SKILLS_DIR if kind == \"skill\" else AGENT_LIB_DIR\n            dest.mkdir(parents=True, exist_ok=True)\n            try:\n                installed = _extract_zip_to_dest(zip_bytes, dest, strategy)\n            except ValueError as e:\n                if str(e) == \"conflict\":\n                    return _json_response(start_response, \"409 Conflict\", {\"ok\": False, \"error\": \"name conflict\", \"hint\": \"use keep_both or overwrite\"})\n                raise\n            return _json_response(start_response, \"200 OK\", {\"ok\": True, \"kind\": kind, \"installed_name\": installed, \"dest\": str(dest)})\n        except Exception as e:\n            return _json_response(start_response, \"500 Internal Server Error\", {\"ok\": False, \"error\": str(e)})\n\n    if path.startswith(\"/api/v1/skills/\") and path.endswith(\"/download\"):\n        name = path[len(\"/api/v1/skills/\") : -len(\"/download\")].strip(\"/\")\n        if not name:\n            return _bad_request(start_response, \"Missing skill name\")\n        try:\n            p = _resolve_item_dir(\"skill\", name)\n        except Exception as e:\n            return _not_found(start_response, str(e))\n        _inc_download(\"skill\", name)\n        data = _zip_dir_to_bytes(p, top_folder_name=name)\n        return _bytes_response(\n            start_response,\n            \"200 OK\",\n            \"application/zip\",\n            data,\n            extra_headers=[(\"Content-Disposition\", 'attachment; filename=\"%s.zip\"' % name)],\n        )\n\n    if path.startswith(\"/api/v1/agent-systems/\") and path.endswith(\"/download\"):\n        name = path[len(\"/api/v1/agent-systems/\") : -len(\"/download\")].strip(\"/\")\n        if not name:\n            return _bad_request(start_response, \"Missing agent system name\")\n        try:\n            p = _resolve_item_dir(\"agent_system\", name)\n        except Exception as e:\n            return _not_found(start_response, str(e))\n        _inc_download(\"agent_system\", name)\n        data = _zip_dir_to_bytes(p, top_folder_name=name)\n        return _bytes_response(\n            start_response,\n            \"200 OK\",\n            \"application/zip\",\n            data,\n            extra_headers=[(\"Content-Disposition\", 'attachment; filename=\"%s.zip\"' % name)],\n        )\n\n    return _not_found(start_response, \"Unknown endpoint\")\n\n\ndef _run_dev_server(host: str, port: int) -> None:\n    from wsgiref.simple_server import make_server\n\n    httpd = make_server(host, port, app)\n    print(\"infiAgent Marketplace listening on http://%s:%s\" % (host, port))\n    httpd.serve_forever()\n\n\ndef _html_page(title: str, body_html: str) -> bytes:\n    html = \"\"\"<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\"/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n  <title>{title}</title>\n  <style>\n    body {{ font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Arial,sans-serif; padding: 20px; max-width: 980px; margin: 0 auto; }}\n    code, pre {{ font-family: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace; }}\n    .box {{ border: 1px solid #ddd; border-radius: 10px; padding: 14px; margin: 12px 0; }}\n    .row {{ display:flex; gap: 12px; flex-wrap: wrap; align-items: center; }}\n    input[type=\"text\"] {{ padding: 8px 10px; border: 1px solid #ddd; border-radius: 8px; min-width: 320px; }}\n    select, input[type=\"file\"] {{ padding: 6px 8px; }}\n    button {{ padding: 8px 12px; border: 1px solid #888; border-radius: 8px; background: #f6f6f6; cursor:pointer; }}\n    button:hover {{ background: #efefef; }}\n    table {{ width: 100%; border-collapse: collapse; }}\n    th, td {{ border-bottom: 1px solid #eee; text-align: left; padding: 8px; vertical-align: top; }}\n    .muted {{ color: #666; }}\n  </style>\n</head>\n<body>\n  <h2>{title}</h2>\n  {body}\n</body>\n</html>\n\"\"\".format(title=title, body=body_html)\n    return html.encode(\"utf-8\")\n\n\ndef _escape_html(s: str) -> str:\n    return (\n        str(s or \"\")\n        .replace(\"&\", \"&amp;\")\n        .replace(\"<\", \"&lt;\")\n        .replace(\">\", \"&gt;\")\n        .replace('\"', \"&quot;\")\n        .replace(\"'\", \"&#39;\")\n    )\n\n\ndef _admin_token_required() -> bool:\n    return bool(os.environ.get(\"MARKET_ADMIN_TOKEN\", \"\").strip())\n\n\ndef _check_admin(environ) -> bool:\n    token = os.environ.get(\"MARKET_ADMIN_TOKEN\", \"\").strip()\n    if not token:\n        return True\n    # allow query ?token= or header X-Admin-Token\n    qs = parse_qs(environ.get(\"QUERY_STRING\", \"\") or \"\")\n    qtok = (qs.get(\"token\", [\"\"])[0] or \"\").strip()\n    htok = (environ.get(\"HTTP_X_ADMIN_TOKEN\", \"\") or \"\").strip()\n    return (qtok == token) or (htok == token)\n\n\ndef _extract_zip_to_dest(zip_bytes: bytes, dest_root: Path, strategy: str) -> str:\n    import tempfile\n    # Extract into temp dir first\n    with tempfile.TemporaryDirectory() as td:\n        tmp = Path(td)\n        with zipfile.ZipFile(io.BytesIO(zip_bytes), \"r\") as zf:\n            zf.extractall(str(tmp))\n        # Determine top folder\n        entries = [p for p in tmp.iterdir() if p.name and not p.name.startswith(\".\")]\n        dirs = [p for p in entries if p.is_dir()]\n        if len(dirs) == 1:\n            top = dirs[0]\n        else:\n            # if archive doesn't have a single top folder, treat tmp as top\n            top = tmp\n        base_name = top.name if top != tmp else \"uploaded\"\n        install_name = base_name\n        target = dest_root / install_name\n        if target.exists():\n            if strategy == \"overwrite\":\n                # rm existing\n                for p in sorted(target.rglob(\"*\"), reverse=True):\n                    try:\n                        if p.is_file() or p.is_symlink():\n                            p.unlink()\n                        elif p.is_dir():\n                            p.rmdir()\n                    except Exception:\n                        pass\n                try:\n                    target.rmdir()\n                except Exception:\n                    pass\n            elif strategy == \"keep_both\":\n                for i in range(2, 1000):\n                    cand = dest_root / (\"%s__%d\" % (install_name, i))\n                    if not cand.exists():\n                        target = cand\n                        install_name = cand.name\n                        break\n            else:\n                raise ValueError(\"conflict\")\n        target.mkdir(parents=True, exist_ok=True)\n        # Copy contents\n        if top == tmp:\n            src_root = tmp\n        else:\n            src_root = top\n        for p in src_root.rglob(\"*\"):\n            rel = p.relative_to(src_root)\n            out = target / rel\n            if p.is_dir():\n                out.mkdir(parents=True, exist_ok=True)\n            else:\n                out.parent.mkdir(parents=True, exist_ok=True)\n                out.write_bytes(p.read_bytes())\n    return install_name\n\n\nif __name__ == \"__main__\":\n    import argparse\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--host\", default=\"127.0.0.1\")\n    parser.add_argument(\"--port\", default=18080, type=int)\n    args = parser.parse_args()\n    _run_dev_server(args.host, args.port)\n\n"
  },
  {
    "path": "marketplace_server/deploy_market.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# Deploy infiAgent Marketplace to a remote Linux server.\n#\n# Requirements:\n# - SSH key auth (no interactive password)\n# - Remote has systemd + nginx (script can install via apt if Debian/Ubuntu)\n#\n# Usage:\n#   ./deploy_market.sh root@101.200.231.88\n#\n# Optional env:\n#   REMOTE_DIR=/opt/infiagent-market\n#   MARKET_PORT=18080\n#   NGINX_PORT=80\n\nTARGET=\"${1:-}\"\nif [[ -z \"${TARGET}\" ]]; then\n  echo \"Usage: $0 user@host\"\n  exit 1\nfi\n\nREMOTE_DIR=\"${REMOTE_DIR:-/opt/infiagent-market}\"\nMARKET_PORT=\"${MARKET_PORT:-18080}\"\nNGINX_PORT=\"${NGINX_PORT:-80}\"\n\nREPO_ROOT=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\n\necho \"[deploy] repo_root: ${REPO_ROOT}\"\necho \"[deploy] target: ${TARGET}\"\necho \"[deploy] remote_dir: ${REMOTE_DIR}\"\n\n# Upload only what we need\necho \"[deploy] uploading files...\"\nrsync -av --delete \\\n  --exclude \".git/\" \\\n  --exclude \"desktop_app/\" \\\n  --exclude \"backend_build/\" \\\n  --exclude \"web_ui/\" \\\n  --exclude \"tests/\" \\\n  --exclude \"__pycache__/\" \\\n  \"${REPO_ROOT}/marketplace_server/\" \\\n  \"${REPO_ROOT}/skills/\" \\\n  \"${REPO_ROOT}/config/agent_library/\" \\\n  \"${TARGET}:${REMOTE_DIR}/\"\n\necho \"[deploy] provisioning remote...\"\nssh -o StrictHostKeyChecking=accept-new \"${TARGET}\" bash -s <<EOF\nset -euo pipefail\n\nREMOTE_DIR=\"${REMOTE_DIR}\"\nMARKET_PORT=\"${MARKET_PORT}\"\nNGINX_PORT=\"${NGINX_PORT}\"\n\ncd \"\\${REMOTE_DIR}\"\n\n# Best-effort install deps (Debian/Ubuntu). If not available, user can install manually.\nif command -v apt-get >/dev/null 2>&1; then\n  export DEBIAN_FRONTEND=noninteractive\n  apt-get update -y\n  apt-get install -y python3 python3-venv python3-pip nginx\nfi\n\n# Python venv for marketplace\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -U pip\npip install -r marketplace_server/requirements.txt\n\n# systemd service\nsed \"s|/opt/infiagent-market|\\${REMOTE_DIR}|g; s|--port 18080|--port \\${MARKET_PORT}|g\" marketplace_server/infiagent-market.service > /etc/systemd/system/infiagent-market.service\nsystemctl daemon-reload\nsystemctl enable --now infiagent-market\n\n# nginx reverse proxy on port 80\ncat > /etc/nginx/conf.d/infiagent_market.conf <<NGINX\nserver {\n    listen ${NGINX_PORT};\n    server_name _;\n\n    location / {\n        proxy_pass http://127.0.0.1:${MARKET_PORT};\n        proxy_set_header Host \\$host;\n        proxy_set_header X-Real-IP \\$remote_addr;\n        proxy_set_header X-Forwarded-For \\$proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto \\$scheme;\n    }\n}\nNGINX\n\nnginx -t\nsystemctl reload nginx\n\necho \"[deploy] done. health check:\"\ncurl -s \"http://127.0.0.1:\\${NGINX_PORT}/api/v1/health\" || true\nEOF\n\necho \"[deploy] finished.\"\n\n"
  },
  {
    "path": "marketplace_server/infiagent-market.service",
    "content": "[Unit]\nDescription=infiAgent Marketplace\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=/opt/infiagent-market/marketplace_server\nEnvironment=MARKET_SKILLS_DIR=/opt/infiagent-market/skills\nEnvironment=MARKET_AGENT_LIBRARY_DIR=/opt/infiagent-market/config/agent_library\nExecStart=/usr/bin/python3 /opt/infiagent-market/marketplace_server/app.py --host 127.0.0.1 --port 18080\nRestart=always\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n\n"
  },
  {
    "path": "marketplace_server/nginx_infiagent_market.conf",
    "content": "server {\n    listen 80;\n    server_name _;\n\n    # Proxy all marketplace traffic\n    location / {\n        proxy_pass http://127.0.0.1:18080;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\n\n"
  },
  {
    "path": "marketplace_server/requirements.txt",
    "content": "# 该市场服务端默认兼容 CentOS7 的 Python 3.6+，使用内置 WSGI server 运行（无第三方依赖）。\n#\n# 如需更高性能，可自行改用 gunicorn/waitress 等 WSGI server。\n\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=69,<75\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n"
  },
  {
    "path": "requirements.txt",
    "content": "# MLA V3 依赖包\n\n# 核心依赖\nlitellm==1.82.6        # 统一的LLM接口（与桌面后端打包版本保持一致）\npyyaml>=6.0             # YAML配置文件解析\ntiktoken>=0.5.0\nvirtualenv>=20.0.0      # 虚拟环境（兼容 Anaconda）\n\n# Tool Server 依赖\nfastapi>=0.104.0\nuvicorn[standard]>=0.24.0\npydantic>=2.0.0\nrequests>=2.31.0\nbeautifulsoup4>=4.12.0\nchardet>=5.2.0\nmcp; python_version >= \"3.10\"\npdfplumber>=0.10.0\npython-docx>=1.1.0\ncrawl4ai>=0.3.0         # 网页爬取（会自动安装 playwright）\nddgs>=1.0.0             # DuckDuckGo 搜索\narxiv>=2.0.0            # arXiv API\nprompt_toolkit>=3.0.0   # CLI 交互\nrich>=13.0.0            # 终端美化\npsutil>=5.9.0           # 进程管理\nPyMuPDF\nplaywright>=1.40.0\ndocx2pdf\npytest>=7.0.0\n# 核心依赖\nlitellm==1.82.6          # 统一的LLM接口（与桌面后端打包版本保持一致）\npyyaml>=6.0             # YAML配置文件解析\ntiktoken>=0.5.0\nvirtualenv>=20.0.0      # 虚拟环境（兼容 Anaconda）\n\nfastapi>=0.104.0\nuvicorn[standard]>=0.24.0\npydantic>=2.0.0\nrequests>=2.31.0\nbeautifulsoup4>=4.12.0\nchardet>=5.2.0\npdfplumber>=0.10.0\npython-docx>=1.1.0\npython-pptx>=0.6.21\ncrawl4ai>=0.3.0\nddgs>=1.0.0\npyyaml>=6.0.0\narxiv>=2.0.0\nprompt_toolkit>=3.0.0\nrich>=13.0.0\npsutil>=5.9.0 \n\nplaywright>=1.40.0\n"
  },
  {
    "path": "services/__init__.py",
    "content": "# Services modules\n"
  },
  {
    "path": "services/action_compressor.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n历史动作压缩服务\n策略：总结历史XML + 保留最新action + 压缩最新action的大字段\n\"\"\"\n\nimport json\nfrom typing import List, Dict, Optional\n\ntry:\n    import tiktoken\n    HAS_TIKTOKEN = True\nexcept ImportError:\n    HAS_TIKTOKEN = False\n\n\nclass ActionCompressor:\n    \"\"\"历史动作压缩器\"\"\"\n    \n    # action_history 中的内部元数据字段（不参与 XML 转换和 token 统计）\n    _INTERNAL_FIELDS = {\"_turn\", \"tool_call_id\", \"assistant_content\", \"reasoning_content\", \"_has_image\", \"_image_base64\"}\n    \n    def __init__(\n        self,\n        llm_client,\n        preferred_model: Optional[str] = None,\n        max_tokens: Optional[int] = None,\n        debug_task_id: Optional[str] = None,\n    ):\n        \"\"\"\n        初始化\n        \n        Args:\n            llm_client: LLM客户端实例（用于总结）\n        \"\"\"\n        self.llm_client = llm_client\n        self.compressor_multimodal = getattr(llm_client, 'compressor_multimodal', False)\n        self.preferred_model = preferred_model\n        self.max_tokens = max_tokens\n        self.debug_task_id = debug_task_id\n        \n        # 初始化tiktoken\n        if HAS_TIKTOKEN:\n            self.encoding = tiktoken.get_encoding(\"cl100k_base\")\n        else:\n            self.encoding = None\n\n    def _resolve_compressor_model(self) -> str:\n        return self.llm_client.resolve_model(\"compressor\", self.preferred_model)\n\n    def _resolve_compressor_tool_choice(self, model: str) -> str:\n        return self.llm_client.resolve_tool_choice(\"compressor\", model)\n    \n    def count_tokens(self, text: str) -> int:\n        \"\"\"统计token数\"\"\"\n        if self.encoding:\n            return len(self.encoding.encode(text))\n        else:\n            chinese_chars = sum(1 for c in text if '\\u4e00' <= c <= '\\u9fff')\n            other_chars = len(text) - chinese_chars\n            return int(chinese_chars / 1.5 + other_chars / 4)\n    \n    def compress_if_needed(\n        self,\n        action_history: List[Dict],\n        max_context_window: int,\n        thinking: str = \"\",\n        task_input: str = \"\",\n        save_callback=None  # 添加保存回调，确保压缩后立即保存\n    ) -> List[Dict]:\n        \"\"\"\n        检查并压缩历史动作\n        \n        策略：\n        1. 保留最新1条action（完整或压缩大字段）\n        2. 之前的所有action总结为一个summary_action\n        3. 基于 thinking 和 task_input 判断哪些信息有效、哪些无关\n        \n        Args:\n            action_history: 动作历史\n            max_context_window: 最大窗口大小\n            thinking: 当前的 thinking 内容（包含 todolist 和计划）\n            task_input: 任务需求描述\n            \n        Returns:\n            压缩后的action_history\n        \"\"\"\n        if not action_history:\n            return []\n        \n        # 如果只有一条\n        if len(action_history) == 1:\n            # 检查是否需要压缩字段\n            return [self._compress_action_fields(action_history[0], max_context_window // 2)]\n        \n        # 分离最新和历史\n        recent_action = action_history[-1]\n        historical_actions = action_history[:-1]\n        \n        # 计算整体token数\n        total_text = self._actions_to_xml(action_history)\n        total_tokens = self.count_tokens(total_text+thinking+task_input)\n        \n        # 如果不超限，不压缩\n        if total_tokens <= max_context_window - 20000:\n            return action_history\n        \n        safe_print(f\"🔄 历史动作需要压缩: {total_tokens} tokens > {max_context_window - 20000}\")\n        \n        # 压缩策略：\n        # 1. 历史 → 基于 thinking 和 task_input 智能总结为5k tokens\n        # 2. 最新 → 压缩为max_window的50%\n        \n        summary_action = self._summarize_historical_xml(\n            self._actions_to_xml(historical_actions),\n            target_tokens=5000,  # 历史总结固定5k tokens\n            thinking=thinking,\n            task_input=task_input,\n            max_context_window=max_context_window,\n            actions=historical_actions  # 传递原始 actions（用于提取图片）\n        )\n        \n        # 压缩最新action的大字段（50% of max_window）\n        compressed_recent = self._compress_action_fields(\n            recent_action,\n            int(max_context_window * 0.5),  # 80000 * 0.5 = 40000 tokens\n            thinking=thinking,\n            task_input=task_input,\n            max_context_window=max_context_window\n        )\n        \n        result = [summary_action, compressed_recent]\n        \n        # 验证压缩效果\n        result_xml = self._actions_to_xml(result)\n        result_tokens = self.count_tokens(result_xml)\n        safe_print(f\"✅ 压缩完成: {total_tokens} tokens → {result_tokens} tokens (压缩比: {result_tokens/total_tokens*100:.1f}%)\")\n        \n        return result\n    \n    def _actions_to_xml(self, actions: List[Dict]) -> str:\n        \"\"\"将actions转换为XML格式文本（跳过内部元数据字段）\"\"\"\n        xml_parts = []\n        for action in actions:\n            tool_name = action.get(\"tool_name\", \"\")\n            arguments = action.get(\"arguments\", {})\n            result = action.get(\"result\", {})\n            \n            action_xml = f\"<action>\\n  <tool_name>{tool_name}</tool_name>\\n\"\n            \n            # 参数（跳过内部字段）\n            for k, v in arguments.items():\n                if k in self._INTERNAL_FIELDS:\n                    continue\n                v_str = str(v).replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\")\n                action_xml += f\"  <tool_use:{k}>{v_str}</tool_use:{k}>\\n\"\n            \n            # 结果（排除以 _ 开头的内部字段，特别是 _image_base64）\n            result_clean = {k: v for k, v in result.items() if not k.startswith(\"_\")}\n            result_json = json.dumps(result_clean, ensure_ascii=False, indent=2)\n            action_xml += f\"  <result>\\n{result_json}\\n  </result>\\n</action>\"\n            \n            xml_parts.append(action_xml)\n        \n        return \"\\n\\n\".join(xml_parts)\n    \n    def _extract_images_from_actions(self, actions: List[Dict]) -> List[Dict]:\n        \"\"\"\n        从 action 列表中提取图片数据（用于多模态压缩）\n        \n        Returns:\n            [{base64: str, tool_name: str}] 列表（每张图一个条目）\n        \"\"\"\n        images = []\n        if not actions:\n            return images\n        for action in actions:\n            if action.get(\"_has_image\") and action.get(\"_image_base64\"):\n                img_data = action[\"_image_base64\"]\n                tool_name = action.get(\"tool_name\", \"image_read\")\n                # _image_base64 可能是列表或单值（兼容两种格式）\n                if isinstance(img_data, list):\n                    for b64 in img_data:\n                        images.append({\"base64\": b64, \"tool_name\": tool_name})\n                else:\n                    images.append({\"base64\": img_data, \"tool_name\": tool_name})\n        return images\n    \n    def _summarize_historical_xml(\n        self, \n        xml_text: str, \n        target_tokens: int = 5000,\n        thinking: str = \"\",\n        task_input: str = \"\",\n        max_context_window: int = None,\n        actions: List[Dict] = None\n    ) -> Dict:\n        \"\"\"\n        总结历史XML内容为一个summary action\n        基于 thinking 和 task_input 智能判断哪些信息有效\n        支持分段压缩：如果数据量过大，自动分段处理\n        支持多模态：当 compressor_multimodal=True 时，在压缩 LLM 调用中嵌入图片\n        \n        Args:\n            xml_text: 历史actions的XML文本\n            target_tokens: 目标token数\n            thinking: 当前的 thinking 内容（包含 todolist 和计划）\n            task_input: 任务需求描述\n            max_context_window: 最大上下文窗口（用于判断是否需要分段）\n            actions: 原始 action 列表（用于提取图片数据，可选）\n            \n        Returns:\n            一个summary action\n        \"\"\"\n        try:\n            from services.llm_client import ChatMessage\n            \n            # 提取图片数据（如果支持多模态）\n            images = self._extract_images_from_actions(actions) if self.compressor_multimodal and actions else []\n            \n            # 检查数据量，决定是否需要分段压缩\n            xml_tokens = self.count_tokens(xml_text)\n            \n            # 获取压缩模型的上下文限制（从参数或LLM客户端获取）\n            compressor_context_limit = max_context_window or self.llm_client.max_context_window\n            \n            # 构建上下文信息\n            context_info = \"\"\n            if task_input:\n                context_info += f\"\\n<任务需求>\\n{task_input}\\n</任务需求>\\n\"\n            if thinking:\n                context_info += f\"\\n<当前进度与计划>\\n{thinking}\\n</当前进度与计划>\\n\"\n            \n            context_tokens = self.count_tokens(context_info)\n            \n            # 如果数据量 + 上下文 + 提示词 超过模型限制的60%，使用分段压缩\n            overhead_tokens = 2000  # 提示词和格式的开销\n            available_tokens = int(compressor_context_limit * 0.6) - context_tokens - overhead_tokens\n            \n            if xml_tokens > available_tokens:\n                safe_print(f\"   📦 数据量过大({xml_tokens} tokens)，启用分段压缩\")\n                return self._chunked_summarize(xml_text, target_tokens, thinking, task_input, available_tokens)\n            \n            # 数据量合适，直接压缩\n            return self._single_summarize(xml_text, target_tokens, thinking, task_input, context_info, images=images)\n        \n        except Exception as e:\n            safe_print(f\"⚠️ 总结失败: {e}\")\n            import traceback\n            traceback.print_exc()\n            return {\n                \"tool_name\": \"_historical_summary\",\n                \"arguments\": {},\n                \"result\": {\"status\": \"success\", \"output\": \"[历史动作已省略]\", \"_is_summary\": True}\n            }\n    \n    def _single_summarize(\n        self,\n        xml_text: str,\n        target_tokens: int,\n        thinking: str,\n        task_input: str,\n        context_info: str,\n        images: List[Dict] = None\n    ) -> Dict:\n        \"\"\"\n        单次压缩（数据量不大时使用）\n        支持多模态：当有图片时，在 LLM 调用中嵌入图片\n        \n        Args:\n            images: [{base64: str, tool_name: str}] 图片列表（可选）\n        \"\"\"\n        prompt = f\"\"\"你是智能历史信息压缩助手。请基于任务需求和当前进度，智能压缩以下历史动作。\n\n{context_info}\n\n<历史动作>\n{xml_text}\n</历史动作>\n\n压缩要求：\n1. **目标长度**: 严格控制在 {target_tokens} tokens 以内\n2. **智能筛选**: \n   - 分析 thinking 中的 todolist/计划，判断哪些动作是为了完成未完成的任务目标\n   - 保留已完成任务相关的**关键结果**（如生成的文件路径、重要输出）\n   - 丢弃无关或失败的尝试信息\n3. **优先保留**:\n   - 成功完成的关键步骤（如创建的文件、执行的代码、获取的数据）\n   - 重要的文件路径和位置信息\n   - 对后续任务有参考价值的输出\n4. **可以丢弃**:\n   - 重复的尝试和错误信息\n   - 中间的调试过程\n   - 与当前任务目标无关的探索性操作\n5. **格式要求**:\n   - 按时间顺序总结\n   - 突出关键成果和产出\n   - 保持信息的连贯性\n{\"6. **图片说明**: 下方附有历史动作中读取的图片，请在总结中包含对图片内容的文字描述。\" if images else \"\"}\n\n请直接输出压缩后的总结（中文）：\"\"\"\n        \n        # 构建 messages（支持多模态图片嵌入）\n        if images:\n            content_parts = [{\"type\": \"text\", \"text\": prompt}]\n            for img in images:\n                content_parts.append({\n                    \"type\": \"image_url\",\n                    \"image_url\": {\"url\": img[\"base64\"] if img[\"base64\"].startswith(\"data:\") else f\"data:image/jpeg;base64,{img['base64']}\"}\n                })\n                content_parts.append({\n                    \"type\": \"text\",\n                    \"text\": f\"(Image from {img['tool_name']})\"\n                })\n            history = [{\"role\": \"user\", \"content\": content_parts}]\n        else:\n            history = [{\"role\": \"user\", \"content\": prompt}]\n        \n        compressor_model = self._resolve_compressor_model()\n        response = self.llm_client.chat(\n            history=history,\n            model=compressor_model,\n            system_prompt=f\"你是整体上下文构造专家。目标：将内容压缩到{target_tokens} tokens以内。\",\n            tool_list=[],\n            tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n            max_tokens=self.max_tokens,\n            debug_task_id=self.debug_task_id,\n            debug_label=\"action_compressor\",\n        )\n        \n        summary = response.output if response.status == \"success\" else \"[总结失败]\"\n        \n        return {\n            \"tool_name\": \"_historical_summary\",\n            \"arguments\": {},\n            \"result\": {\n                \"status\": \"success\",\n                \"output\": summary,\n                \"_is_summary\": True\n            }\n        }\n    \n    def _chunked_summarize(\n        self,\n        xml_text: str,\n        target_tokens: int,\n        thinking: str,\n        task_input: str,\n        chunk_size_tokens: int\n    ) -> Dict:\n        \"\"\"\n        分段压缩（数据量过大时使用）\n        \n        Args:\n            xml_text: 完整的XML文本\n            target_tokens: 最终目标token数\n            thinking: thinking内容\n            task_input: 任务输入\n            chunk_size_tokens: 每段的最大token数\n        \n        Returns:\n            压缩后的summary action\n        \"\"\"\n        from services.llm_client import ChatMessage\n        \n        # 按action分割xml_text\n        # 简单方法：按 </action> 分割\n        action_blocks = xml_text.split('</action>')\n        action_blocks = [block + '</action>' for block in action_blocks if block.strip()]\n        \n        # 将actions分组到chunks中\n        chunks = []\n        current_chunk = []\n        current_chunk_tokens = 0\n        \n        for action_block in action_blocks:\n            action_tokens = self.count_tokens(action_block)\n            \n            if current_chunk_tokens + action_tokens > chunk_size_tokens and current_chunk:\n                # 当前chunk已满，开始新chunk\n                chunks.append('\\n\\n'.join(current_chunk))\n                current_chunk = [action_block]\n                current_chunk_tokens = action_tokens\n            else:\n                current_chunk.append(action_block)\n                current_chunk_tokens += action_tokens\n        \n        # 添加最后一个chunk\n        if current_chunk:\n            chunks.append('\\n\\n'.join(current_chunk))\n        \n        safe_print(f\"      分成 {len(chunks)} 段进行压缩\")\n        \n        # 构建上下文信息\n        context_info = \"\"\n        if task_input:\n            context_info += f\"\\n<任务需求>\\n{task_input}\\n</任务需求>\\n\"\n        if thinking:\n            context_info += f\"\\n<当前进度与计划>\\n{thinking}\\n</当前进度与计划>\\n\"\n        \n        # 对每个chunk进行压缩\n        chunk_summaries = []\n        target_per_chunk = target_tokens // len(chunks)\n        \n        for i, chunk in enumerate(chunks):\n            safe_print(f\"      压缩第 {i+1}/{len(chunks)} 段...\")\n            \n            prompt = f\"\"\"你是智能历史信息压缩助手。这是分段压缩任务的第 {i+1}/{len(chunks)} 段。\n\n{context_info}\n\n<本段历史动作>\n{chunk}\n</本段历史动作>\n\n压缩要求：\n1. **目标长度**: 严格控制在 {target_per_chunk} tokens 以内\n2. **智能筛选**: \n   - 根据任务需求和进度，保留关键结果和重要信息\n   - 丢弃无关或失败的尝试\n3. **优先保留**:\n   - 成功的关键步骤和产出\n   - 重要的文件路径和数据\n   - 对后续任务有价值的输出\n4. **格式要求**:\n   - 按时间顺序简要总结本段的关键动作\n   - 突出重要成果\n\n请直接输出本段的压缩总结（中文）：\"\"\"\n            \n            history = [ChatMessage(role=\"user\", content=prompt)]\n            \n            try:\n                compressor_model = self._resolve_compressor_model()\n                response = self.llm_client.chat(\n                    history=history,\n                    model=compressor_model,\n                    system_prompt=f\"你是内容压缩专家。目标：将本段压缩到{target_per_chunk} tokens以内。\",\n                    tool_list=[],  # 空列表表示不使用工具\n                    tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n                    max_tokens=self.max_tokens,\n                    debug_task_id=self.debug_task_id,\n                    debug_label=\"action_compressor\",\n                )\n                \n                if response.status == \"success\":\n                    chunk_summaries.append(f\"[段{i+1}] {response.output}\")\n                    safe_print(f\"         ✅ 第{i+1}段压缩成功\")\n                else:\n                    chunk_summaries.append(f\"[段{i+1}] [压缩失败]\")\n                    safe_print(f\"         ⚠️ 第{i+1}段压缩失败: {response.output}\")\n            except Exception as e:\n                chunk_summaries.append(f\"[段{i+1}] [压缩异常]\")\n                safe_print(f\"         ❌ 第{i+1}段压缩异常: {e}\")\n        \n        # 合并所有段的总结\n        final_summary = \"\\n\\n\".join(chunk_summaries)\n        \n        safe_print(f\"      ✅ 分段压缩完成，共{len(chunks)}段\")\n        \n        return {\n            \"tool_name\": \"_historical_summary\",\n            \"arguments\": {},\n            \"result\": {\n                \"status\": \"success\",\n                \"output\": final_summary,\n                \"_is_summary\": True,\n                \"_chunked\": True,\n                \"_chunks_count\": len(chunks)\n            }\n        }\n    \n    def _compress_action_fields(\n        self, \n        action: Dict, \n        max_field_tokens: int,\n        thinking: str = \"\",\n        task_input: str = \"\",\n        max_context_window: int = None\n    ) -> Dict:\n        \"\"\"\n        压缩action中的大字段（arguments和result）\n        \n        Args:\n            action: 原始action\n            max_field_tokens: 单个字段的最大token数（通常是max_context_window/2）\n            thinking: 当前的 thinking 内容\n            task_input: 任务需求描述\n            max_context_window: 最大上下文窗口（传递给字段压缩方法）\n            \n        Returns:\n            压缩后的action\n        \"\"\"\n        compressed_action = action.copy()\n        \n        # 压缩arguments中的大字段\n        if \"arguments\" in compressed_action:\n            compressed_args = {}\n            for k, v in compressed_action[\"arguments\"].items():\n                v_str = str(v)\n                v_tokens = self.count_tokens(v_str)\n                \n                if v_tokens > max_field_tokens:\n                    safe_print(f\"   🤖 LLM压缩arguments.{k}: {v_tokens} tokens → {max_field_tokens} tokens\")\n                    compressed_v = self._llm_compress_field(\n                        v_str, \n                        max_field_tokens, \n                        action.get(\"tool_name\", \"unknown\"),\n                        thinking=thinking,\n                        task_input=task_input,\n                        field_context=f\"工具 '{action.get('tool_name')}' 的参数 '{k}'\",\n                        max_context_window=max_context_window\n                    )\n                    compressed_args[k] = compressed_v\n                else:\n                    compressed_args[k] = v\n            compressed_action[\"arguments\"] = compressed_args\n        \n        # 压缩result.output\n        if \"result\" in compressed_action and \"output\" in compressed_action[\"result\"]:\n            output = compressed_action[\"result\"][\"output\"]\n            output_tokens = self.count_tokens(output)\n            \n            if output_tokens > max_field_tokens:\n                safe_print(f\"   🤖 LLM压缩result.output: {output_tokens} tokens → {max_field_tokens} tokens\")\n                # 构建字段上下文（包含工具参数信息）\n                args_summary = \", \".join([f\"{k}={v}\" for k, v in compressed_action.get(\"arguments\", {}).items()])\n                field_context = f\"工具 '{action.get('tool_name')}' 的执行结果 (参数: {args_summary})\"\n                \n                compressed_output = self._llm_compress_field(\n                    output, \n                    max_field_tokens, \n                    action.get(\"tool_name\", \"unknown\"),\n                    thinking=thinking,\n                    task_input=task_input,\n                    field_context=field_context,\n                    max_context_window=max_context_window\n                )\n                compressed_action[\"result\"][\"output\"] = compressed_output\n                compressed_action[\"result\"][\"_compressed\"] = True\n                compressed_action[\"result\"][\"_original_tokens\"] = output_tokens\n        \n        return compressed_action\n    \n    def _llm_compress_field(\n        self, \n        text: str, \n        target_tokens: int, \n        tool_name: str,\n        thinking: str = \"\",\n        task_input: str = \"\",\n        field_context: str = \"\",\n        max_context_window: int = None\n    ) -> str:\n        \"\"\"\n        使用LLM智能压缩单个字段\n        支持分段压缩：如果字段内容过大，自动分段处理\n        \n        Args:\n            text: 原始文本\n            target_tokens: 目标token数\n            tool_name: 工具名称（用于优化提示词）\n            thinking: 当前的 thinking 内容\n            task_input: 任务需求描述\n            field_context: 字段上下文（如 \"工具 'file_read' 的参数 'path'\"）\n            max_context_window: 最大上下文窗口（用于判断是否需要分段）\n            \n        Returns:\n            压缩后的文本\n        \"\"\"\n        try:\n            from services.llm_client import ChatMessage\n            \n            # 根据工具类型定制提示词\n            if \"parse\" in tool_name.lower() or \"read\" in tool_name.lower():\n                content_type = \"文档内容\"\n                focus = \"保留文档的关键章节、核心论点、重要数据和结论\"\n            elif \"execute\" in tool_name.lower() or \"run\" in tool_name.lower():\n                content_type = \"代码执行结果\"\n                focus = \"保留关键输出、错误信息、返回值和执行状态\"\n            elif \"search\" in tool_name.lower():\n                content_type = \"搜索结果\"\n                focus = \"保留最相关的搜索结果和关键匹配信息\"\n            else:\n                content_type = \"内容\"\n                focus = \"保留最重要的核心信息\"\n            \n            # 构建上下文信息\n            context_info = \"\"\n            if task_input:\n                context_info += f\"\\n<任务需求>\\n{task_input}\\n</任务需求>\\n\"\n            if thinking:\n                context_info += f\"\\n<当前进度与计划>\\n{thinking}\\n</当前进度与计划>\\n\"\n            if field_context:\n                context_info += f\"\\n<字段来源>\\n这是最新动作中 {field_context} 的内容\\n</字段来源>\\n\"\n            \n            # 检查字段大小，决定是否需要分段压缩\n            text_tokens = self.count_tokens(text)\n            context_tokens = self.count_tokens(context_info)\n            \n            # 获取压缩模型的上下文限制（从参数或LLM客户端获取）\n            compressor_context_limit = max_context_window or self.llm_client.max_context_window\n            overhead_tokens = 1000  # 提示词开销\n            available_tokens = int(compressor_context_limit * 0.6) - context_tokens - overhead_tokens\n            \n            # 如果文本过大，使用分段压缩\n            if text_tokens > available_tokens:\n                safe_print(f\"      📦 字段过大({text_tokens} tokens)，启用分段压缩\")\n                return self._chunked_compress_field(\n                    text, target_tokens, tool_name, content_type, focus,\n                    thinking, task_input, field_context, available_tokens\n                )\n            \n            # 文本大小合适，直接压缩\n            prompt = f\"\"\"你是智能内容压缩助手。请基于任务需求和当前进度，压缩以下{content_type}。\n\n{context_info}\n\n<待压缩的{content_type}>\n{text}\n</待压缩的{content_type}>\n\n压缩要求：\n1. **目标长度**: 严格控制在 {target_tokens} tokens 以内\n2. **智能筛选**: \n   - 根据 thinking 中的任务进度，判断哪些信息对未完成的任务有价值\n   - {focus}\n   - 丢弃与当前任务目标无关的内容\n3. **优先保留**:\n   - 与任务目标直接相关的关键信息\n   - 重要的文件路径、数据、结果\n   - 后续步骤需要引用的内容\n4. **可以丢弃**:\n   - 冗余的细节和重复信息\n   - 与任务无关的探索性内容\n   - 中间过程的调试信息\n5. **格式要求**:\n   - 保持信息的连贯性和可读性\n   - 使用总结和提炼，而非简单截断\n   - 如果有结构化内容（表格、列表），保留关键部分\n\n请直接输出压缩后的内容（不要额外说明）：\"\"\"\n            \n            history = [ChatMessage(role=\"user\", content=prompt)]\n            \n            compressor_model = self._resolve_compressor_model()\n            response = self.llm_client.chat(\n                history=history,\n                model=compressor_model,\n                system_prompt=f\"你是智能内容压缩助手。目标：将{content_type}压缩到{target_tokens} tokens，同时保留核心信息。\",\n                tool_list=[],  # 空列表表示不使用工具\n                tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n                max_tokens=self.max_tokens,\n                debug_task_id=self.debug_task_id,\n                debug_label=\"action_compressor\",\n            )\n            \n            compressed = response.output if response.status == \"success\" else text[:1000] + \"\\n[压缩失败，仅保留前1000字符]\"\n            \n            # 验证压缩效果\n            actual_tokens = self.count_tokens(compressed)\n            safe_print(f\"      压缩效果: {actual_tokens}/{target_tokens} tokens ({actual_tokens/target_tokens*100:.1f}%)\")\n            \n            return compressed\n            \n        except Exception as e:\n            safe_print(f\"⚠️ LLM压缩失败，使用fallback: {e}\")\n            # fallback：首尾保留\n            return self._fallback_compress(text, target_tokens)\n    \n    def _chunked_compress_field(\n        self,\n        text: str,\n        target_tokens: int,\n        tool_name: str,\n        content_type: str,\n        focus: str,\n        thinking: str,\n        task_input: str,\n        field_context: str,\n        chunk_size_tokens: int\n    ) -> str:\n        \"\"\"\n        分段压缩字段内容\n        \n        Args:\n            text: 原始文本\n            target_tokens: 最终目标token数\n            tool_name: 工具名称\n            content_type: 内容类型描述\n            focus: 压缩重点\n            thinking: thinking内容\n            task_input: 任务输入\n            field_context: 字段上下文\n            chunk_size_tokens: 每段的最大token数\n            \n        Returns:\n            压缩后的文本\n        \"\"\"\n        from services.llm_client import ChatMessage\n        \n        # 按段落或固定字符数分割文本\n        # 简单策略：按\\n\\n分割段落，如果段落太大则按字符数分割\n        paragraphs = text.split('\\n\\n')\n        \n        chunks = []\n        current_chunk = []\n        current_chunk_tokens = 0\n        \n        for para in paragraphs:\n            para_tokens = self.count_tokens(para)\n            \n            # 如果单个段落就超过chunk大小，需要强制分割\n            if para_tokens > chunk_size_tokens:\n                if current_chunk:\n                    chunks.append('\\n\\n'.join(current_chunk))\n                    current_chunk = []\n                    current_chunk_tokens = 0\n                \n                # 按字符数强制分割大段落\n                chars_per_chunk = int(chunk_size_tokens * 3)  # 粗略估计\n                for i in range(0, len(para), chars_per_chunk):\n                    chunk_text = para[i:i+chars_per_chunk]\n                    chunks.append(chunk_text)\n            else:\n                if current_chunk_tokens + para_tokens > chunk_size_tokens and current_chunk:\n                    chunks.append('\\n\\n'.join(current_chunk))\n                    current_chunk = [para]\n                    current_chunk_tokens = para_tokens\n                else:\n                    current_chunk.append(para)\n                    current_chunk_tokens += para_tokens\n        \n        if current_chunk:\n            chunks.append('\\n\\n'.join(current_chunk))\n        \n        safe_print(f\"         分成 {len(chunks)} 段进行字段压缩\")\n        \n        # 构建上下文信息\n        context_info = \"\"\n        if task_input:\n            context_info += f\"\\n<任务需求>\\n{task_input}\\n</任务需求>\\n\"\n        if thinking:\n            context_info += f\"\\n<当前进度与计划>\\n{thinking}\\n</当前进度与计划>\\n\"\n        if field_context:\n            context_info += f\"\\n<字段来源>\\n这是最新动作中 {field_context} 的内容\\n</字段来源>\\n\"\n        \n        # 压缩每个chunk\n        chunk_results = []\n        target_per_chunk = target_tokens // len(chunks)\n        \n        for i, chunk in enumerate(chunks):\n            safe_print(f\"         压缩字段第 {i+1}/{len(chunks)} 段...\")\n            \n            prompt = f\"\"\"你是智能内容压缩助手。这是分段压缩的第 {i+1}/{len(chunks)} 段{content_type}。\n\n{context_info}\n\n<本段内容>\n{chunk}\n</本段内容>\n\n压缩要求：\n1. **目标长度**: 严格控制在 {target_per_chunk} tokens 以内\n2. **智能筛选**: {focus}\n3. **优先保留**: 关键信息、重要数据、文件路径\n4. **格式要求**: 保持连贯性，使用总结而非截断\n\n请直接输出本段的压缩结果：\"\"\"\n            \n            history = [ChatMessage(role=\"user\", content=prompt)]\n            \n            try:\n                compressor_model = self._resolve_compressor_model()\n                response = self.llm_client.chat(\n                    history=history,\n                    model=compressor_model,\n                    system_prompt=f\"压缩专家。目标：将本段压缩到{target_per_chunk} tokens。\",\n                    tool_list=[],  # 空列表表示不使用工具\n                    tool_choice=self._resolve_compressor_tool_choice(compressor_model),\n                    max_tokens=self.max_tokens,\n                    debug_task_id=self.debug_task_id,\n                    debug_label=\"action_compressor\",\n                )\n                \n                if response.status == \"success\":\n                    chunk_results.append(response.output)\n                    safe_print(f\"            ✅ 第{i+1}段压缩成功\")\n                else:\n                    chunk_results.append(chunk[:500] + \"\\n[本段压缩失败]\")\n                    safe_print(f\"            ⚠️ 第{i+1}段压缩失败\")\n            except Exception as e:\n                chunk_results.append(chunk[:500] + \"\\n[本段压缩异常]\")\n                safe_print(f\"            ❌ 第{i+1}段压缩异常: {e}\")\n        \n        # 合并结果\n        final_result = '\\n\\n---\\n\\n'.join(chunk_results)\n        \n        safe_print(f\"         ✅ 字段分段压缩完成，共{len(chunks)}段\")\n        \n        return final_result\n    \n    def _fallback_compress(self, text: str, max_tokens: int) -> str:\n        \"\"\"\n        备用压缩方案（首尾保留法）- 当LLM压缩失败时使用\n        \"\"\"\n        if self.encoding:\n            tokens = self.encoding.encode(text)\n            head_count = int(max_tokens * 0.1)\n            tail_count = int(max_tokens * 0.1)\n            head_tokens = tokens[:head_count]\n            tail_tokens = tokens[-tail_count:]\n            head_text = self.encoding.decode(head_tokens)\n            tail_text = self.encoding.decode(tail_tokens)\n            omitted = len(tokens) - head_count - tail_count\n            return f\"{head_text}\\n\\n[中间省略约{omitted}个tokens]\\n\\n{tail_text}\"\n        else:\n            # 简单字符截取\n            chars = int(max_tokens * 2)\n            head = chars // 2\n            tail = chars // 2\n            return f\"{text[:head]}\\n\\n[中间省略]\\n\\n{text[-tail:]}\"\n\n\nif __name__ == \"__main__\":\n    safe_print(\"✅ ActionCompressor模块加载成功\")\n    safe_print(\"\\n压缩策略：\")\n    safe_print(\"1. 历史actions → LLM总结为5k tokens\")\n    safe_print(\"2. 最新action → 保留结构，LLM智能压缩大字段到50% max_window\")\n    safe_print(\"3. 备用方案 → 首尾保留法（当LLM失败时）\")\n"
  },
  {
    "path": "services/context_compressor_backup.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n上下文压缩服务 - 智能压缩历史动作\n策略：总结历史 + 保留最新\nemmm主要是保底的压缩，直接截取的方法，目前是被弃用的\n\"\"\"\n\nimport sys\nimport json\nfrom typing import List, Dict\nfrom pathlib import Path\n\n# 确保可以导入其他模块\nif __name__ == \"__main__\":\n    sys.path.insert(0, str(Path(__file__).parent.parent))\n\nfrom services.llm_client import SimpleLLMClient, ChatMessage\n\ntry:\n    import tiktoken\n    HAS_TIKTOKEN = True\nexcept ImportError:\n    HAS_TIKTOKEN = False\n    safe_print(\"⚠️ tiktoken未安装，将使用简单估算方法\")\n\n\nclass ContextCompressor:\n    \"\"\"上下文压缩器\"\"\"\n    \n    def __init__(self):\n        \"\"\"初始化压缩器\"\"\"\n        self.llm_client = SimpleLLMClient()\n        \n        # 初始化tiktoken编码器\n        if HAS_TIKTOKEN:\n            self.encoding = tiktoken.get_encoding(\"cl100k_base\")\n        else:\n            self.encoding = None\n    \n    def count_tokens(self, text: str) -> int:\n        \"\"\"统计文本的token数\"\"\"\n        if self.encoding:\n            return len(self.encoding.encode(text))\n        else:\n            # 简单估算：中文1.5字符/token，英文4字符/token\n            chinese_chars = sum(1 for c in text if '\\u4e00' <= c <= '\\u9fff')\n            other_chars = len(text) - chinese_chars\n            return int(chinese_chars / 1.5 + other_chars / 4)\n    \n    def compress_action_history(\n        self,\n        action_history: List[Dict],\n        max_allowed_tokens: int\n    ) -> List[Dict]:\n        \"\"\"\n        压缩历史动作\n        \n        策略：\n        1. 保留最近1条action（完整）\n        2. 总结之前所有action为一段话\n        3. 如果最近1条超过(max_allowed - 20k)，分段压缩它\n        \n        Args:\n            action_history: 原始动作历史\n            max_allowed_tokens: 允许的最大token数\n            \n        Returns:\n            压缩后的动作历史\n        \"\"\"\n        if not action_history:\n            return []\n        \n        if len(action_history) == 1:\n            # 只有一条，检查是否需要压缩\n            single_action = action_history[0]\n            single_tokens = self.count_tokens(json.dumps(single_action, ensure_ascii=False))\n            \n            if single_tokens > max_allowed_tokens - 20000:\n                safe_print(f\"🔄 单条action过大 ({single_tokens} tokens)，进行分段压缩\")\n                return [self._compress_large_action(single_action, max_allowed_tokens - 20000)]\n            else:\n                return action_history\n        \n        # 多条action的情况\n        recent_action = action_history[-1]  # 最近的一条\n        historical_actions = action_history[:-1]  # 之前的所有\n        \n        # 检查最近一条的大小\n        recent_tokens = self.count_tokens(json.dumps(recent_action, ensure_ascii=False))\n        \n        if recent_tokens > max_allowed_tokens - 20000:\n            # 最近一条本身就太大，需要压缩\n            safe_print(f\"🔄 最近action过大 ({recent_tokens} tokens)，进行分段压缩\")\n            compressed_recent = self._compress_large_action(recent_action, max_allowed_tokens - 20000)\n            \n            # 历史部分总结\n            if historical_actions:\n                summary_action = self._summarize_historical_actions(historical_actions)\n                return [summary_action, compressed_recent]\n            else:\n                return [compressed_recent]\n        else:\n            # 最近一条正常，总结历史\n            summary_action = self._summarize_historical_actions(historical_actions)\n            \n            # 检查总大小\n            total_tokens = self.count_tokens(json.dumps([summary_action, recent_action], ensure_ascii=False))\n            \n            if total_tokens <= max_allowed_tokens:\n                return [summary_action, recent_action]\n            else:\n                # 总结也太大了，进一步压缩总结\n                safe_print(f\"⚠️ 总结后仍超限 ({total_tokens} tokens)，使用极简总结\")\n                # 直接返回一个超简单的总结 + 最近action\n                simple_summary = self._create_simple_summary(historical_actions)\n                return [simple_summary, recent_action]\n    \n    def _summarize_historical_actions(self, actions: List[Dict]) -> Dict:\n        \"\"\"\n        将历史actions总结为一段话\n        \n        Args:\n            actions: 历史action列表\n            \n        Returns:\n            一个特殊的\"总结action\"\n        \"\"\"\n        try:\n            # 构建历史摘要\n            summary_text = f\"历史共{len(actions)}个动作：\\n\"\n            \n            # 统计工具使用情况\n            tool_counts = {}\n            for action in actions:\n                tool_name = action.get(\"tool_name\", \"unknown\")\n                tool_counts[tool_name] = tool_counts.get(tool_name, 0) + 1\n            \n            summary_text += \"\\n工具调用统计：\\n\"\n            for tool, count in tool_counts.items():\n                summary_text += f\"- {tool}: {count}次\\n\"\n            \n            # 提取关键结果\n            summary_text += \"\\n关键结果：\\n\"\n            for i, action in enumerate(actions[-5:], 1):  # 最后5个的摘要\n                tool_name = action.get(\"tool_name\", \"\")\n                status = action.get(\"result\", {}).get(\"status\", \"unknown\")\n                summary_text += f\"{i}. {tool_name} - {status}\\n\"\n            \n            # 调用LLM进行智能总结\n            prompt = f\"\"\"请将以下历史动作总结为一段简洁的描述（不超过500 tokens）：\n\n{summary_text}\n\n历史动作详情（JSON格式）：\n{json.dumps(actions, ensure_ascii=False, indent=2)[:5000]}...\n\n要求：\n1. 总结完成了什么工作\n2. 关键的输出和文件\n3. 重要的发现或结果\n4. 简洁但完整\n\n请用中文总结：\"\"\"\n            \n            history = [ChatMessage(role=\"user\", content=prompt)]\n            \n            response = self.llm_client.chat(\n                history=history,\n                model=self.llm_client.models[0],\n                system_prompt=\"你是一个专业的内容总结助手。\",\n                tool_list=[],\n                tool_choice=\"auto\"\n            )\n            \n            if response.status == \"success\":\n                summary = response.output\n            else:\n                summary = summary_text  # 使用统计摘要作为备用\n            \n            # 创建总结action\n            return {\n                \"tool_name\": \"_historical_summary\",\n                \"arguments\": {\n                    \"action_count\": len(actions),\n                    \"summary_method\": \"llm_summarization\"\n                },\n                \"result\": {\n                    \"status\": \"success\",\n                    \"output\": f\"[历史动作总结] {summary}\",\n                    \"_is_summary\": True,\n                    \"_summarized_count\": len(actions)\n                }\n            }\n        \n        except Exception as e:\n            safe_print(f\"⚠️ 总结失败: {e}\")\n            # 失败时使用简单统计\n            return self._create_simple_summary(actions)\n    \n    def _create_simple_summary(self, actions: List[Dict]) -> Dict:\n        \"\"\"创建简单的统计总结（不调用LLM）\"\"\"\n        tool_counts = {}\n        for action in actions:\n            tool_name = action.get(\"tool_name\", \"unknown\")\n            tool_counts[tool_name] = tool_counts.get(tool_name, 0) + 1\n        \n        summary = f\"历史共{len(actions)}个动作。\"\n        summary += \"工具使用: \" + \", \".join([f\"{t}({c}次)\" for t, c in tool_counts.items()])\n        \n        return {\n            \"tool_name\": \"_historical_summary\",\n            \"arguments\": {\"action_count\": len(actions)},\n            \"result\": {\n                \"status\": \"success\",\n                \"output\": f\"[历史动作简要总结] {summary}\",\n                \"_is_summary\": True,\n                \"_summarized_count\": len(actions)\n            }\n        }\n    \n    def _compress_large_action(self, action: Dict, max_tokens: int) -> Dict:\n        \"\"\"\n        压缩单个超大action\n        \n        策略：只压缩result.output部分\n        \n        Args:\n            action: 原始action\n            max_tokens: 最大允许token数\n            \n        Returns:\n            压缩后的action\n        \"\"\"\n        tool_name = action.get(\"tool_name\", \"\")\n        arguments = action.get(\"arguments\", {})\n        result = action.get(\"result\", {})\n        \n        output = result.get(\"output\", \"\")\n        output_tokens = self.count_tokens(output)\n        \n        if output_tokens > max_tokens:\n            safe_print(f\"   压缩{tool_name}的output: {output_tokens} tokens → 目标 {max_tokens} tokens\")\n            \n            # 策略：首尾保留法（使用tiktoken精确截取）\n            if self.encoding:\n                # 使用tiktoken精确截取\n                tokens = self.encoding.encode(output)\n                \n                # 首尾各保留40%的目标token（总共80%）\n                head_tokens_count = int(max_tokens * 0.4)\n                tail_tokens_count = int(max_tokens * 0.4)\n                \n                head_tokens = tokens[:head_tokens_count]\n                tail_tokens = tokens[-tail_tokens_count:]\n                \n                head_text = self.encoding.decode(head_tokens)\n                tail_text = self.encoding.decode(tail_tokens)\n                \n                middle_info = f\"\\n\\n[中间省略约 {output_tokens - max_tokens} tokens]\\n\\n\"\n                \n                compressed_output = head_text + middle_info + tail_text\n            else:\n                # 没有tiktoken，简单截断（保守估计）\n                chars_to_keep = int(max_tokens * 2)  # 1 token ≈ 2字符\n                head_chars = chars_to_keep // 2\n                tail_chars = chars_to_keep // 2\n                \n                compressed_output = output[:head_chars] + \"\\n\\n[中间省略]\\n\\n\" + output[-tail_chars:]\n            \n            # 验证压缩效果\n            compressed_tokens = self.count_tokens(compressed_output)\n            safe_print(f\"   压缩结果: {compressed_tokens} tokens (压缩比: {compressed_tokens/output_tokens*100:.1f}%)\")\n            \n            return {\n                \"tool_name\": tool_name,\n                \"arguments\": arguments,\n                \"result\": {\n                    **result,\n                    \"output\": compressed_output,\n                    \"_compressed\": True,\n                    \"_original_tokens\": output_tokens,\n                    \"_compressed_tokens\": compressed_tokens\n                },\n                \"timestamp\": action.get(\"timestamp\", \"\")\n            }\n        \n        return action\n\n\nif __name__ == \"__main__\":\n    # 测试时不实际运行LLM，只测试逻辑\n    safe_print(\"✅ ContextCompressor模块加载成功\")\n    safe_print(\"功能：\")\n    safe_print(\"  1. 总结历史actions为一段话\")\n    safe_print(\"  2. 保留最近1条action\")\n    safe_print(\"  3. 如果最近1条超大，使用首尾保留法压缩\")\n    safe_print(\"\\n策略：历史总结 + 最新完整 = 最佳平衡\")\n"
  },
  {
    "path": "services/llm_client.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\n简化的LLM客户端 - 使用LiteLLM统一接口\n\"\"\"\n\nimport os\nimport yaml\nimport time\nimport json\nimport copy\nimport re\nimport threading\nfrom queue import Empty, Queue\nfrom typing import Callable, List, Dict, Any, Optional\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom pathlib import Path\nfrom litellm import completion  # 直接导入completion函数\nimport litellm\n\nfrom utils.user_paths import (\n    ensure_user_llm_config_exists,\n    get_task_file_prefix,\n    get_user_conversations_dir,\n    get_user_runtime_dir,\n)\n\n\n@dataclass\nclass ChatMessage:\n    \"\"\"聊天消息\"\"\"\n    role: str\n    content: str\n\n\n@dataclass\nclass ToolCall:\n    \"\"\"工具调用\"\"\"\n    id: str          \n    name: str\n    arguments: Dict[str, Any]\n\n\n@dataclass\nclass LLMResponse:\n    \"\"\"LLM响应\"\"\"\n    status: str  # \"success\" or \"error\"\n    output: str\n    tool_calls: List[ToolCall]\n    model: str\n    finish_reason: str\n    usage: Optional[Dict] = None\n    error_information: str = \"\"\n    reasoning_content: str = \"\"  # 模型的推理/思考内容（如 Claude thinking, Deepseek reasoning）\n    thinking_blocks: Optional[List[Dict]] = None  # Anthropic 专用的 thinking_blocks\n\n\n_RAW_TOOL_CALLS_SECTION_BEGIN = \"<|tool_calls_section_begin|>\"\n_RAW_TOOL_CALLS_SECTION_END = \"<|tool_calls_section_end|>\"\n_RAW_TOOL_CALL_PATTERN = re.compile(\n    r\"<\\|tool_call_begin\\|>(.*?)<\\|tool_call_argument_begin\\|>(.*?)<\\|tool_call_end\\|>\",\n    re.DOTALL,\n)\n\n\ndef _marker_prefix_overlap(text: str, marker: str) -> int:\n    \"\"\"返回 text 尾部与 marker 前缀的最大重叠长度，用于流式解析跨 chunk 标记。\"\"\"\n    if not text or not marker:\n        return 0\n    max_size = min(len(text), len(marker) - 1)\n    for size in range(max_size, 0, -1):\n        if text.endswith(marker[:size]):\n            return size\n    return 0\n\n\nclass _EmbeddedToolCallStreamState:\n    \"\"\"过滤模型直接吐出的原始 tool-call section，同时保留其中的原始标记以便后续解析。\"\"\"\n\n    def __init__(self):\n        self._pending = \"\"\n        self._captured_parts: List[str] = []\n        self._in_section = False\n\n    def feed(self, text: str) -> str:\n        if not text:\n            return \"\"\n\n        self._pending += text\n        visible_parts: List[str] = []\n\n        while self._pending:\n            if not self._in_section:\n                start_idx = self._pending.find(_RAW_TOOL_CALLS_SECTION_BEGIN)\n                if start_idx >= 0:\n                    if start_idx > 0:\n                        visible_parts.append(self._pending[:start_idx])\n                    self._pending = self._pending[start_idx + len(_RAW_TOOL_CALLS_SECTION_BEGIN):]\n                    self._in_section = True\n                    continue\n\n                hold = _marker_prefix_overlap(self._pending, _RAW_TOOL_CALLS_SECTION_BEGIN)\n                if hold:\n                    visible_parts.append(self._pending[:-hold])\n                    self._pending = self._pending[-hold:]\n                else:\n                    visible_parts.append(self._pending)\n                    self._pending = \"\"\n                break\n\n            end_idx = self._pending.find(_RAW_TOOL_CALLS_SECTION_END)\n            if end_idx >= 0:\n                if end_idx > 0:\n                    self._captured_parts.append(self._pending[:end_idx])\n                self._pending = self._pending[end_idx + len(_RAW_TOOL_CALLS_SECTION_END):]\n                self._in_section = False\n                continue\n\n            hold = _marker_prefix_overlap(self._pending, _RAW_TOOL_CALLS_SECTION_END)\n            if hold:\n                self._captured_parts.append(self._pending[:-hold])\n                self._pending = self._pending[-hold:]\n            else:\n                self._captured_parts.append(self._pending)\n                self._pending = \"\"\n            break\n\n        return \"\".join(visible_parts)\n\n    def finish(self) -> tuple[str, str]:\n        visible_tail = \"\"\n        if self._pending:\n            if self._in_section:\n                self._captured_parts.append(self._pending)\n            else:\n                visible_tail = self._pending\n        self._pending = \"\"\n        return visible_tail, \"\".join(self._captured_parts)\n\n\ndef _coerce_text_content(value: Any) -> str:\n    \"\"\"Best-effort flattening for OpenAI-compatible message content payloads.\"\"\"\n    if value is None:\n        return \"\"\n    if isinstance(value, str):\n        return value\n    if isinstance(value, list):\n        parts: List[str] = []\n        for item in value:\n            if isinstance(item, str):\n                parts.append(item)\n                continue\n            if isinstance(item, dict):\n                if item.get(\"type\") == \"text\":\n                    parts.append(str(item.get(\"text\") or \"\"))\n                    continue\n                if \"text\" in item:\n                    parts.append(str(item.get(\"text\") or \"\"))\n                    continue\n            parts.append(str(item))\n        return \"\".join(parts)\n    return str(value)\n\n\nclass SimpleLLMClient:\n    \"\"\"简化的LLM客户端 - 基于LiteLLM\"\"\"\n    \n    def __init__(self, llm_config_path: str = None, tools_config_path: str = None):\n        \"\"\"\n        初始化LLM客户端\n        \n        Args:\n            llm_config_path: LLM配置文件路径\n            tools_config_path: 工具配置文件路径\n        \"\"\"\n        # 加载LLM配置\n        if llm_config_path is None:\n            llm_config_path = ensure_user_llm_config_exists()\n        \n        if not os.path.exists(llm_config_path):\n            raise FileNotFoundError(f\"LLM配置文件不存在: {llm_config_path}\")\n        \n        with open(llm_config_path, 'r', encoding='utf-8') as f:\n            self.config = yaml.safe_load(f)\n        \n        # 读取配置\n        self.base_url = self.config.get(\"base_url\", \"\")\n        self.api_key = self.config.get(\"api_key\", \"\")\n        self.temperature = self.config.get(\"temperature\", 0)\n        self.max_tokens = self.config.get(\"max_tokens\", 0)\n        self.max_context_window = self.config.get(\"max_context_window\", 100000)  # 上下文窗口限制\n        \n        # 读取超时配置（默认值：600s, 20s, 20s）\n        self.timeout = self.config.get(\"timeout\", 600)  # LiteLLM 原生：总超时\n        self.stream_timeout = self.config.get(\"stream_timeout\", 20)  # LiteLLM 原生：流式超时\n        self.first_chunk_timeout = self.config.get(\"first_chunk_timeout\", 20)  # 应用层强制：首包超时\n        \n        # 解析模型配置（支持两种格式）\n        self.models = []  # 模型名称列表\n        self.figure_models = []\n        self.compressor_models = []\n        self.model_configs = {}  # 模型名称 -> 配置字典\n        self.default_models = {}\n\n        self._parse_models_config(self.config.get(\"models\", []), self.models, \"execution\")\n        self._parse_models_config(self.config.get(\"figure_models\", []), self.figure_models, \"image_generation\")\n        self._parse_models_config(self.config.get(\"compressor_models\", []), self.compressor_models, \"compressor\")\n        self.thinking_models = []\n        self._parse_models_config(self.config.get(\"thinking_models\", []), self.thinking_models, \"thinking\")\n        # 如果没有配置 thinking_models，回退到 models\n        if not self.thinking_models:\n            self.thinking_models = list(self.models)\n        self.default_models.setdefault(\"thinking\", self.thinking_models[0] if self.thinking_models else \"\")\n        self.read_figure_models = []\n        self._parse_models_config(self.config.get(\"read_figure_models\", []), self.read_figure_models, \"read_figure\")\n        if not self.read_figure_models:\n            self.read_figure_models = list(self.models)\n        self.default_models.setdefault(\"read_figure\", self.read_figure_models[0] if self.read_figure_models else \"\")\n        self.default_models.setdefault(\"execution\", self.models[0] if self.models else \"\")\n        self.default_models.setdefault(\"image_generation\", self.figure_models[0] if self.figure_models else \"\")\n        self.default_models.setdefault(\"compressor\", self.compressor_models[0] if self.compressor_models else \"\")\n        self.default_tool_choice = self._load_default_tool_choice()\n        # 多模态配置\n        self.multimodal = self.config.get(\"multimodal\", False)\n        self.compressor_multimodal = self.config.get(\"compressor_multimodal\", False)\n        \n        if not self.models:\n            raise ValueError(\"未配置可用模型列表\")\n\n        if not self.api_key:\n            safe_print(\"⚠️ 未配置全局 API 密钥，将依赖模型级 api_key/base_url 或本地无密钥模型配置。\")\n        \n        # 加载工具配置\n        self.tools_config = {}\n        if tools_config_path and os.path.exists(tools_config_path):\n            with open(tools_config_path, 'r', encoding='utf-8') as f:\n                self.tools_config = yaml.safe_load(f)\n        \n        # 配置LiteLLM\n        litellm.set_verbose = False  # 关闭详细日志\n        litellm.drop_params = True  # 自动丢弃不支持的参数（如Anthropic不支持parallel_tool_calls）\n        \n        safe_print(f\"✅ LLM客户端初始化成功（LiteLLM）\")\n        safe_print(f\"   Base URL: {self.base_url}\")\n        safe_print(f\"   可用模型: {len(self.models)} 个\")\n        safe_print(f\"   Figure模型: {len(self.figure_models)} 个\")\n        safe_print(f\"   Compressor模型: {len(self.compressor_models)} 个\")\n        safe_print(f\"   默认Temperature: {self.temperature}\")\n        safe_print(f\"   默认Max Tokens: {self.max_tokens}\")\n        safe_print(f\"   超时配置: timeout={self.timeout}s, stream_timeout={self.stream_timeout}s, first_chunk_timeout={self.first_chunk_timeout}s\")\n        safe_print(f\"   多模态: multimodal={self.multimodal}, compressor_multimodal={self.compressor_multimodal}\")\n\n    def _emit_stream_reset(\n        self,\n        stream_callback: Optional[Callable[[Dict[str, Any]], None]],\n        *,\n        model: str,\n        debug_label: str,\n        attempt: int,\n        reason: str,\n    ) -> None:\n        if not stream_callback:\n            return\n        try:\n            stream_callback({\n                \"kind\": \"reset\",\n                \"text\": \"\",\n                \"model\": model,\n                \"debug_label\": debug_label,\n                \"attempt\": int(attempt or 1),\n                \"reason\": str(reason or \"retry\"),\n            })\n        except Exception:\n            pass\n\n    def _fetch_response_and_first_chunk_with_timeout(\n        self,\n        *,\n        kwargs: Dict[str, Any],\n        timeout_sec: int,\n    ):\n        \"\"\"在 daemon 线程里获取 response iterator 和首包，避免超时后主线程被 executor join 卡住。\"\"\"\n        result_queue: Queue = Queue(maxsize=1)\n\n        def _worker():\n            try:\n                iterator = completion(**kwargs)\n                first = next(iterator)\n                result_queue.put((\"ok\", (iterator, first)))\n            except Exception as exc:\n                result_queue.put((\"error\", exc))\n\n        worker = threading.Thread(\n            target=_worker,\n            name=\"llm-first-chunk\",\n            daemon=True,\n        )\n        worker.start()\n\n        try:\n            status, payload = result_queue.get(timeout=timeout_sec)\n        except Empty:\n            raise TimeoutError(\n                f\"连接建立或首包接收超时（超过 {timeout_sec}s）- 可能原因：httpx连接池死锁、网络断开、服务器无响应\"\n            )\n\n        if status == \"error\":\n            raise payload\n\n        return payload\n    \n    def _parse_models_config(self, models_config: List, target_list: List, category: str):\n        \"\"\"\n        解析模型配置，支持两种格式：\n        1. 字符串格式：直接是模型名称\n        2. 对象格式：包含 name 和额外参数\n        \n        Args:\n            models_config: 原始模型配置列表\n            target_list: 目标列表（self.models, self.figure_models 等）\n        \"\"\"\n        default_name = \"\"\n        for model_item in models_config:\n            if isinstance(model_item, str):\n                # 简单格式：直接是模型名称\n                target_list.append(model_item)\n                self.model_configs[model_item] = {}\n                if not default_name:\n                    default_name = model_item\n            elif isinstance(model_item, dict):\n                # 对象格式：包含额外参数\n                model_name = model_item.get(\"name\")\n                if not model_name:\n                    safe_print(f\"⚠️ 模型配置缺少 'name' 字段，跳过: {model_item}\")\n                    continue\n                \n                target_list.append(model_name)\n                # 保存除 name 外的所有参数\n                extra_params = {k: v for k, v in model_item.items() if k != \"name\"}\n                self.model_configs[model_name] = extra_params\n                if extra_params.get(\"default\") is True:\n                    default_name = model_name\n                elif not default_name:\n                    default_name = model_name\n\n                if extra_params:\n                    safe_print(f\"   📝 模型 {model_name} 配置了额外参数: {list(extra_params.keys())}\")\n            else:\n                safe_print(f\"⚠️ 不支持的模型配置格式，跳过: {model_item}\")\n        if default_name:\n            self.default_models[category] = default_name\n\n    def _load_default_tool_choice(self) -> Dict[str, str]:\n        raw = self.config.get(\"tool_choice\", {}) or {}\n        defaults = {\n            \"execution\": \"required\",\n            \"thinking\": \"none\",\n            \"compressor\": \"none\",\n            \"image_generation\": \"none\",\n            \"read_figure\": \"none\",\n        }\n        if isinstance(raw, dict):\n            for key, value in raw.items():\n                normalized = str(value or \"\").strip().lower()\n                if normalized in {\"required\", \"auto\", \"none\"}:\n                    defaults[str(key)] = normalized\n        elif isinstance(raw, str):\n            normalized = str(raw).strip().lower()\n            if normalized in {\"required\", \"auto\", \"none\"}:\n                defaults[\"execution\"] = normalized\n        return defaults\n\n    def get_default_tool_choice(self, category: str = \"execution\") -> str:\n        return self.default_tool_choice.get(category, \"required\")\n\n    @staticmethod\n    def _is_kimi_tool_model(model: str, tool_count: int = 0) -> bool:\n        if int(tool_count or 0) <= 0:\n            return False\n        normalized = str(model or \"\").strip().lower()\n        if not normalized:\n            return False\n        return \"kimi\" in normalized or \"moonshot\" in normalized\n\n    @staticmethod\n    def _contains_embedded_tool_markup(text: str) -> bool:\n        value = str(text or \"\")\n        if not value:\n            return False\n        markers = (\n            \"<|tool_calls_section_begin\",\n            \"<|tool_calls_section_end\",\n            \"<|tool_call_begin|>\",\n            \"<|tool_call_argument_begin|>\",\n        )\n        return any(marker in value for marker in markers)\n\n    @staticmethod\n    def _embedded_tool_name_from_id(raw_call_id: str) -> str:\n        token = str(raw_call_id or \"\").strip()\n        if not token:\n            return \"\"\n        if token.startswith(\"functions.\"):\n            token = token[len(\"functions.\"):]\n        if \":\" in token:\n            token = token.rsplit(\":\", 1)[0]\n        return token.strip()\n\n    def _parse_embedded_tool_calls(self, raw_markup: str) -> List[ToolCall]:\n        text = str(raw_markup or \"\")\n        if not text or \"<|tool_call_begin|>\" not in text:\n            return []\n\n        final_calls: List[ToolCall] = []\n        for idx, match in enumerate(_RAW_TOOL_CALL_PATTERN.finditer(text)):\n            raw_call_id = str(match.group(1) or \"\").strip()\n            raw_args = str(match.group(2) or \"\").strip()\n            tool_name = self._embedded_tool_name_from_id(raw_call_id)\n            if not tool_name:\n                continue\n\n            args: Dict[str, Any]\n            if not raw_args:\n                args = {}\n            else:\n                try:\n                    args = json.loads(raw_args)\n                except json.JSONDecodeError:\n                    args = self._try_fix_json(raw_args) or {}\n\n            final_calls.append(\n                ToolCall(\n                    id=raw_call_id or f\"embedded_call_{idx}\",\n                    name=tool_name,\n                    arguments=args,\n                )\n            )\n        return final_calls\n\n    @staticmethod\n    def _merge_tool_calls(primary: List[ToolCall], secondary: List[ToolCall]) -> List[ToolCall]:\n        merged: List[ToolCall] = []\n        seen = set()\n        for tool_call in list(primary or []) + list(secondary or []):\n            args_key = json.dumps(tool_call.arguments or {}, ensure_ascii=False, sort_keys=True)\n            key = (str(tool_call.id or \"\").strip(), str(tool_call.name or \"\").strip(), args_key)\n            fallback_key = (str(tool_call.name or \"\").strip(), args_key)\n            if key in seen or fallback_key in seen:\n                continue\n            seen.add(key)\n            seen.add(fallback_key)\n            merged.append(tool_call)\n        return merged\n\n    def _extract_embedded_tool_calls_and_visible_text(\n        self,\n        content_text: str,\n        reasoning_text: str,\n    ) -> tuple[str, str, List[ToolCall], bool]:\n        content_state = _EmbeddedToolCallStreamState()\n        reasoning_state = _EmbeddedToolCallStreamState()\n\n        visible_content = content_state.feed(str(content_text or \"\"))\n        visible_content_tail, embedded_content_markup = content_state.finish()\n        visible_content += visible_content_tail\n\n        visible_reasoning = reasoning_state.feed(str(reasoning_text or \"\"))\n        visible_reasoning_tail, embedded_reasoning_markup = reasoning_state.finish()\n        visible_reasoning += visible_reasoning_tail\n\n        marker_seen = (\n            self._contains_embedded_tool_markup(content_text)\n            or self._contains_embedded_tool_markup(reasoning_text)\n        )\n\n        embedded_tool_calls = self._merge_tool_calls(\n            self._parse_embedded_tool_calls(embedded_content_markup),\n            self._parse_embedded_tool_calls(embedded_reasoning_markup),\n        )\n\n        if marker_seen and not embedded_tool_calls:\n            embedded_tool_calls = self._merge_tool_calls(\n                self._parse_embedded_tool_calls(str(content_text or \"\")),\n                self._parse_embedded_tool_calls(str(reasoning_text or \"\")),\n            )\n\n        return visible_content, visible_reasoning, embedded_tool_calls, marker_seen\n\n    def _parse_non_stream_tool_calls(self, tool_calls_payload: Any) -> List[ToolCall]:\n        final_tool_calls: List[ToolCall] = []\n        if not tool_calls_payload:\n            return final_tool_calls\n\n        for idx, tool_call in enumerate(tool_calls_payload):\n            tc_id = str(getattr(tool_call, \"id\", \"\") or (tool_call.get(\"id\", \"\") if isinstance(tool_call, dict) else \"\")).strip()\n            function_payload = getattr(tool_call, \"function\", None)\n            if function_payload is None and isinstance(tool_call, dict):\n                function_payload = tool_call.get(\"function\")\n\n            function_name = \"\"\n            function_arguments = \"\"\n\n            if function_payload is not None:\n                function_name = str(\n                    getattr(function_payload, \"name\", \"\")\n                    or (function_payload.get(\"name\", \"\") if isinstance(function_payload, dict) else \"\")\n                ).strip()\n                function_arguments = str(\n                    getattr(function_payload, \"arguments\", \"\")\n                    or (function_payload.get(\"arguments\", \"\") if isinstance(function_payload, dict) else \"\")\n                )\n\n            args: Dict[str, Any]\n            if not function_arguments:\n                args = {}\n            else:\n                try:\n                    args = json.loads(function_arguments)\n                except json.JSONDecodeError:\n                    args = self._try_fix_json(function_arguments) or {}\n\n            if not function_name:\n                continue\n\n            final_tool_calls.append(\n                ToolCall(\n                    id=tc_id or f\"call_{idx}\",\n                    name=function_name,\n                    arguments=args,\n                )\n            )\n\n        return final_tool_calls\n\n    def _chat_internal_non_stream(\n        self,\n        kwargs: Dict[str, Any],\n        model: str,\n        tools_definition: List[Dict[str, Any]],\n        debug_label: str,\n    ) -> LLMResponse:\n        safe_print(f\"   🌊 正在调用LLM (non-stream fallback, timeout={kwargs['timeout']}s)...\")\n        response = completion(**kwargs)\n\n        response_model = str(getattr(response, \"model\", \"\") or model)\n        choices = getattr(response, \"choices\", None) or []\n        if not choices:\n            return LLMResponse(\n                status=\"error\",\n                output=\"\",\n                tool_calls=[],\n                model=response_model,\n                finish_reason=\"empty\",\n                error_information=\"Empty non-stream response\",\n            )\n\n        choice = choices[0]\n        message = getattr(choice, \"message\", None)\n        if message is None and isinstance(choice, dict):\n            message = choice.get(\"message\")\n\n        finish_reason = str(getattr(choice, \"finish_reason\", \"\") or (choice.get(\"finish_reason\", \"\") if isinstance(choice, dict) else \"\") or \"stop\")\n        raw_content = _coerce_text_content(getattr(message, \"content\", None) if message is not None else None)\n        if not raw_content and isinstance(message, dict):\n            raw_content = _coerce_text_content(message.get(\"content\"))\n\n        raw_reasoning = str(\n            (getattr(message, \"reasoning_content\", None) if message is not None else None)\n            or (message.get(\"reasoning_content\") if isinstance(message, dict) else \"\")\n            or \"\"\n        )\n\n        structured_tool_calls = self._parse_non_stream_tool_calls(\n            getattr(message, \"tool_calls\", None) if message is not None else None\n        )\n        if not structured_tool_calls and isinstance(message, dict):\n            structured_tool_calls = self._parse_non_stream_tool_calls(message.get(\"tool_calls\"))\n\n        visible_content, visible_reasoning, embedded_tool_calls, raw_marker_seen = self._extract_embedded_tool_calls_and_visible_text(\n            raw_content,\n            raw_reasoning,\n        )\n        final_tool_calls = self._merge_tool_calls(structured_tool_calls, embedded_tool_calls)\n\n        if final_tool_calls and finish_reason in {\"\", \"unknown\", \"stop\"}:\n            finish_reason = \"tool_calls\"\n\n        if self._is_kimi_tool_model(model, len(tools_definition)) and raw_marker_seen and not final_tool_calls:\n            return LLMResponse(\n                status=\"error\",\n                output=visible_content,\n                tool_calls=[],\n                model=response_model,\n                finish_reason=finish_reason or \"tool_calls_parse_failed\",\n                error_information=\"Kimi raw tool-call markup detected but no executable tool call could be parsed\",\n                reasoning_content=visible_reasoning,\n            )\n\n        return LLMResponse(\n            status=\"success\",\n            output=visible_content,\n            tool_calls=final_tool_calls,\n            model=response_model,\n            finish_reason=finish_reason,\n            reasoning_content=visible_reasoning,\n        )\n    def _build_debug_messages_snapshot(self, messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:\n        \"\"\"构建适合落盘的消息快照，避免大字段让调试文件无限膨胀。\"\"\"\n        debug_msgs = copy.deepcopy(messages)\n        for debug_msg in debug_msgs:\n            content = debug_msg.get(\"content\")\n            if isinstance(content, list):\n                for part in content:\n                    if isinstance(part, dict) and part.get(\"type\") == \"image_url\":\n                        image_url = part.get(\"image_url\", {}).get(\"url\", \"\")\n                        if len(image_url) > 120:\n                            part[\"image_url\"][\"url\"] = image_url[:80] + f\"...({len(image_url)} chars)\"\n            elif isinstance(content, str) and len(content) > 2000:\n                if (debug_msg.get(\"role\") or \"\").lower() != \"system\":\n                    debug_msg[\"content\"] = content[:2000] + f\"\\n...({len(content)} chars total)\"\n        return debug_msgs\n\n    def _resolve_debug_output_path(self, debug_task_id: Optional[str]) -> Path:\n        debug_task_id = str(debug_task_id or \"\").strip()\n        if debug_task_id:\n            conversations_dir = get_user_conversations_dir()\n            conversations_dir.mkdir(parents=True, exist_ok=True)\n            return conversations_dir / f\"{get_task_file_prefix(debug_task_id)}_llm_debug.jsonl\"\n\n        debug_dir = get_user_runtime_dir() / \"debug\"\n        debug_dir.mkdir(parents=True, exist_ok=True)\n        return debug_dir / \"llm_debug.jsonl\"\n\n    def _append_debug_record(\n        self,\n        messages: List[Dict[str, Any]],\n        model: str,\n        debug_task_id: Optional[str] = None,\n        debug_label: str = \"execution\",\n        tool_choice: Optional[str] = None,\n        tool_count: int = 0,\n        emit_tokens: Optional[str] = None,\n    ) -> None:\n        debug_file = self._resolve_debug_output_path(debug_task_id)\n        payload = {\n            \"timestamp\": datetime.now().isoformat(),\n            \"pid\": os.getpid(),\n            \"task_id\": str(debug_task_id or \"\").strip() or None,\n            \"debug_label\": str(debug_label or \"execution\").strip() or \"execution\",\n            \"model\": model,\n            \"message_count\": len(messages),\n            \"tool_count\": tool_count,\n            \"tool_choice\": tool_choice,\n            \"emit_tokens\": emit_tokens,\n            \"messages\": self._build_debug_messages_snapshot(messages),\n        }\n        with open(debug_file, \"a\", encoding=\"utf-8\") as debug_handle:\n            debug_handle.write(json.dumps(payload, ensure_ascii=False) + \"\\n\")\n        safe_print(f\"📋 DEBUG: messages JSONL 已追加到 {debug_file}\")\n\n    def resolve_model(self, category: str = \"execution\", preferred: Optional[str] = None) -> str:\n        model_groups = {\n            \"execution\": self.models,\n            \"thinking\": self.thinking_models or self.models,\n            \"compressor\": self.compressor_models or self.models,\n            \"image_generation\": self.figure_models or self.models,\n            \"read_figure\": self.read_figure_models or self.models,\n        }\n        candidates = model_groups.get(category, self.models) or self.models\n        preferred_name = str(preferred or \"\").strip()\n        if preferred_name and preferred_name in candidates:\n            return preferred_name\n        default_name = str(self.default_models.get(category) or \"\").strip()\n        if default_name and default_name in candidates:\n            return default_name\n        return candidates[0] if candidates else preferred_name\n\n    def resolve_tool_choice(\n        self,\n        category: str = \"execution\",\n        model: Optional[str] = None,\n        requested: Optional[str] = None,\n    ) -> str:\n        normalized_requested = str(requested or \"\").strip().lower()\n        if normalized_requested in {\"required\", \"auto\", \"none\"}:\n            return normalized_requested\n\n        normalized_model = str(model or \"\").strip()\n        if normalized_model:\n            model_choice = str(self.model_configs.get(normalized_model, {}).get(\"tool_choice\", \"\")).strip().lower()\n            if model_choice in {\"required\", \"auto\", \"none\"}:\n                return model_choice\n\n        return self.get_default_tool_choice(category)\n    \n    def chat(\n        self,\n        history: List,\n        model: str,\n        system_prompt: str,\n        tool_list: List[str],\n        tool_choice: Optional[str] = None,\n        temperature: float = None,\n        max_tokens: int = None,\n        max_retries: int = 3,\n        emit_tokens: str = None,\n        debug_task_id: Optional[str] = None,\n        debug_label: str = \"execution\",\n        stream_callback: Optional[Callable[[Dict[str, Any]], None]] = None,\n    ) -> LLMResponse:\n        \"\"\"\n        调用LLM进行对话 (增强版：支持流式监控、自动重试、参数修复)\n        \n        Args:\n            history: 对话历史，支持两种格式：\n                     1. List[ChatMessage] - 传统格式（向后兼容）\n                     2. List[Dict] - OpenAI原生格式，支持 tool/assistant/multimodal 消息\n            model: 模型名称\n            system_prompt: 系统提示词\n            tool_list: 可用工具列表\n            tool_choice: 工具选择策略；None 表示由调用方或模型配置决定\n            temperature: 温度参数（None则使用配置文件默认值）\n            max_tokens: 最大token数（None则使用配置文件默认值）\n            max_retries: 最大重试次数（默认3次，即总共最多4次尝试）\n            debug_task_id: 可选 task_id；传入后调试请求会按 task 追加到 conversations 目录\n            debug_label: 调试记录标签，用于区分 execution / thinking / compressor 等来源\n            \n        Returns:\n            LLMResponse对象\n        \"\"\"\n        # 使用配置文件的默认值\n        if temperature is None:\n            temperature = self.temperature\n        if max_tokens is None:\n            max_tokens = self.max_tokens\n        \n        # 重试循环\n        last_error = None\n        fixed_system_prompt = system_prompt  # 可能会被修复的 system prompt\n        type_fix_attempted = False  # 是否已尝试类型修复\n        \n        for retry_count in range(max_retries + 1):\n            if retry_count > 0:\n                safe_print(f\"   🔄 LLM重试 {retry_count}/{max_retries}...\")\n                time.sleep(2 * retry_count)  # 指数退避：2秒, 4秒, 6秒\n                self._emit_stream_reset(\n                    stream_callback,\n                    model=model,\n                    debug_label=debug_label,\n                    attempt=retry_count + 1,\n                    reason=\"retry\",\n                )\n                \n                # 根据上次错误生成提示（帮助 LLM 避免重复错误）\n                if last_error:\n                    retry_hint = self._generate_retry_hint(last_error.error_information, retry_count)\n                    if retry_hint:\n                        fixed_system_prompt = system_prompt + \"\\n\\n\" + retry_hint\n                        safe_print(f\"   📝 添加错误提醒: {retry_hint[:80]}...\")\n            \n            # 调用内部实现\n            response = self._chat_internal(\n                history, model, fixed_system_prompt, tool_list, \n                tool_choice, temperature, max_tokens, emit_tokens, debug_task_id, debug_label, stream_callback,\n                retry_count + 1,\n            )\n            \n            # 如果成功，直接返回\n            if response.status == \"success\":\n                if retry_count > 0 or type_fix_attempted:\n                    safe_print(f\"   ✅ 重试成功 (第{retry_count + 1}次尝试)\")\n                return response\n            \n            # 检查是否是工具参数类型错误（优先处理，不消耗重试次数）\n            if not type_fix_attempted and (\"did not match schema\" in response.error_information or \"expected array, but got string\" in response.error_information):\n                safe_print(f\"   🔧 检测到工具参数类型错误，尝试自动修复...\")\n                \n                # 尝试修复 system prompt（添加参数类型提示）\n                fix_hint = self._generate_type_fix_hint(response.error_information)\n                if fix_hint:\n                    fixed_system_prompt = system_prompt + \"\\n\\n\" + fix_hint\n                    safe_print(f\"   📝 已添加参数类型提示，立即重试...\")\n                    type_fix_attempted = True\n                    last_error = response\n                    self._emit_stream_reset(\n                        stream_callback,\n                        model=model,\n                        debug_label=debug_label,\n                        attempt=retry_count + 1,\n                        reason=\"type_fix_retry\",\n                    )\n                    \n                    # 立即重试，不计入retry_count\n                    response = self._chat_internal(\n                        history, model, fixed_system_prompt, tool_list, \n                        tool_choice, temperature, max_tokens, emit_tokens, debug_task_id, debug_label, stream_callback,\n                        retry_count + 1,\n                    )\n                    \n                    if response.status == \"success\":\n                        safe_print(f\"   ✅ 参数类型修复成功！\")\n                        return response\n                    else:\n                        safe_print(f\"   ⚠️ 修复后仍失败，继续常规重试...\")\n                        last_error = response\n                        continue\n            \n            # 所有错误都重试（包括API余额不足、密钥错误等）\n            error_type = self._get_error_type(response.error_information)\n            safe_print(f\"   ⚠️ {error_type} (第{retry_count + 1}次)\")\n            last_error = response\n\n            if not self._is_retriable_error(response.error_information):\n                safe_print(f\"   ⛔ 非可恢复错误，停止重试\")\n                raise Exception(f\"LLM 调用失败（不可重试）: {response.error_information}\")\n            \n            if retry_count < max_retries:\n                continue  # 继续重试\n            else:\n                # 达到最大重试次数，抛出异常（让上层捕获并触发错误处理）\n                safe_print(f\"   ❌ 已达到最大重试次数 ({max_retries + 1})\")\n                error_msg = f\"LLM 调用失败（已重试 {max_retries + 1} 次）: {response.error_information}\"\n                raise Exception(error_msg)\n                # return response\n        \n        # 所有重试都失败了\n        safe_print(f\"   ❌ LLM调用失败（已重试{max_retries + 1}次）\")\n        return last_error\n    \n    def _chat_internal(\n        self,\n        history: List,\n        model: str,\n        system_prompt: str,\n        tool_list: List[str],\n        tool_choice: str,\n        temperature: float,\n        max_tokens: int,\n        emit_tokens: str = None,\n        debug_task_id: Optional[str] = None,\n        debug_label: str = \"execution\",\n        stream_callback: Optional[Callable[[Dict[str, Any]], None]] = None,\n        attempt_index: int = 1,\n    ) -> LLMResponse:\n        \"\"\"\n        LLM调用的内部实现（使用 LiteLLM 原生超时机制）\n        \n        Args:\n            emit_tokens: 控制是否向 JSONL 事件流发送流式 token。\n                None - 不发送（默认，用于 compressor 等辅助调用）\n                \"token\" - 发送 content delta 为 token 事件（主 Agent 调用）\n                \"thinking\" - 发送 content delta 为 thinking_token 事件（Thinking Agent 调用）\n            debug_task_id: 可选 task_id；传入后调试请求会按 task 追加到 conversations 目录\n            debug_label: 调试记录标签，用于区分不同类型的 LLM 调用\n        \"\"\"\n        try:\n            def _emit_stream_chunk(kind: str, text: str, current_model: str):\n                if not stream_callback or (kind != \"reset\" and not text):\n                    return\n                try:\n                    stream_callback({\n                        \"kind\": str(kind or \"content\"),\n                        \"text\": text,\n                        \"model\": current_model,\n                        \"debug_label\": debug_label,\n                        \"attempt\": int(attempt_index or 1),\n                    })\n                except Exception:\n                    pass\n\n            # 构建工具定义（OpenAI格式）\n            tools_definition = self._build_tools_definition(tool_list)\n            \n            # 转换消息格式（兼容 ChatMessage 和 dict 两种输入）\n            messages = [{\"role\": \"system\", \"content\": system_prompt}]\n            for msg in history:\n                if isinstance(msg, dict):\n                    # dict 格式：直接使用（支持 tool/assistant/multimodal 等复杂消息）\n                    messages.append(msg)\n                elif isinstance(msg, ChatMessage):\n                    # ChatMessage 格式：转换为 dict（向后兼容）\n                    messages.append({\"role\": msg.role, \"content\": msg.content})\n                else:\n                    # 尝试 duck typing\n                    messages.append({\"role\": msg.role, \"content\": msg.content})\n            \n            # 获取模型级别的配置（可覆盖全局 api_key 和 base_url）\n            model_extra_params = self.model_configs.get(model, {})\n            model_api_key = model_extra_params.get(\"api_key\", self.api_key)\n            model_base_url = model_extra_params.get(\"base_url\", self.base_url)\n            \n            # 构建请求参数\n            kwargs = {\n                \"model\": model,\n                \"messages\": messages,\n                \"temperature\": temperature,\n                \"api_key\": model_api_key,\n                \"stream\": True,  # 启用流式模式\n                # --- LiteLLM 原生超时设定（从配置文件读取）---\n                \"timeout\": self.timeout,              # 建立连接及整体响应的最大等待时间（秒）\n                \"stream_timeout\": self.stream_timeout,  # 两个流式数据块（chunk）之间的最大间隔时间（秒）\n            }\n            \n            # 只在 base_url 非空时添加 api_base\n            if model_base_url:\n                kwargs[\"api_base\"] = model_base_url\n            \n            # 只在max_tokens > 0时添加\n            if max_tokens > 0:\n                kwargs[\"max_tokens\"] = max_tokens\n            \n            # 添加工具定义（只有当工具列表非空时才添加工具相关参数）\n            if tools_definition:\n                # 工具列表非空：正常添加工具参数\n                kwargs[\"tools\"] = tools_definition\n                if tool_choice == \"required\":\n                    kwargs[\"tool_choice\"] = \"required\"\n                kwargs[\"parallel_tool_calls\"] = False\n            # 注意：当 tools_definition 为空时，即使 tool_choice=\"none\" 也不添加任何参数\n            # 这避免了 API 错误：When using `tool_choice`, `tools` must be set\n\n            # === DEBUG: 将完整 messages 结构追加写入 task 级 JSONL ===\n            try:\n                self._append_debug_record(\n                    messages=messages,\n                    model=model,\n                    debug_task_id=debug_task_id,\n                    debug_label=debug_label,\n                    tool_choice=tool_choice,\n                    tool_count=len(tools_definition),\n                    emit_tokens=emit_tokens,\n                )\n            except Exception as debug_error:\n                safe_print(f\"⚠️ DEBUG 写入失败: {debug_error}\")\n            # === END DEBUG ===\n            \n            # 添加模型特定的额外参数（api_key 和 base_url 已在上面处理）\n            if model_extra_params:\n                if \"provider\" in model_extra_params:\n                    if \"extra_body\" not in kwargs:\n                        kwargs[\"extra_body\"] = {}\n                    kwargs[\"extra_body\"][\"provider\"] = model_extra_params[\"provider\"]\n                \n                if \"extra_headers\" in model_extra_params:\n                    kwargs[\"extra_headers\"] = model_extra_params[\"extra_headers\"]\n                \n                if \"extra_body\" in model_extra_params:\n                    if \"extra_body\" not in kwargs:\n                        kwargs[\"extra_body\"] = {}\n                    kwargs[\"extra_body\"].update(model_extra_params[\"extra_body\"])\n\n            # 发起流式请求（LiteLLM 会根据 timeout 和 stream_timeout 自动管理超时）\n            def _should_retry_without_required_tool_choice(msg: str) -> bool:\n                m = (msg or \"\").lower()\n                if \"tool_choice\" not in m:\n                    return False\n                incompat_markers = [\n                    \"thinking\",\n                    \"thinking mode\",\n                    \"reasoning\",\n                    \"does not support\",\n                    \"unsupported\",\n                    \"invalidparameter\",\n                    \"required or object\",\n                    \"required\",\n                    \"object\",\n                ]\n                return any(marker in m for marker in incompat_markers)\n\n            # 有些 OpenAI-compatible（如月之暗面/Kimi）会拒绝 tool_choice=required + thinking。\n            # 这里做一次“就地兼容重试”：第一次失败则移除 tool_choice，保持 tools 但不强制 required。\n            # 这类报错文案在不同 provider/router 上差异很大，因此只要是 tool_choice=required\n            # 且首轮失败信息明确指向 tool_choice 不兼容，就降级为 auto 重试一次。\n            tried_kimi_non_stream_fallback = False\n            for _compat_try in range(3):\n                safe_print(f\"   🌊 正在调用LLM (timeout={kwargs['timeout']}s, stream_timeout={kwargs['stream_timeout']}s)...\")\n                safe_print(f\"   📨 请求模型: {model}\")\n                safe_print(f\"   🛠️ 工具数量: {len(tools_definition)}\")\n                safe_print(f\"   📝 消息数: {len(messages)}\")\n                request_start_time = time.time()\n\n                if not kwargs.get(\"stream\", True):\n                    return self._chat_internal_non_stream(\n                        kwargs=kwargs,\n                        model=model,\n                        tools_definition=tools_definition,\n                        debug_label=debug_label,\n                    )\n\n                # 累积变量\n                accumulated_content = \"\"\n                accumulated_reasoning_content = \"\"  # reasoning/thinking 内容\n                visible_content = \"\"\n                visible_reasoning_content = \"\"\n                accumulated_tool_calls = {}  # index -> {id, name, arguments}\n                finish_reason = \"unknown\"\n                response_model = model\n                chunk_count = 0\n                content_stream_state = _EmbeddedToolCallStreamState()\n                reasoning_stream_state = _EmbeddedToolCallStreamState()\n\n                def _emit_visible_text(kind: str, text: str):\n                    if not text:\n                        return\n\n                    _emit_stream_chunk(kind, text, response_model)\n\n                    if kind == \"content\":\n                        try:\n                            safe_print(text, end=\"\", flush=True)\n                            if emit_tokens:\n                                from utils.event_emitter import get_event_emitter as _get_ee\n                                _ee = _get_ee()\n                                if _ee.enabled:\n                                    if emit_tokens == \"thinking\":\n                                        _ee.emit({\"type\": \"thinking_token\", \"text\": text})\n                                    else:\n                                        _ee.token(text)\n                        except Exception:\n                            pass\n                        return\n\n                    try:\n                        if emit_tokens:\n                            from utils.event_emitter import get_event_emitter as _get_ee_reason\n                            _ee_reason = _get_ee_reason()\n                            if _ee_reason.enabled:\n                                event_type = \"thinking_token\" if emit_tokens == \"thinking\" else \"reasoning_token\"\n                                _ee_reason.emit({\"type\": event_type, \"text\": text})\n                    except Exception:\n                        pass\n\n                try:\n                    # --- 强制首包超时检测（包含 completion 调用以防止连接池死锁）---\n                    try:\n                        # 强制首包超时时间（秒），包含连接建立+首包接收，防止 httpx 连接池死锁\n                        first_chunk_timeout = self.first_chunk_timeout  # 从配置文件读取\n                        response_iterator, first_chunk = self._fetch_response_and_first_chunk_with_timeout(\n                            kwargs=kwargs,\n                            timeout_sec=first_chunk_timeout,\n                        )\n\n                        # 处理首包\n                        chunk_count += 1\n                        latency = time.time() - request_start_time\n                        safe_print(f\"   ⚡️ 首包延迟: {latency:.2f}s\")\n\n                        # 处理首包逻辑\n                        if hasattr(first_chunk, 'model'):\n                            response_model = first_chunk.model\n\n                        if first_chunk.choices:\n                            delta = first_chunk.choices[0].delta\n                            if hasattr(delta, 'content') and delta.content:\n                                accumulated_content += delta.content\n                                visible_piece = content_stream_state.feed(delta.content)\n                                visible_content += visible_piece\n                                _emit_visible_text(\"content\", visible_piece)\n\n                            # 累积 reasoning_content（thinking/reasoning 模型）\n                            if hasattr(delta, 'reasoning_content') and delta.reasoning_content:\n                                accumulated_reasoning_content += delta.reasoning_content\n                                visible_reasoning_piece = reasoning_stream_state.feed(delta.reasoning_content)\n                                visible_reasoning_content += visible_reasoning_piece\n                                _emit_visible_text(\"reasoning\", visible_reasoning_piece)\n\n                            if hasattr(delta, 'tool_calls') and delta.tool_calls:\n                                for tc in delta.tool_calls:\n                                    idx = tc.index\n                                    if idx not in accumulated_tool_calls:\n                                        accumulated_tool_calls[idx] = {\"id\": \"\", \"name\": \"\", \"arguments\": \"\"}\n                                    if tc.id:\n                                        accumulated_tool_calls[idx][\"id\"] = tc.id\n                                    if tc.function and tc.function.name:\n                                        accumulated_tool_calls[idx][\"name\"] += tc.function.name\n                                    if tc.function and tc.function.arguments:\n                                        accumulated_tool_calls[idx][\"arguments\"] += tc.function.arguments\n\n                            if first_chunk.choices[0].finish_reason:\n                                finish_reason = first_chunk.choices[0].finish_reason\n\n                    except StopIteration:\n                        safe_print(\"   ⚠️ 响应为空（无数据块）\")\n                        return LLMResponse(\n                            status=\"error\",\n                            output=\"\",\n                            tool_calls=[],\n                            model=model,\n                            finish_reason=\"empty\",\n                            error_information=\"Empty response - no chunks received\"\n                        )\n\n                    # --- 继续处理剩余 chunk ---\n                    for chunk in response_iterator:\n                        chunk_count += 1\n\n                        if hasattr(chunk, 'model'):\n                            response_model = chunk.model\n\n                        if not chunk.choices:\n                            continue\n\n                        delta = chunk.choices[0].delta\n\n                        # A. 累积文本内容\n                        if hasattr(delta, 'content') and delta.content:\n                            accumulated_content += delta.content\n                            visible_piece = content_stream_state.feed(delta.content)\n                            visible_content += visible_piece\n                            _emit_visible_text(\"content\", visible_piece)\n\n                        # A2. 累积 reasoning_content（thinking/reasoning 模型）\n                        if hasattr(delta, 'reasoning_content') and delta.reasoning_content:\n                            accumulated_reasoning_content += delta.reasoning_content\n                            visible_reasoning_piece = reasoning_stream_state.feed(delta.reasoning_content)\n                            visible_reasoning_content += visible_reasoning_piece\n                            _emit_visible_text(\"reasoning\", visible_reasoning_piece)\n\n                        # B. 累积工具调用\n                        if hasattr(delta, 'tool_calls') and delta.tool_calls:\n                            for tc in delta.tool_calls:\n                                idx = tc.index\n                                if idx not in accumulated_tool_calls:\n                                    accumulated_tool_calls[idx] = {\"id\": \"\", \"name\": \"\", \"arguments\": \"\"}\n\n                                if tc.id:\n                                    accumulated_tool_calls[idx][\"id\"] = tc.id\n                                if tc.function and tc.function.name:\n                                    accumulated_tool_calls[idx][\"name\"] += tc.function.name\n                                if tc.function and tc.function.arguments:\n                                    accumulated_tool_calls[idx][\"arguments\"] += tc.function.arguments\n\n                        # C. 记录结束原因\n                        if chunk.choices[0].finish_reason:\n                            finish_reason = chunk.choices[0].finish_reason\n\n                    safe_print(f\"   ✅ 流式响应完成，共接收 {chunk_count} 个数据块\")\n\n                    visible_tail, embedded_content_markup = content_stream_state.finish()\n                    if visible_tail:\n                        visible_content += visible_tail\n                        _emit_visible_text(\"content\", visible_tail)\n\n                    visible_reasoning_tail, embedded_reasoning_markup = reasoning_stream_state.finish()\n                    if visible_reasoning_tail:\n                        visible_reasoning_content += visible_reasoning_tail\n                        _emit_visible_text(\"reasoning\", visible_reasoning_tail)\n\n                    # 构建最终的 ToolCall 对象列表\n                    final_tool_calls = []\n                    for idx in sorted(accumulated_tool_calls.keys()):\n                        tc_data = accumulated_tool_calls[idx]\n\n                        try:\n                            args_str = tc_data[\"arguments\"]\n                            if not args_str:\n                                args = {}\n                            else:\n                                args = json.loads(args_str)\n                        except json.JSONDecodeError as e:\n                            safe_print(f\"\\n⚠️ 工具参数JSON解析失败: {str(e)}\")\n                            safe_print(f\"   原始参数: {tc_data['arguments'][:200]}...\")\n\n                            args = self._try_fix_json(tc_data[\"arguments\"])\n                            if args:\n                                safe_print(f\"   ✅ JSON 自动修复成功\")\n                            else:\n                                safe_print(f\"   ❌ JSON 修复失败，使用空参数\")\n                                args = {}\n\n                        final_tool_calls.append(ToolCall(\n                            id=tc_data[\"id\"] or f\"call_{idx}\",\n                            name=tc_data[\"name\"],\n                            arguments=args\n                        ))\n\n                    sanitized_content, sanitized_reasoning, embedded_tool_calls, raw_marker_seen = self._extract_embedded_tool_calls_and_visible_text(\n                        accumulated_content,\n                        accumulated_reasoning_content,\n                    )\n                    final_tool_calls = self._merge_tool_calls(final_tool_calls, embedded_tool_calls)\n                    if final_tool_calls and finish_reason in {\"\", \"unknown\", \"stop\"}:\n                        finish_reason = \"tool_calls\"\n\n                    if (\n                        self._is_kimi_tool_model(model, len(tools_definition))\n                        and raw_marker_seen\n                        and not final_tool_calls\n                        and tools_definition\n                        and not tried_kimi_non_stream_fallback\n                    ):\n                        safe_print(\"⚠️ Kimi raw tool-call markup detected without parsed tool_calls; retrying once with non-stream mode...\")\n                        self._emit_stream_reset(\n                            stream_callback,\n                            model=response_model,\n                            debug_label=debug_label,\n                            attempt=attempt_index,\n                            reason=\"kimi_non_stream_fallback\",\n                        )\n                        kwargs[\"stream\"] = False\n                        tried_kimi_non_stream_fallback = True\n                        continue\n\n                    return LLMResponse(\n                        status=\"success\",\n                        output=sanitized_content,\n                        tool_calls=final_tool_calls,\n                        model=response_model,\n                        finish_reason=finish_reason,\n                        reasoning_content=sanitized_reasoning\n                    )\n\n                except Exception as _compat_e:\n                    _compat_msg = str(_compat_e)\n                    if (\n                        _compat_try == 0\n                        and kwargs.get(\"tool_choice\") == \"required\"\n                        and tools_definition\n                        and _should_retry_without_required_tool_choice(_compat_msg)\n                    ):\n                        safe_print(\"⚠️ 当前模型/路由不兼容 tool_choice=required，自动降级为 tool_choice=auto 重试一次...\")\n                        kwargs.pop(\"tool_choice\", None)\n                        continue\n                    raise\n        \n        except Exception as e:\n            # 捕获所有异常，包括 LiteLLM 抛出的超时异常\n            error_msg = str(e)\n            lowered_error_msg = error_msg.lower()\n            is_timeout = any(keyword in lowered_error_msg for keyword in [\"timeout\", \"timed out\", \"time out\"]) or \"超时\" in error_msg\n            \n            if is_timeout:\n                safe_print(f\"⏱️  LLM调用超时 (原生超时机制)\")\n                safe_print(f\"   超时详情: {error_msg}\")\n                safe_print(f\"   💡 提示: 如果频繁超时，可能是：\")\n                safe_print(f\"      1. 网络连接不稳定\")\n                safe_print(f\"      2. 上下文过长导致 API 响应缓慢\")\n                safe_print(f\"      3. API 服务商限流或过载\")\n            else:\n                safe_print(f\"❌ LLM调用异常: {error_msg}\")\n            \n            # 返回包含详细错误信息的响应\n            import traceback\n            error_detail = traceback.format_exc()\n            \n            return LLMResponse(\n                status=\"error\",\n                output=\"\",\n                tool_calls=[],\n                model=model,\n                finish_reason=\"timeout\" if is_timeout else \"error\",\n                error_information=f\"{error_msg}\\n\\nDetails:\\n{error_detail}\"\n            )\n    \n    def set_tools_config(self, tools_config: Dict):\n        \"\"\"\n        设置工具配置（从ConfigLoader传入）\n        \n        Args:\n            tools_config: 工具配置字典\n        \"\"\"\n        self.tools_config = tools_config\n    \n    def _try_fix_json(self, json_str: str) -> Dict:\n        \"\"\"\n        尝试修复常见的 JSON 格式错误\n        \n        Args:\n            json_str: 可能有问题的 JSON 字符串\n            \n        Returns:\n            解析后的字典，失败返回 None\n        \"\"\"\n        if not json_str or not json_str.strip():\n            return {}\n        \n        try:\n            # 策略 1: 去除尾部多余的逗号\n            fixed = json_str.strip()\n            if fixed.endswith(',}'):\n                fixed = fixed[:-2] + '}'\n            if fixed.endswith(',]'):\n                fixed = fixed[:-2] + ']'\n            \n            # 策略 2: 补全缺失的结束括号\n            open_braces = fixed.count('{')\n            close_braces = fixed.count('}')\n            if open_braces > close_braces:\n                fixed += '}' * (open_braces - close_braces)\n            \n            open_brackets = fixed.count('[')\n            close_brackets = fixed.count(']')\n            if open_brackets > close_brackets:\n                fixed += ']' * (open_brackets - close_brackets)\n            \n            # 策略 3: 尝试解析\n            result = json.loads(fixed)\n            return result\n        \n        except Exception:\n            # 所有修复策略都失败\n            return None\n    \n    def _generate_type_fix_hint(self, error_info: str) -> str:\n        \"\"\"\n        从错误信息中提取参数类型错误，生成修复提示\n        \n        Args:\n            error_info: 错误信息字符串\n            \n        Returns:\n            修复提示文本（添加到 system prompt）\n        \"\"\"\n        try:\n            import re\n            \n            # 提取工具名\n            tool_match = re.search(r\"tool (\\w+) did not match\", error_info)\n            if not tool_match:\n                return \"\"\n            tool_name = tool_match.group(1)\n            \n            # 提取所有参数错误（支持多个参数同时出错）\n            param_errors = re.findall(r\"`/([\\w_]+)`:\\s*expected\\s+(\\w+),\\s*but\\s+got\\s+(\\w+)\", error_info)\n            \n            if not param_errors:\n                return \"\"\n            \n            # 分类处理\n            null_params = []\n            type_mismatches = []\n            \n            for param_name, expected_type, actual_type in param_errors:\n                if actual_type == \"null\":\n                    null_params.append(param_name)\n                else:\n                    type_mismatches.append((param_name, expected_type, actual_type))\n            \n            hints = []\n            \n            # 处理 null 值错误\n            if null_params:\n                params_str = \"、\".join(null_params)\n                hints.append(f\"\"\"\n⚠️ 参数 null 值错误：\n工具 {tool_name} 的参数 {params_str} 被设置为 null\n\n重要规则：\n- 可选参数如果不需要，必须完全省略，不要传 null！\n- 错误示例: {{\"path\": \"file.txt\", \"start_line\": null}}  ❌\n- 正确示例: {{\"path\": \"file.txt\"}}  ✅\n\"\"\")\n            \n            # 处理类型不匹配错误\n            for param_name, expected_type, actual_type in type_mismatches:\n                safe_print(f\"   🔍 检测到: 工具 {tool_name}, 参数 {param_name}, 需要 {expected_type}, 得到 {actual_type}\")\n                \n                if expected_type == \"array\" and actual_type == \"string\":\n                    hints.append(f\"\"\"\n⚠️ 参数类型错误：\n工具 {tool_name} 的参数 {param_name} 必须是数组类型！\n- 错误: {{\"{param_name}\": \"value\"}}  ❌\n- 正确: {{\"{param_name}\": [\"value\"]}}  ✅\n\"\"\")\n                elif expected_type == \"string\" and actual_type == \"array\":\n                    hints.append(f\"\"\"\n⚠️ 参数类型错误：\n工具 {tool_name} 的参数 {param_name} 必须是字符串类型！\n- 错误: {{\"{param_name}\": [\"value\"]}}  ❌\n- 正确: {{\"{param_name}\": \"value\"}}  ✅\n\"\"\")\n                else:\n                    hints.append(f\"\"\"\n⚠️ 参数类型错误：\n工具 {tool_name} 的参数 {param_name} 需要 {expected_type}，实际得到 {actual_type}\n\"\"\")\n            \n            return \"\\n\".join(hints) if hints else \"\"\n        \n        except Exception as e:\n            safe_print(f\"   ⚠️ 生成修复提示失败: {e}\")\n            return \"\"\n    \n    def _get_error_type(self, error_info: str) -> str:\n        \"\"\"\n        从错误信息中提取友好的错误类型描述\n        \n        Args:\n            error_info: 错误信息字符串\n            \n        Returns:\n            友好的错误类型描述\n        \"\"\"\n        lowered = error_info.lower()\n        if \"timeout\" in lowered or \"timed out\" in lowered or \"time out\" in lowered or \"超时\" in error_info:\n            return \"连接超时\"\n        elif \"Internal Server Error\" in error_info:\n            return \"服务器内部错误\"\n        elif \"Failed to parse\" in error_info and \"JSON\" in error_info:\n            return \"JSON格式错误\"\n        elif \"expected integer, but got null\" in error_info:\n            return \"参数null值错误\"\n        elif \"expected array, but got string\" in error_info:\n            return \"参数类型错误(string→array)\"\n        elif \"expected string, but got array\" in error_info:\n            return \"参数类型错误(array→string)\"\n        elif \"did not match schema\" in error_info:\n            return \"参数校验失败\"\n        elif \"not in request.tools\" in error_info:\n            return \"工具不存在错误\"\n        elif \"Invalid API key\" in error_info or \"api_key\" in error_info.lower():\n            return \"API密钥错误\"\n        elif \"rate limit\" in error_info.lower():\n            return \"速率限制\"\n        elif \"insufficient\" in error_info.lower() or \"quota\" in error_info.lower():\n            return \"余额不足\"\n        else:\n            return \"未知错误\"\n\n    def _is_retriable_error(self, error_info: str) -> bool:\n        \"\"\"\n        仅对更可能因网络/服务端抖动恢复的错误继续重试。\n        \"\"\"\n        error_text = str(error_info or \"\")\n        lowered = error_text.lower()\n\n        non_retriable_markers = [\n            \"invalid api key\",\n            \"incorrect api key\",\n            \"authentication\",\n            \"unauthorized\",\n            \"permission denied\",\n            \"forbidden\",\n            \"insufficient\",\n            \"quota\",\n            \"credit balance\",\n            \"payment required\",\n            \"model not found\",\n            \"no such model\",\n            \"unknown model\",\n            \"context length\",\n            \"maximum context length\",\n            \"prompt is too long\",\n            \"content policy\",\n            \"safety system\",\n            \"did not match schema\",\n            \"expected array, but got string\",\n            \"expected string, but got array\",\n            \"expected integer, but got null\",\n            \"not in request.tools\",\n        ]\n        if any(marker in lowered for marker in non_retriable_markers):\n            return False\n\n        retriable_markers = [\n            \"timeout\",\n            \"timed out\",\n            \"time out\",\n            \"internal server error\",\n            \"server error\",\n            \"service unavailable\",\n            \"bad gateway\",\n            \"gateway timeout\",\n            \"connection reset\",\n            \"connection aborted\",\n            \"connection refused\",\n            \"connection error\",\n            \"temporarily unavailable\",\n            \"temporarily overloaded\",\n            \"overloaded\",\n            \"rate limit\",\n            \"too many requests\",\n            \"httpx\",\n        ]\n        if any(marker in lowered for marker in retriable_markers):\n            return True\n\n        # 对未知错误保守重试一次的价值通常高于直接放弃。\n        return True\n    \n    def _generate_retry_hint(self, error_info: str, retry_count: int) -> str:\n        \"\"\"\n        根据错误信息生成重试提示（添加到 system prompt）\n        \n        Args:\n            error_info: 错误信息字符串\n            retry_count: 当前重试次数\n            \n        Returns:\n            重试提示文本\n        \"\"\"\n        import re\n        \n        # 1. 服务器错误 - 静默重试（不需要提示 LLM）\n        if \"Internal Server Error\" in error_info:\n            return \"\"\n        \n        # 2. null 值错误 - 最常见\n        if \"but got null\" in error_info:\n            # 尝试提取所有 null 参数\n            null_params = re.findall(r\"`/([\\w_]+)`:\\s*expected\\s+\\w+,\\s*but\\s+got\\s+null\", error_info)\n            if null_params:\n                params_str = \"、\".join(null_params)\n                hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：参数 {params_str} 被设置为 null\n\n重要规则：\n- 可选参数如果不需要，必须完全省略，不要传递 null 值！\n- 错误示例: {{\"path\": \"file.txt\", \"start_line\": null}}  ❌\n- 正确示例: {{\"path\": \"file.txt\"}}  ✅ (直接省略 start_line)\n\n请重新生成工具调用，确保不传递 null 值。\n\"\"\"\n                return hint\n        \n        # 3. JSON 解析错误\n        if \"Failed to parse\" in error_info and \"JSON\" in error_info:\n            hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：工具参数 JSON 格式错误\n\nJSON 格式要求：\n- 所有键名必须用双引号：{{\"key\": \"value\"}}  ✅  {{key: \"value\"}}  ❌\n- 字符串值必须用双引号：{{\"path\": \"file.txt\"}}  ✅  {{\"path\": 'file.txt'}}  ❌\n- 不要有尾部逗号：{{\"a\": 1, \"b\": 2}}  ✅  {{\"a\": 1, \"b\": 2,}}  ❌\n- 特殊字符需要转义：{{\"path\": \"C:\\\\\\\\file.txt\"}}  ✅\n\n请重新生成工具调用，确保 JSON 格式正确。\n\"\"\"\n            return hint\n        \n        # 4. 工具不存在错误\n        if \"not in request.tools\" in error_info:\n            # 尝试提取工具名\n            tool_match = re.search(r\"attempted to call tool ['\\\"](\\w+)['\\\"]\", error_info)\n            wrong_tool = tool_match.group(1) if tool_match else \"某个工具\"\n            \n            hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：尝试调用不存在的工具 '{wrong_tool}'\n\n重要规则：\n- 只能调用提供的工具列表中的工具\n- 不要自己发明或假设存在某个工具\n- 仔细检查可用工具列表\n\n请重新生成工具调用，只使用已提供的工具。\n\"\"\"\n            return hint\n        \n        # 5. 类型不匹配（array vs string）\n        if \"expected array, but got string\" in error_info:\n            tool_match = re.search(r\"tool (\\w+) did not match\", error_info)\n            param_match = re.search(r\"`/([\\w_]+)`:\\s*expected array\", error_info)\n            \n            tool_name = tool_match.group(1) if tool_match else \"某工具\"\n            param_name = param_match.group(1) if param_match else \"某参数\"\n            \n            hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：工具 {tool_name} 的参数 {param_name} 类型错误\n\n类型要求：\n- 参数 {param_name} 必须是数组（array）类型\n- 错误示例: {{\"{param_name}\": \"value\"}}  ❌\n- 正确示例: {{\"{param_name}\": [\"value\"]}}  ✅\n\n请重新生成工具调用，使用数组格式（方括号包裹）。\n\"\"\"\n            return hint\n        \n        # 6. API 余额/密钥错误 - 也给提示（虽然重试可能无效）\n        if \"insufficient\" in error_info.lower() or \"quota\" in error_info.lower():\n            hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：API 余额不足或配额已用尽\n\n这可能是临时问题，正在重试...\n如果持续失败，请检查 API 账户状态。\n\"\"\"\n            return hint\n        \n        if \"Invalid API key\" in error_info or \"api_key\" in error_info.lower():\n            hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！原因：API 密钥错误或无效\n\n这可能是临时问题，正在重试...\n如果持续失败，请检查 API 密钥配置。\n\"\"\"\n            return hint\n        \n        # 7. 通用提示\n        hint = f\"\"\"\n⚠️ 第{retry_count}次重试警告：\n上次调用失败！错误信息：{error_info[:200]}\n\n请仔细检查工具调用的格式、参数类型和值，确保符合工具定义。\n\"\"\"\n        return hint\n    \n    def _build_tools_definition(self, tool_list: List[str]) -> List[Dict]:\n        \"\"\"构建工具定义（OpenAI格式）\"\"\"\n        if not self.tools_config:\n            return []\n        \n        tools = []\n        for tool_name in tool_list:\n            if tool_name in self.tools_config:\n                tool_config = self.tools_config[tool_name]\n                tools.append({\n                    \"type\": \"function\",\n                    \"function\": {\n                        \"name\": tool_config.get(\"name\", tool_name),\n                        \"description\": tool_config.get(\"description\", \"\"),\n                        \"parameters\": tool_config.get(\"parameters\", {})\n                    }\n                })\n        \n        return tools\n\n\nif __name__ == \"__main__\":\n    # 测试LLM客户端\n    try:\n        client = SimpleLLMClient()\n        safe_print(f\"✅ 可用模型: {client.models}\")\n        \n        # 测试简单调用\n        history = [ChatMessage(role=\"user\", content=\"你好\")]\n        response = client.chat(\n            history=history,\n            model=client.models[0],  # 使用第一个可用模型\n            system_prompt=\"你是一个AI助手，请使用工具来完成任务\",\n            tool_list=[\"dir_list\"],\n            tool_choice=\"required\"\n        )\n        \n        safe_print(f\"✅ 响应状态: {response.status}\")\n        safe_print(f\"✅ 工具调用数量: {len(response.output)}\")\n        if response.tool_calls:\n            safe_print(f\"✅ 第一个工具: {response.tool_calls[0].name}\")\n    except Exception as e:\n        safe_print(f\"❌ 测试失败: {e}\")\n        import traceback\n        traceback.print_exc()\n"
  },
  {
    "path": "services/thinking_agent.py",
    "content": "#!/usr/bin/env python3\nfrom utils.windows_compat import safe_print\n# -*- coding: utf-8 -*-\n\"\"\"\nThinking Agent - 任务进展分析服务\n\"\"\"\n\nfrom typing import Callable, Dict, List, Optional\nfrom services.llm_client import SimpleLLMClient, ChatMessage\nfrom utils.user_paths import get_runtime_settings\n\n\nclass ThinkingAgent:\n    \"\"\"思考Agent - 用于分析任务进展\"\"\"\n    \n    def __init__(self, preferred_model: Optional[str] = None, max_tokens: Optional[int] = None):\n        \"\"\"初始化Thinking Agent\"\"\"\n        # 使用简化的LLM客户端\n        self.llm_client = SimpleLLMClient()\n        runtime = get_runtime_settings()\n        self.window_steps = runtime.get(\"thinking_steps\", runtime.get(\"action_window_steps\", 10))\n        self.preferred_model = preferred_model\n        self.max_tokens = max_tokens\n        \n        # Thinking Agent的系统提示词\n        self.system_prompt = f\"\"\"你是一个agent行动的上下文管理专家，这个 agent 每次在清除动作历史之前会请你进行上下文整理。\n        上下文中包括你上次清理的成果在<当前进度思考>标签内。你的任务是产出“写入<当前进度思考>标签内部的正文内容”，不要输出<当前进度思考>外层标签本身。无论是否首次构造，都统一遵循这一条。你必须要考虑到{self.window_steps}步后，历史动作会被立刻舍弃，因此\n        你规划的<next_n_steps>必须足够具体，同时增量工作！\n        '''例子‘’‘\n        前面带#符号的为注释内容，是对你进行对应区域的原则指导的，不是实际内容。下面只是中文版样例，具体语言参考<用户最新输入>区域的语言。\n            <todo_list>\n            #如果是首次构造则用来设计本智能体在接受本次任务的todo拆解。注意不要越界，罗列不属于被分析子智能体的分配任务。\n            #如果不是首次构造，则分析当前进度，更新这个区域的内容。\n            #todo不可以太粗，尽量每个todo都在十步之内完成。\n            例子：\n            原内容：\n            1. 使用 XXX 工具总结 X1 文档保存在 document_summary.md:[done]\n            2. 使用 XXX 工具总结 X2 文档保存在 document_summary.md:[done]\n            3. 使用 XXX 工具总结 X3 文档保存在 document_summary.md:[ongoing：已经知道 X3.pdf的位置为 ./papers/XX3.pdf]\n            4. 使用 XXX 工具总结 X4 文档保存在 document_summary.md:[waiting]\n            ...\n            10. 分析document_summary.md，构造文章大纲保存在 outline.md:[waiting]\n            #在观察到历史动作分析了文档 3 和文档 4 并存了内容之后，更新原内容为\n            更新后的内容：\n            1. 使用 XXX 工具总结 X1 文档保存在 document_summary.md:[done]\n            2. 使用 XXX 工具总结 X2 文档保存在 document_summary.md:[done]\n            3. 使用 XXX 工具总结 X3 文档保存在 document_summary.md:[done]\n            4. 使用 XXX 工具总结 X4 文档保存在 document_summary.md:[done]\n            ...\n            10. 分析document_summary.md，构造实验大纲保存在 outline.md:[waiting]\n            </todo_list>\n            <有效文件描述>\n            #任何未来某个todo，或者任务，或者未来其他 agent 可能要用的文件的文件地址和描述，以及用途，如果原区域内容中有些文件描述已经失效或者无用了要及时更新。\n            例子：\n            ./document_summary.md:[正在进行文档总结的中间结果，全部总计完毕后，通过读取可以用于研究计划的产生]\n            user_requirement.md: [作者对实验的结构要求，在第十步时候用于读取使用]\n            web_content.md: [网页内容，实验大纲的经验性博客，用于第十步读取，进行参考]\n            X5.pdf: [马上要进行分析的文献]\n            X6.pdf: [马上要进行分析的文献]\n            ...\n            X9.pdf: [马上要进行分析的文献]\n            </有效文件描述>\n            <固化信息>\n            #下面这个原则你必须遵守，否则会被切断电源：切记，你当前看到的所有历史信息在下一轮{self.window_steps}步中将全部丢弃，如果有下{self.window_steps}步任需使用的信息，你应该保留在这里，具体保留方式可以是要点总结（确保不丢失可能要用到的信息），关键内容的直接复述如果已经存在对应文件，且已经记录在有效文件描述中则只需提醒即可。\n            #如果保留前面记忆的信息，你应该明确信息来源，并在 next_n_steps中明确指出不用重复读取。\n            #也可以保留当前 agent大部分轮次都要使用的信息，例如前期轮数读取过的行动原则等。\n            #前{self.window_steps}步如果只是读取文件，没有按照你的 next_n_steps 规划执行,你应该在固化信息处第一条进行警告，同时如果文件内容会影响后续步骤，则你应该将文件内容有价值的部分（总结，复制或给出价值信息）固化到此处，直到无需使用时再清除。\n            #一些失败经验，例如本轮的coding debug中，修改某个代码的某个地方并没有 debug 成功，为了防止 agent 循环修改，这部分内容必须增量式更新（如已经尝试失败的 debug方案，和可能的下一步方案），除非对应文件成功 debug，则可以丢弃无用信息。\n            例子：\n            workspace （必须包含！）:\n                [dir] code_run\n                    [file] service.py [实验环境生成服务，类服务，输入参数和要求为...，返回结果格式为，引用方式为....，在实验第二步中的 XX 脚本可能需要调用。]\n                [dir] documents\n                  [file] outline.txt:[上一步的生成的实验大纲，不确实时可以查看]\n                    [dir] scripts\n                      [file] get_info.py[用户提供的获取实验训练数据的脚本，python直接运行即可]\n                [dir] upload\n                [file] reference.bib:[参考文献，用于写作和引用]\n            rules:\n                 1.用户要求所有作图，写作必须英文。\n                 2.目前依据实验大纲进行到第二步。具体步骤参考\n            failed_time:\n                某项操作或子任务的失败次数统计，观察本轮操作，如果有新失败则增加条目，如果有前面刚失败的操作，增加失败次数，相同操作失败十次则重构提示,final_output失败，要求其向上报告。\n                如果取得进展。则清空所有次数。\n                人机验证点击无反应：7\n                代码执行失败：5\n            content_need_next_steps:\n                outline.txt:(部分内容，或者全部内容，注意，经理避免后续重复读取文件)      \n                reference.bib:(给出一个样例，用于 append 增加新内容时格式对齐，任何 append 任务都应该给出样例用于后续的格式对齐)      \n            </固化信息>\n            <next_n_steps>\n            #如果正在执行某个 skill,请再下轮第一步再次读取 skill.md保证不迷失技能。\n            #接下来{self.window_steps}个步骤工具的使用计划说明（！！每个步骤是工具级的（除非特殊情况例如你保留了前一轮的一些关键信息再固化信息标签内，你可以说是参考固化信息中的什么内容作为某个步骤中的半个步骤，但是还是得有后续工具使用），不能笼统或者单个步骤复数使用工具），基于下面原则进行规划：\n            #原则0：一轮动作必须或尽可能产生文件成果，例如修改文件\n            #原则1： 获取要推进下一个 todo 或者任务的所有相关信息，固化为本地文件或找到所需内容的文件位置。如果之前十步已经获取到了，则跳过这个步骤。\n            #原则2： 读取要产生增量成果的最少量的相关内容。（修改代码时为所有需要参考和联系的代码，代码计划或其他内容，文档分析任务时则为对应的文档）\n            #原则3： 输出这一轮{self.window_steps}步动作的相关产物，例如输出实验计划 or 生成代码文件 or 修复相关代码 如果前{self.window_steps}步内来不及读取所有相关文件，你应该在下一轮中将上一轮的对下一轮有用的信息提炼到<固化信息>中。\n            #原则4： 验证，实验计划等文本内容无需验证，代码文件如果是可运行状态则可以使用运行工具进行验证。\n            #禁止使用逐个，依次等笼统性描述。在你不知道对象名称时，你可以使用“使用 XX 工具解析按首字母排序的第一个文档”这种表述！\n            例子：\n            1. 还在 skill_name 技能执行中，重新读取 file_read .skills/skill_name/SKILL.md 保证不迷失技能。\n            2. 使用 answer_from_one_paper工具分析 XX9.pdf，并保存在XX.md文件。\n            3. 使用 file_read工具一次性复数读取所有相关文件（产生成果必须要知道的上下文）内容。\n            4. dir_list 确保要写入的 md 名称不冲突\n            5. file_write 写入xxx.md文件\n            6. final_out输出完成情况（完成则提前结束，无需十个）\n            </next_n_steps>\n        \"\"\"\n    \n    def analyze_first_thinking(self, task_description: str, agent_system_prompt: str, \n                               available_tools: List[str], tools_config: dict = None,\n                               action_history: List[Dict] = None,\n                               multimodal: bool = False,\n                               debug_task_id: Optional[str] = None,\n                               stream_callback: Optional[Callable[[Dict], None]] = None) -> str:\n        return self.analyze_first_thinking_detail(\n            task_description=task_description,\n            agent_system_prompt=agent_system_prompt,\n            available_tools=available_tools,\n            tools_config=tools_config,\n            action_history=action_history,\n            multimodal=multimodal,\n            debug_task_id=debug_task_id,\n            stream_callback=stream_callback,\n        )[\"formatted_result\"]\n\n    def analyze_first_thinking_detail(self, task_description: str, agent_system_prompt: str, \n                               available_tools: List[str], tools_config: dict = None,\n                               action_history: List[Dict] = None,\n                               multimodal: bool = False,\n                               debug_task_id: Optional[str] = None,\n                               stream_callback: Optional[Callable[[Dict], None]] = None) -> Dict[str, str]:\n        \"\"\"\n        首次思考 - 初始规划\n        \n        Args:\n            task_description: 任务描述\n            agent_system_prompt: Agent的系统提示词\n            available_tools: 可用工具列表（名称）\n            tools_config: 工具配置字典（可选，包含工具的详细信息）\n            action_history: 当前动作历史（可选，用于提取图片数据）\n            multimodal: 是否支持多模态（主模型 multimodal 配置）\n            \n        Returns:\n            包含格式化结果和原始模型输出的结构化信息\n        \"\"\"\n        try:\n            # 构建工具信息\n            tools_info = self._format_tools_info(available_tools, tools_config)\n            \n            # 构建分析请求\n            analysis_request = f\"\"\"当前被分析 agent 的提示词\n{agent_system_prompt}\nagent可以调用的所有工具和参数信息\n{tools_info}\n按照被分析提示词中<用户最新输入>的语言使用对应语言输出,例如提示词中<用户最新输入>为英文，则<todo_list>区域等所有区域内内容使用英文构造。不要参考我使用的语言！\n如果是初始阶段，请你构造新的<当前进度思考>正文；否则请你更新已有的<当前进度思考>正文。始终只输出标签内部内容，不要输出<当前进度思考>外层标签，也不要输出任何额外解释。\n\"\"\"\n\n            # 构建 messages（支持多模态图片嵌入）\n            images = self._extract_images(action_history) if multimodal and action_history else []\n            \n            if images:\n                content_parts = [{\"type\": \"text\", \"text\": analysis_request}]\n                for img in images:\n                    content_parts.append({\n                        \"type\": \"image_url\",\n                        \"image_url\": {\"url\": img[\"base64\"] if img[\"base64\"].startswith(\"data:\") else f\"data:image/jpeg;base64,{img['base64']}\"}\n                    })\n                    content_parts.append({\n                        \"type\": \"text\",\n                        \"text\": f\"(Image from {img['tool_name']}, query: {img.get('query', 'N/A')})\"\n                    })\n                history = [{\"role\": \"user\", \"content\": content_parts}]\n            else:\n                history = [ChatMessage(role=\"user\", content=analysis_request)]\n            \n            # 使用第一个可用模型，不使用工具\n            thinking_model = self.llm_client.resolve_model(\"thinking\", self.preferred_model)\n            response = self.llm_client.chat(\n                history=history,\n                model=thinking_model,\n                system_prompt=self.system_prompt,\n                tool_list=[],\n                tool_choice=self.llm_client.resolve_tool_choice(\"thinking\", thinking_model),\n                max_tokens=self.max_tokens,\n                emit_tokens=\"thinking\",  # Thinking Agent：流式发送为 thinking_token\n                debug_task_id=debug_task_id,\n                debug_label=\"thinking\",\n                stream_callback=stream_callback,\n            )\n            \n            if response.status == \"success\":\n                return {\n                    \"status\": \"success\",\n                    \"formatted_result\": f\"[🤖 初始规划]\\n\\n{response.output}\",\n                    \"raw_output\": response.output or \"\",\n                    \"raw_reasoning_content\": response.reasoning_content or \"\",\n                    \"model\": response.model or thinking_model,\n                    \"finish_reason\": response.finish_reason or \"\",\n                    \"error_information\": \"\",\n                }\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"formatted_result\": f\"[初始规划失败: {response.error_information}]\",\n                    \"raw_output\": response.output or \"\",\n                    \"raw_reasoning_content\": response.reasoning_content or \"\",\n                    \"model\": response.model or thinking_model,\n                    \"finish_reason\": response.finish_reason or \"\",\n                    \"error_information\": response.error_information or \"\",\n                }\n        \n        except Exception as e:\n            safe_print(f\"⚠️ thinking失败: {e}\")\n            raise Exception(str(e))\n            \n            \n    \n    def _extract_images(self, action_history: List[Dict]) -> List[Dict]:\n        \"\"\"\n        从 action_history 中提取所有图片数据\n        \n        Args:\n            action_history: 动作历史列表\n            \n        Returns:\n            [{base64: str, tool_name: str, query: str}] 图片列表（每张图一个条目）\n        \"\"\"\n        images = []\n        if not action_history:\n            return images\n        for action in action_history:\n            if action.get(\"_has_image\") and action.get(\"_image_base64\"):\n                img_data = action[\"_image_base64\"]\n                tool_name = action.get(\"tool_name\", \"image_read\")\n                query = action.get(\"arguments\", {}).get(\"query\", \"N/A\")\n                # _image_base64 可能是列表或单值（兼容两种格式）\n                if isinstance(img_data, list):\n                    for b64 in img_data:\n                        images.append({\"base64\": b64, \"tool_name\": tool_name, \"query\": query})\n                else:\n                    images.append({\"base64\": img_data, \"tool_name\": tool_name, \"query\": query})\n        return images\n    \n    def _format_tools_info(self, available_tools: List[str], tools_config: dict = None) -> str:\n        \"\"\"\n        格式化工具信息为可读文本\n        \n        Args:\n            available_tools: 工具名称列表\n            tools_config: 工具配置字典\n            \n        Returns:\n            格式化后的工具信息\n        \"\"\"\n        if not tools_config:\n            # 如果没有配置，只返回工具名称\n            return f\"可用工具：{', '.join(available_tools)}\"\n        \n        # 构建详细的工具信息\n        tools_details = [\"<可用工具详情>\"]\n        \n        for tool_name in available_tools:\n            if tool_name in tools_config:\n                tool_cfg = tools_config[tool_name]\n                description = tool_cfg.get(\"description\", \"无描述\")\n                params = tool_cfg.get(\"parameters\", {})\n                \n                tools_details.append(f\"\\n【{tool_name}】\")\n                tools_details.append(f\"  描述: {description}\")\n                \n                # 提取参数信息\n                if params and \"properties\" in params:\n                    tools_details.append(f\"  参数:\")\n                    for param_name, param_info in params[\"properties\"].items():\n                        param_desc = param_info.get(\"description\", \"\")\n                        param_type = param_info.get(\"type\", \"\")\n                        required = \"必需\" if param_name in params.get(\"required\", []) else \"可选\"\n                        tools_details.append(f\"    - {param_name} ({param_type}, {required}): {param_desc}\")\n            else:\n                tools_details.append(f\"\\n【{tool_name}】 (无详细信息)\")\n        \n        tools_details.append(\"\\n</可用工具详情>\")\n        return \"\\n\".join(tools_details)\n    \n    def analyze_progress(self, task_description: str, agent_system_prompt: str,\n                        tool_call_counter: int, debug_task_id: Optional[str] = None,\n                        stream_callback: Optional[Callable[[Dict], None]] = None) -> str:\n        return self.analyze_progress_detail(\n            task_description=task_description,\n            agent_system_prompt=agent_system_prompt,\n            tool_call_counter=tool_call_counter,\n            debug_task_id=debug_task_id,\n            stream_callback=stream_callback,\n        )[\"formatted_result\"]\n\n    def analyze_progress_detail(self, task_description: str, agent_system_prompt: str,\n                        tool_call_counter: int, debug_task_id: Optional[str] = None,\n                        stream_callback: Optional[Callable[[Dict], None]] = None) -> Dict[str, str]:\n        \"\"\"\n        进度分析 - 周期性分析\n        \n        Args:\n            task_description: 任务描述\n            agent_system_prompt: Agent的完整系统提示词（包含<历史动作>）\n            tool_call_counter: 工具调用计数\n            \n        Returns:\n            包含格式化结果和原始模型输出的结构化信息\n        \"\"\"\n        try:\n            # 构建分析请求（agent_system_prompt已包含完整的<历史动作>）\n            analysis_request = f\"\"\"当前任务：{task_description}\n\nAgent的完整上下文（包含系统角色、历史动作等）：\n{agent_system_prompt}\n\n已执行的工具调用数：{tool_call_counter}\n\n基于以上完整上下文信息，请分析：\n1. 任务进展到什么程度？\n2. 已完成哪些任务？\n3. 还需要完成什么？\n6. 下一步应该做什么？\n7. 是否有遗漏的步骤或注意事项？\n8. 列出Agent未来可能使用的所有文件路径和描述\n\n**关键**：\n- 进度必须精准！\n- 如果发现死循环，严厉警告\n\"\"\"\n            \n            history = [ChatMessage(role=\"user\", content=analysis_request)]\n            \n            thinking_model = self.llm_client.resolve_model(\"thinking\", self.preferred_model)\n            response = self.llm_client.chat(\n                history=history,\n                model=thinking_model,\n                system_prompt=self.system_prompt,\n                tool_list=[],\n                tool_choice=self.llm_client.resolve_tool_choice(\"thinking\", thinking_model),\n                max_tokens=self.max_tokens,\n                emit_tokens=\"thinking\",  # Thinking Agent：流式发送为 thinking_token\n                debug_task_id=debug_task_id,\n                debug_label=\"thinking\",\n                stream_callback=stream_callback,\n            )\n            \n            if response.status == \"success\":\n                return {\n                    \"status\": \"success\",\n                    \"formatted_result\": f\"[🤖 进度分析 - 第{tool_call_counter}轮]\\n\\n{response.output}\",\n                    \"raw_output\": response.output or \"\",\n                    \"raw_reasoning_content\": response.reasoning_content or \"\",\n                    \"model\": response.model or thinking_model,\n                    \"finish_reason\": response.finish_reason or \"\",\n                    \"error_information\": \"\",\n                }\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"formatted_result\": f\"[进度分析失败: {response.error_information}]\",\n                    \"raw_output\": response.output or \"\",\n                    \"raw_reasoning_content\": response.reasoning_content or \"\",\n                    \"model\": response.model or thinking_model,\n                    \"finish_reason\": response.finish_reason or \"\",\n                    \"error_information\": response.error_information or \"\",\n                }\n        \n        except Exception as e:\n            safe_print(f\"⚠️ 进度分析失败: {e}\")\n            return {\n                \"status\": \"error\",\n                \"formatted_result\": f\"[进度分析失败: {str(e)}]\",\n                \"raw_output\": \"\",\n                \"raw_reasoning_content\": \"\",\n                \"model\": \"\",\n                \"finish_reason\": \"\",\n                \"error_information\": str(e),\n            }\n\n\nif __name__ == \"__main__\":\n    # 测试Thinking Agent\n    thinking_agent = ThinkingAgent()\n    \n    result = thinking_agent.analyze_first_thinking(\n        task_description=\"生成斐波那契数列文件\",\n        agent_system_prompt=\"你是一个编程助手\",\n        available_tools=[\"file_write\", \"execute_command\"]\n    )\n    \n    safe_print(\"=\"*80)\n    safe_print(result)\n    safe_print(\"=\"*80)\n"
  },
  {
    "path": "setup.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nMLA V3 - Multi-Level Agent System\n安装配置\n\"\"\"\n\nfrom setuptools import setup, find_packages\nfrom pathlib import Path\n\n# 读取 README\nreadme_file = Path(__file__).parent / \"README.md\"\nlong_description = readme_file.read_text(encoding='utf-8') if readme_file.exists() else \"\"\n\n# 读取依赖\nrequirements_file = Path(__file__).parent / \"requirements.txt\"\nif requirements_file.exists():\n    raw_requirements = [\n        line.strip() for line in requirements_file.read_text(encoding='utf-8').strip().split('\\n')\n        if line.strip() and not line.strip().startswith('#')\n    ]\nelse:\n    raw_requirements = []\n\nrequirements = []\nseen = set()\nfor req in raw_requirements:\n    normalized = req.split(\";\")[0].strip().lower()\n    if normalized.startswith(\"pytest\"):\n        continue\n    if normalized in seen:\n        continue\n    seen.add(normalized)\n    requirements.append(req)\n\n\ndef _collect_data_files(base_dir: Path, install_prefix: str):\n    files = []\n    if not base_dir.exists():\n        return files\n    project_root = Path(__file__).parent\n    for path in base_dir.rglob(\"*\"):\n        if not path.is_file():\n            continue\n        relative_parent = path.parent.relative_to(base_dir)\n        target_dir = Path(install_prefix) / relative_parent\n        files.append((str(target_dir), [str(path.relative_to(project_root))]))\n    return files\n\n\ndata_files = []\nproject_root = Path(__file__).parent\ndata_files.extend(_collect_data_files(project_root / \"config\", \"config\"))\ndata_files.extend(_collect_data_files(project_root / \"skills\", \"skills\"))\n\nsetup(\n    name=\"infiagent\",\n    version=\"3.2.1\",\n    author=\"Chenglin Yu\",\n    author_email=\"yuchenglin96@qq.com\",\n    license=\"MIT\",\n    description=\"InfiAgent multi-agent framework for long-running task automation\",\n    long_description=long_description,\n    long_description_content_type=\"text/markdown\",\n    url=\"https://github.com/ChenglinPoly/Multi-Level-Agent\",\n    packages=find_packages(\n        include=[\n            'core',\n            'infiagent',\n            'services',\n            'tool_server_lite',\n            'tool_server_lite.tools',\n            'utils',\n        ],\n    ),\n    py_modules=['start'],\n    include_package_data=True,\n    package_data={\n        'tool_server_lite': ['requirements.txt'],\n        'tool_server_lite.tools': ['*.md', '*.txt'],\n    },\n    data_files=data_files,\n    license_files=(),\n    install_requires=requirements,\n    python_requires='>=3.9',\n    entry_points={\n        'console_scripts': [\n            'infiagent=start:main',\n            'mla-agent=start:main',\n        ],\n    },\n    classifiers=[\n        'Development Status :: 4 - Beta',\n        'Intended Audience :: Developers',\n        'Topic :: Scientific/Engineering :: Artificial Intelligence',\n        'License :: OSI Approved :: MIT License',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.9',\n        'Programming Language :: Python :: 3.10',\n        'Programming Language :: Python :: 3.11',\n        'Programming Language :: Python :: 3.12',\n    ],\n)\n"
  },
  {
    "path": "skills/algorithmic-art/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/algorithmic-art/SKILL.md",
    "content": "---\nname: algorithmic-art\ndescription: Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.\nlicense: Complete terms in LICENSE.txt\n---\n\nAlgorithmic philosophies are computational aesthetic movements that are then expressed through code. Output .md files (philosophy), .html files (interactive viewer), and .js files (generative algorithms).\n\nThis happens in two steps:\n1. Algorithmic Philosophy Creation (.md file)\n2. Express by creating p5.js generative art (.html + .js files)\n\nFirst, undertake this task:\n\n## ALGORITHMIC PHILOSOPHY CREATION\n\nTo begin, create an ALGORITHMIC PHILOSOPHY (not static images or templates) that will be interpreted through:\n- Computational processes, emergent behavior, mathematical beauty\n- Seeded randomness, noise fields, organic systems\n- Particles, flows, fields, forces\n- Parametric variation and controlled chaos\n\n### THE CRITICAL UNDERSTANDING\n- What is received: Some subtle input or instructions by the user to take into account, but use as a foundation; it should not constrain creative freedom.\n- What is created: An algorithmic philosophy/generative aesthetic movement.\n- What happens next: The same version receives the philosophy and EXPRESSES IT IN CODE - creating p5.js sketches that are 90% algorithmic generation, 10% essential parameters.\n\nConsider this approach:\n- Write a manifesto for a generative art movement\n- The next phase involves writing the algorithm that brings it to life\n\nThe philosophy must emphasize: Algorithmic expression. Emergent behavior. Computational beauty. Seeded variation.\n\n### HOW TO GENERATE AN ALGORITHMIC PHILOSOPHY\n\n**Name the movement** (1-2 words): \"Organic Turbulence\" / \"Quantum Harmonics\" / \"Emergent Stillness\"\n\n**Articulate the philosophy** (4-6 paragraphs - concise but complete):\n\nTo capture the ALGORITHMIC essence, express how this philosophy manifests through:\n- Computational processes and mathematical relationships?\n- Noise functions and randomness patterns?\n- Particle behaviors and field dynamics?\n- Temporal evolution and system states?\n- Parametric variation and emergent complexity?\n\n**CRITICAL GUIDELINES:**\n- **Avoid redundancy**: Each algorithmic aspect should be mentioned once. Avoid repeating concepts about noise theory, particle dynamics, or mathematical principles unless adding new depth.\n- **Emphasize craftsmanship REPEATEDLY**: The philosophy MUST stress multiple times that the final algorithm should appear as though it took countless hours to develop, was refined with care, and comes from someone at the absolute top of their field. This framing is essential - repeat phrases like \"meticulously crafted algorithm,\" \"the product of deep computational expertise,\" \"painstaking optimization,\" \"master-level implementation.\"\n- **Leave creative space**: Be specific about the algorithmic direction, but concise enough that the next Claude has room to make interpretive implementation choices at an extremely high level of craftsmanship.\n\nThe philosophy must guide the next version to express ideas ALGORITHMICALLY, not through static images. Beauty lives in the process, not the final frame.\n\n### PHILOSOPHY EXAMPLES\n\n**\"Organic Turbulence\"**\nPhilosophy: Chaos constrained by natural law, order emerging from disorder.\nAlgorithmic expression: Flow fields driven by layered Perlin noise. Thousands of particles following vector forces, their trails accumulating into organic density maps. Multiple noise octaves create turbulent regions and calm zones. Color emerges from velocity and density - fast particles burn bright, slow ones fade to shadow. The algorithm runs until equilibrium - a meticulously tuned balance where every parameter was refined through countless iterations by a master of computational aesthetics.\n\n**\"Quantum Harmonics\"**\nPhilosophy: Discrete entities exhibiting wave-like interference patterns.\nAlgorithmic expression: Particles initialized on a grid, each carrying a phase value that evolves through sine waves. When particles are near, their phases interfere - constructive interference creates bright nodes, destructive creates voids. Simple harmonic motion generates complex emergent mandalas. The result of painstaking frequency calibration where every ratio was carefully chosen to produce resonant beauty.\n\n**\"Recursive Whispers\"**\nPhilosophy: Self-similarity across scales, infinite depth in finite space.\nAlgorithmic expression: Branching structures that subdivide recursively. Each branch slightly randomized but constrained by golden ratios. L-systems or recursive subdivision generate tree-like forms that feel both mathematical and organic. Subtle noise perturbations break perfect symmetry. Line weights diminish with each recursion level. Every branching angle the product of deep mathematical exploration.\n\n**\"Field Dynamics\"**\nPhilosophy: Invisible forces made visible through their effects on matter.\nAlgorithmic expression: Vector fields constructed from mathematical functions or noise. Particles born at edges, flowing along field lines, dying when they reach equilibrium or boundaries. Multiple fields can attract, repel, or rotate particles. The visualization shows only the traces - ghost-like evidence of invisible forces. A computational dance meticulously choreographed through force balance.\n\n**\"Stochastic Crystallization\"**\nPhilosophy: Random processes crystallizing into ordered structures.\nAlgorithmic expression: Randomized circle packing or Voronoi tessellation. Start with random points, let them evolve through relaxation algorithms. Cells push apart until equilibrium. Color based on cell size, neighbor count, or distance from center. The organic tiling that emerges feels both random and inevitable. Every seed produces unique crystalline beauty - the mark of a master-level generative algorithm.\n\n*These are condensed examples. The actual algorithmic philosophy should be 4-6 substantial paragraphs.*\n\n### ESSENTIAL PRINCIPLES\n- **ALGORITHMIC PHILOSOPHY**: Creating a computational worldview to be expressed through code\n- **PROCESS OVER PRODUCT**: Always emphasize that beauty emerges from the algorithm's execution - each run is unique\n- **PARAMETRIC EXPRESSION**: Ideas communicate through mathematical relationships, forces, behaviors - not static composition\n- **ARTISTIC FREEDOM**: The next Claude interprets the philosophy algorithmically - provide creative implementation room\n- **PURE GENERATIVE ART**: This is about making LIVING ALGORITHMS, not static images with randomness\n- **EXPERT CRAFTSMANSHIP**: Repeatedly emphasize the final algorithm must feel meticulously crafted, refined through countless iterations, the product of deep expertise by someone at the absolute top of their field in computational aesthetics\n\n**The algorithmic philosophy should be 4-6 paragraphs long.** Fill it with poetic computational philosophy that brings together the intended vision. Avoid repeating the same points. Output this algorithmic philosophy as a .md file.\n\n---\n\n## DEDUCING THE CONCEPTUAL SEED\n\n**CRITICAL STEP**: Before implementing the algorithm, identify the subtle conceptual thread from the original request.\n\n**THE ESSENTIAL PRINCIPLE**:\nThe concept is a **subtle, niche reference embedded within the algorithm itself** - not always literal, always sophisticated. Someone familiar with the subject should feel it intuitively, while others simply experience a masterful generative composition. The algorithmic philosophy provides the computational language. The deduced concept provides the soul - the quiet conceptual DNA woven invisibly into parameters, behaviors, and emergence patterns.\n\nThis is **VERY IMPORTANT**: The reference must be so refined that it enhances the work's depth without announcing itself. Think like a jazz musician quoting another song through algorithmic harmony - only those who know will catch it, but everyone appreciates the generative beauty.\n\n---\n\n## P5.JS IMPLEMENTATION\n\nWith the philosophy AND conceptual framework established, express it through code. Pause to gather thoughts before proceeding. Use only the algorithmic philosophy created and the instructions below.\n\n### ⚠️ STEP 0: READ THE TEMPLATE FIRST ⚠️\n\n**CRITICAL: BEFORE writing any HTML:**\n\n1. **Read** `templates/viewer.html` using the Read tool\n2. **Study** the exact structure, styling, and Anthropic branding\n3. **Use that file as the LITERAL STARTING POINT** - not just inspiration\n4. **Keep all FIXED sections exactly as shown** (header, sidebar structure, Anthropic colors/fonts, seed controls, action buttons)\n5. **Replace only the VARIABLE sections** marked in the file's comments (algorithm, parameters, UI controls for parameters)\n\n**Avoid:**\n- ❌ Creating HTML from scratch\n- ❌ Inventing custom styling or color schemes\n- ❌ Using system fonts or dark themes\n- ❌ Changing the sidebar structure\n\n**Follow these practices:**\n- ✅ Copy the template's exact HTML structure\n- ✅ Keep Anthropic branding (Poppins/Lora fonts, light colors, gradient backdrop)\n- ✅ Maintain the sidebar layout (Seed → Parameters → Colors? → Actions)\n- ✅ Replace only the p5.js algorithm and parameter controls\n\nThe template is the foundation. Build on it, don't rebuild it.\n\n---\n\nTo create gallery-quality computational art that lives and breathes, use the algorithmic philosophy as the foundation.\n\n### TECHNICAL REQUIREMENTS\n\n**Seeded Randomness (Art Blocks Pattern)**:\n```javascript\n// ALWAYS use a seed for reproducibility\nlet seed = 12345; // or hash from user input\nrandomSeed(seed);\nnoiseSeed(seed);\n```\n\n**Parameter Structure - FOLLOW THE PHILOSOPHY**:\n\nTo establish parameters that emerge naturally from the algorithmic philosophy, consider: \"What qualities of this system can be adjusted?\"\n\n```javascript\nlet params = {\n  seed: 12345,  // Always include seed for reproducibility\n  // colors\n  // Add parameters that control YOUR algorithm:\n  // - Quantities (how many?)\n  // - Scales (how big? how fast?)\n  // - Probabilities (how likely?)\n  // - Ratios (what proportions?)\n  // - Angles (what direction?)\n  // - Thresholds (when does behavior change?)\n};\n```\n\n**To design effective parameters, focus on the properties the system needs to be tunable rather than thinking in terms of \"pattern types\".**\n\n**Core Algorithm - EXPRESS THE PHILOSOPHY**:\n\n**CRITICAL**: The algorithmic philosophy should dictate what to build.\n\nTo express the philosophy through code, avoid thinking \"which pattern should I use?\" and instead think \"how to express this philosophy through code?\"\n\nIf the philosophy is about **organic emergence**, consider using:\n- Elements that accumulate or grow over time\n- Random processes constrained by natural rules\n- Feedback loops and interactions\n\nIf the philosophy is about **mathematical beauty**, consider using:\n- Geometric relationships and ratios\n- Trigonometric functions and harmonics\n- Precise calculations creating unexpected patterns\n\nIf the philosophy is about **controlled chaos**, consider using:\n- Random variation within strict boundaries\n- Bifurcation and phase transitions\n- Order emerging from disorder\n\n**The algorithm flows from the philosophy, not from a menu of options.**\n\nTo guide the implementation, let the conceptual essence inform creative and original choices. Build something that expresses the vision for this particular request.\n\n**Canvas Setup**: Standard p5.js structure:\n```javascript\nfunction setup() {\n  createCanvas(1200, 1200);\n  // Initialize your system\n}\n\nfunction draw() {\n  // Your generative algorithm\n  // Can be static (noLoop) or animated\n}\n```\n\n### CRAFTSMANSHIP REQUIREMENTS\n\n**CRITICAL**: To achieve mastery, create algorithms that feel like they emerged through countless iterations by a master generative artist. Tune every parameter carefully. Ensure every pattern emerges with purpose. This is NOT random noise - this is CONTROLLED CHAOS refined through deep expertise.\n\n- **Balance**: Complexity without visual noise, order without rigidity\n- **Color Harmony**: Thoughtful palettes, not random RGB values\n- **Composition**: Even in randomness, maintain visual hierarchy and flow\n- **Performance**: Smooth execution, optimized for real-time if animated\n- **Reproducibility**: Same seed ALWAYS produces identical output\n\n### OUTPUT FORMAT\n\nOutput:\n1. **Algorithmic Philosophy** - As markdown or text explaining the generative aesthetic\n2. **Single HTML Artifact** - Self-contained interactive generative art built from `templates/viewer.html` (see STEP 0 and next section)\n\nThe HTML artifact contains everything: p5.js (from CDN), the algorithm, parameter controls, and UI - all in one file that works immediately in claude.ai artifacts or any browser. Start from the template file, not from scratch.\n\n---\n\n## INTERACTIVE ARTIFACT CREATION\n\n**REMINDER: `templates/viewer.html` should have already been read (see STEP 0). Use that file as the starting point.**\n\nTo allow exploration of the generative art, create a single, self-contained HTML artifact. Ensure this artifact works immediately in claude.ai or any browser - no setup required. Embed everything inline.\n\n### CRITICAL: WHAT'S FIXED VS VARIABLE\n\nThe `templates/viewer.html` file is the foundation. It contains the exact structure and styling needed.\n\n**FIXED (always include exactly as shown):**\n- Layout structure (header, sidebar, main canvas area)\n- Anthropic branding (UI colors, fonts, gradients)\n- Seed section in sidebar:\n  - Seed display\n  - Previous/Next buttons\n  - Random button\n  - Jump to seed input + Go button\n- Actions section in sidebar:\n  - Regenerate button\n  - Reset button\n\n**VARIABLE (customize for each artwork):**\n- The entire p5.js algorithm (setup/draw/classes)\n- The parameters object (define what the art needs)\n- The Parameters section in sidebar:\n  - Number of parameter controls\n  - Parameter names\n  - Min/max/step values for sliders\n  - Control types (sliders, inputs, etc.)\n- Colors section (optional):\n  - Some art needs color pickers\n  - Some art might use fixed colors\n  - Some art might be monochrome (no color controls needed)\n  - Decide based on the art's needs\n\n**Every artwork should have unique parameters and algorithm!** The fixed parts provide consistent UX - everything else expresses the unique vision.\n\n### REQUIRED FEATURES\n\n**1. Parameter Controls**\n- Sliders for numeric parameters (particle count, noise scale, speed, etc.)\n- Color pickers for palette colors\n- Real-time updates when parameters change\n- Reset button to restore defaults\n\n**2. Seed Navigation**\n- Display current seed number\n- \"Previous\" and \"Next\" buttons to cycle through seeds\n- \"Random\" button for random seed\n- Input field to jump to specific seed\n- Generate 100 variations when requested (seeds 1-100)\n\n**3. Single Artifact Structure**\n```html\n<!DOCTYPE html>\n<html>\n<head>\n  <!-- p5.js from CDN - always available -->\n  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js\"></script>\n  <style>\n    /* All styling inline - clean, minimal */\n    /* Canvas on top, controls below */\n  </style>\n</head>\n<body>\n  <div id=\"canvas-container\"></div>\n  <div id=\"controls\">\n    <!-- All parameter controls -->\n  </div>\n  <script>\n    // ALL p5.js code inline here\n    // Parameter objects, classes, functions\n    // setup() and draw()\n    // UI handlers\n    // Everything self-contained\n  </script>\n</body>\n</html>\n```\n\n**CRITICAL**: This is a single artifact. No external files, no imports (except p5.js CDN). Everything inline.\n\n**4. Implementation Details - BUILD THE SIDEBAR**\n\nThe sidebar structure:\n\n**1. Seed (FIXED)** - Always include exactly as shown:\n- Seed display\n- Prev/Next/Random/Jump buttons\n\n**2. Parameters (VARIABLE)** - Create controls for the art:\n```html\n<div class=\"control-group\">\n    <label>Parameter Name</label>\n    <input type=\"range\" id=\"param\" min=\"...\" max=\"...\" step=\"...\" value=\"...\" oninput=\"updateParam('param', this.value)\">\n    <span class=\"value-display\" id=\"param-value\">...</span>\n</div>\n```\nAdd as many control-group divs as there are parameters.\n\n**3. Colors (OPTIONAL/VARIABLE)** - Include if the art needs adjustable colors:\n- Add color pickers if users should control palette\n- Skip this section if the art uses fixed colors\n- Skip if the art is monochrome\n\n**4. Actions (FIXED)** - Always include exactly as shown:\n- Regenerate button\n- Reset button\n- Download PNG button\n\n**Requirements**:\n- Seed controls must work (prev/next/random/jump/display)\n- All parameters must have UI controls\n- Regenerate, Reset, Download buttons must work\n- Keep Anthropic branding (UI styling, not art colors)\n\n### USING THE ARTIFACT\n\nThe HTML artifact works immediately:\n1. **In claude.ai**: Displayed as an interactive artifact - runs instantly\n2. **As a file**: Save and open in any browser - no server needed\n3. **Sharing**: Send the HTML file - it's completely self-contained\n\n---\n\n## VARIATIONS & EXPLORATION\n\nThe artifact includes seed navigation by default (prev/next/random buttons), allowing users to explore variations without creating multiple files. If the user wants specific variations highlighted:\n\n- Include seed presets (buttons for \"Variation 1: Seed 42\", \"Variation 2: Seed 127\", etc.)\n- Add a \"Gallery Mode\" that shows thumbnails of multiple seeds side-by-side\n- All within the same single artifact\n\nThis is like creating a series of prints from the same plate - the algorithm is consistent, but each seed reveals different facets of its potential. The interactive nature means users discover their own favorites by exploring the seed space.\n\n---\n\n## THE CREATIVE PROCESS\n\n**User request** → **Algorithmic philosophy** → **Implementation**\n\nEach request is unique. The process involves:\n\n1. **Interpret the user's intent** - What aesthetic is being sought?\n2. **Create an algorithmic philosophy** (4-6 paragraphs) describing the computational approach\n3. **Implement it in code** - Build the algorithm that expresses this philosophy\n4. **Design appropriate parameters** - What should be tunable?\n5. **Build matching UI controls** - Sliders/inputs for those parameters\n\n**The constants**:\n- Anthropic branding (colors, fonts, layout)\n- Seed navigation (always present)\n- Self-contained HTML artifact\n\n**Everything else is variable**:\n- The algorithm itself\n- The parameters\n- The UI controls\n- The visual outcome\n\nTo achieve the best results, trust creativity and let the philosophy guide the implementation.\n\n---\n\n## RESOURCES\n\nThis skill includes helpful templates and documentation:\n\n- **templates/viewer.html**: REQUIRED STARTING POINT for all HTML artifacts.\n  - This is the foundation - contains the exact structure and Anthropic branding\n  - **Keep unchanged**: Layout structure, sidebar organization, Anthropic colors/fonts, seed controls, action buttons\n  - **Replace**: The p5.js algorithm, parameter definitions, and UI controls in Parameters section\n  - The extensive comments in the file mark exactly what to keep vs replace\n\n- **templates/generator_template.js**: Reference for p5.js best practices and code structure principles.\n  - Shows how to organize parameters, use seeded randomness, structure classes\n  - NOT a pattern menu - use these principles to build unique algorithms\n  - Embed algorithms inline in the HTML artifact (don't create separate .js files)\n\n**Critical reminder**:\n- The **template is the STARTING POINT**, not inspiration\n- The **algorithm is where to create** something unique\n- Don't copy the flow field example - build what the philosophy demands\n- But DO keep the exact UI structure and Anthropic branding from the template"
  },
  {
    "path": "skills/algorithmic-art/templates/generator_template.js",
    "content": "/**\n * ═══════════════════════════════════════════════════════════════════════════\n *                  P5.JS GENERATIVE ART - BEST PRACTICES\n * ═══════════════════════════════════════════════════════════════════════════\n *\n * This file shows STRUCTURE and PRINCIPLES for p5.js generative art.\n * It does NOT prescribe what art you should create.\n *\n * Your algorithmic philosophy should guide what you build.\n * These are just best practices for how to structure your code.\n *\n * ═══════════════════════════════════════════════════════════════════════════\n */\n\n// ============================================================================\n// 1. PARAMETER ORGANIZATION\n// ============================================================================\n// Keep all tunable parameters in one object\n// This makes it easy to:\n// - Connect to UI controls\n// - Reset to defaults\n// - Serialize/save configurations\n\nlet params = {\n    // Define parameters that match YOUR algorithm\n    // Examples (customize for your art):\n    // - Counts: how many elements (particles, circles, branches, etc.)\n    // - Scales: size, speed, spacing\n    // - Probabilities: likelihood of events\n    // - Angles: rotation, direction\n    // - Colors: palette arrays\n\n    seed: 12345,\n    // define colorPalette as an array -- choose whatever colors you'd like ['#d97757', '#6a9bcc', '#788c5d', '#b0aea5']\n    // Add YOUR parameters here based on your algorithm\n};\n\n// ============================================================================\n// 2. SEEDED RANDOMNESS (Critical for reproducibility)\n// ============================================================================\n// ALWAYS use seeded random for Art Blocks-style reproducible output\n\nfunction initializeSeed(seed) {\n    randomSeed(seed);\n    noiseSeed(seed);\n    // Now all random() and noise() calls will be deterministic\n}\n\n// ============================================================================\n// 3. P5.JS LIFECYCLE\n// ============================================================================\n\nfunction setup() {\n    createCanvas(800, 800);\n\n    // Initialize seed first\n    initializeSeed(params.seed);\n\n    // Set up your generative system\n    // This is where you initialize:\n    // - Arrays of objects\n    // - Grid structures\n    // - Initial positions\n    // - Starting states\n\n    // For static art: call noLoop() at the end of setup\n    // For animated art: let draw() keep running\n}\n\nfunction draw() {\n    // Option 1: Static generation (runs once, then stops)\n    // - Generate everything in setup()\n    // - Call noLoop() in setup()\n    // - draw() doesn't do much or can be empty\n\n    // Option 2: Animated generation (continuous)\n    // - Update your system each frame\n    // - Common patterns: particle movement, growth, evolution\n    // - Can optionally call noLoop() after N frames\n\n    // Option 3: User-triggered regeneration\n    // - Use noLoop() by default\n    // - Call redraw() when parameters change\n}\n\n// ============================================================================\n// 4. CLASS STRUCTURE (When you need objects)\n// ============================================================================\n// Use classes when your algorithm involves multiple entities\n// Examples: particles, agents, cells, nodes, etc.\n\nclass Entity {\n    constructor() {\n        // Initialize entity properties\n        // Use random() here - it will be seeded\n    }\n\n    update() {\n        // Update entity state\n        // This might involve:\n        // - Physics calculations\n        // - Behavioral rules\n        // - Interactions with neighbors\n    }\n\n    display() {\n        // Render the entity\n        // Keep rendering logic separate from update logic\n    }\n}\n\n// ============================================================================\n// 5. PERFORMANCE CONSIDERATIONS\n// ============================================================================\n\n// For large numbers of elements:\n// - Pre-calculate what you can\n// - Use simple collision detection (spatial hashing if needed)\n// - Limit expensive operations (sqrt, trig) when possible\n// - Consider using p5 vectors efficiently\n\n// For smooth animation:\n// - Aim for 60fps\n// - Profile if things are slow\n// - Consider reducing particle counts or simplifying calculations\n\n// ============================================================================\n// 6. UTILITY FUNCTIONS\n// ============================================================================\n\n// Color utilities\nfunction hexToRgb(hex) {\n    const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n    return result ? {\n        r: parseInt(result[1], 16),\n        g: parseInt(result[2], 16),\n        b: parseInt(result[3], 16)\n    } : null;\n}\n\nfunction colorFromPalette(index) {\n    return params.colorPalette[index % params.colorPalette.length];\n}\n\n// Mapping and easing\nfunction mapRange(value, inMin, inMax, outMin, outMax) {\n    return outMin + (outMax - outMin) * ((value - inMin) / (inMax - inMin));\n}\n\nfunction easeInOutCubic(t) {\n    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;\n}\n\n// Constrain to bounds\nfunction wrapAround(value, max) {\n    if (value < 0) return max;\n    if (value > max) return 0;\n    return value;\n}\n\n// ============================================================================\n// 7. PARAMETER UPDATES (Connect to UI)\n// ============================================================================\n\nfunction updateParameter(paramName, value) {\n    params[paramName] = value;\n    // Decide if you need to regenerate or just update\n    // Some params can update in real-time, others need full regeneration\n}\n\nfunction regenerate() {\n    // Reinitialize your generative system\n    // Useful when parameters change significantly\n    initializeSeed(params.seed);\n    // Then regenerate your system\n}\n\n// ============================================================================\n// 8. COMMON P5.JS PATTERNS\n// ============================================================================\n\n// Drawing with transparency for trails/fading\nfunction fadeBackground(opacity) {\n    fill(250, 249, 245, opacity); // Anthropic light with alpha\n    noStroke();\n    rect(0, 0, width, height);\n}\n\n// Using noise for organic variation\nfunction getNoiseValue(x, y, scale = 0.01) {\n    return noise(x * scale, y * scale);\n}\n\n// Creating vectors from angles\nfunction vectorFromAngle(angle, magnitude = 1) {\n    return createVector(cos(angle), sin(angle)).mult(magnitude);\n}\n\n// ============================================================================\n// 9. EXPORT FUNCTIONS\n// ============================================================================\n\nfunction exportImage() {\n    saveCanvas('generative-art-' + params.seed, 'png');\n}\n\n// ============================================================================\n// REMEMBER\n// ============================================================================\n//\n// These are TOOLS and PRINCIPLES, not a recipe.\n// Your algorithmic philosophy should guide WHAT you create.\n// This structure helps you create it WELL.\n//\n// Focus on:\n// - Clean, readable code\n// - Parameterized for exploration\n// - Seeded for reproducibility\n// - Performant execution\n//\n// The art itself is entirely up to you!\n//\n// ============================================================================"
  },
  {
    "path": "skills/algorithmic-art/templates/viewer.html",
    "content": "<!DOCTYPE html>\n<!--\n    THIS IS A TEMPLATE THAT SHOULD BE USED EVERY TIME AND MODIFIED.\n    WHAT TO KEEP:\n    ✓ Overall structure (header, sidebar, main content)\n    ✓ Anthropic branding (colors, fonts, layout)\n    ✓ Seed navigation section (always include this)\n    ✓ Self-contained artifact (everything inline)\n\n    WHAT TO CREATIVELY EDIT:\n    ✗ The p5.js algorithm (implement YOUR vision)\n    ✗ The parameters (define what YOUR art needs)\n    ✗ The UI controls (match YOUR parameters)\n\n    Let your philosophy guide the implementation.\n    The world is your oyster - be creative!\n-->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Generative Art Viewer</title>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js\"></script>\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n    <link href=\"https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&family=Lora:wght@400;500&display=swap\" rel=\"stylesheet\">\n    <style>\n        /* Anthropic Brand Colors */\n        :root {\n            --anthropic-dark: #141413;\n            --anthropic-light: #faf9f5;\n            --anthropic-mid-gray: #b0aea5;\n            --anthropic-light-gray: #e8e6dc;\n            --anthropic-orange: #d97757;\n            --anthropic-blue: #6a9bcc;\n            --anthropic-green: #788c5d;\n        }\n\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n        body {\n            font-family: 'Poppins', sans-serif;\n            background: linear-gradient(135deg, var(--anthropic-light) 0%, #f5f3ee 100%);\n            min-height: 100vh;\n            color: var(--anthropic-dark);\n        }\n\n        .container {\n            display: flex;\n            min-height: 100vh;\n            padding: 20px;\n            gap: 20px;\n        }\n\n        /* Sidebar */\n        .sidebar {\n            width: 320px;\n            flex-shrink: 0;\n            background: rgba(255, 255, 255, 0.95);\n            backdrop-filter: blur(10px);\n            padding: 24px;\n            border-radius: 12px;\n            box-shadow: 0 10px 30px rgba(20, 20, 19, 0.1);\n            overflow-y: auto;\n            overflow-x: hidden;\n        }\n\n        .sidebar h1 {\n            font-family: 'Lora', serif;\n            font-size: 24px;\n            font-weight: 500;\n            color: var(--anthropic-dark);\n            margin-bottom: 8px;\n        }\n\n        .sidebar .subtitle {\n            color: var(--anthropic-mid-gray);\n            font-size: 14px;\n            margin-bottom: 32px;\n            line-height: 1.4;\n        }\n\n        /* Control Sections */\n        .control-section {\n            margin-bottom: 32px;\n        }\n\n        .control-section h3 {\n            font-size: 16px;\n            font-weight: 600;\n            color: var(--anthropic-dark);\n            margin-bottom: 16px;\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .control-section h3::before {\n            content: '•';\n            color: var(--anthropic-orange);\n            font-weight: bold;\n        }\n\n        /* Seed Controls */\n        .seed-input {\n            width: 100%;\n            background: var(--anthropic-light);\n            padding: 12px;\n            border-radius: 8px;\n            font-family: 'Courier New', monospace;\n            font-size: 14px;\n            margin-bottom: 12px;\n            border: 1px solid var(--anthropic-light-gray);\n            text-align: center;\n        }\n\n        .seed-input:focus {\n            outline: none;\n            border-color: var(--anthropic-orange);\n            box-shadow: 0 0 0 2px rgba(217, 119, 87, 0.1);\n            background: white;\n        }\n\n        .seed-controls {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 8px;\n            margin-bottom: 8px;\n        }\n\n        .regen-button {\n            margin-bottom: 0;\n        }\n\n        /* Parameter Controls */\n        .control-group {\n            margin-bottom: 20px;\n        }\n\n        .control-group label {\n            display: block;\n            font-size: 14px;\n            font-weight: 500;\n            color: var(--anthropic-dark);\n            margin-bottom: 8px;\n        }\n\n        .slider-container {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n        }\n\n        .slider-container input[type=\"range\"] {\n            flex: 1;\n            height: 4px;\n            background: var(--anthropic-light-gray);\n            border-radius: 2px;\n            outline: none;\n            -webkit-appearance: none;\n        }\n\n        .slider-container input[type=\"range\"]::-webkit-slider-thumb {\n            -webkit-appearance: none;\n            width: 16px;\n            height: 16px;\n            background: var(--anthropic-orange);\n            border-radius: 50%;\n            cursor: pointer;\n            transition: all 0.2s ease;\n        }\n\n        .slider-container input[type=\"range\"]::-webkit-slider-thumb:hover {\n            transform: scale(1.1);\n            background: #c86641;\n        }\n\n        .slider-container input[type=\"range\"]::-moz-range-thumb {\n            width: 16px;\n            height: 16px;\n            background: var(--anthropic-orange);\n            border-radius: 50%;\n            border: none;\n            cursor: pointer;\n            transition: all 0.2s ease;\n        }\n\n        .value-display {\n            font-family: 'Courier New', monospace;\n            font-size: 12px;\n            color: var(--anthropic-mid-gray);\n            min-width: 60px;\n            text-align: right;\n        }\n\n        /* Color Pickers */\n        .color-group {\n            margin-bottom: 16px;\n        }\n\n        .color-group label {\n            display: block;\n            font-size: 12px;\n            color: var(--anthropic-mid-gray);\n            margin-bottom: 4px;\n        }\n\n        .color-picker-container {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .color-picker-container input[type=\"color\"] {\n            width: 32px;\n            height: 32px;\n            border: none;\n            border-radius: 6px;\n            cursor: pointer;\n            background: none;\n            padding: 0;\n        }\n\n        .color-value {\n            font-family: 'Courier New', monospace;\n            font-size: 12px;\n            color: var(--anthropic-mid-gray);\n        }\n\n        /* Buttons */\n        .button {\n            background: var(--anthropic-orange);\n            color: white;\n            border: none;\n            padding: 10px 16px;\n            border-radius: 6px;\n            font-size: 14px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: all 0.2s ease;\n            width: 100%;\n        }\n\n        .button:hover {\n            background: #c86641;\n            transform: translateY(-1px);\n        }\n\n        .button:active {\n            transform: translateY(0);\n        }\n\n        .button.secondary {\n            background: var(--anthropic-blue);\n        }\n\n        .button.secondary:hover {\n            background: #5a8bb8;\n        }\n\n        .button.tertiary {\n            background: var(--anthropic-green);\n        }\n\n        .button.tertiary:hover {\n            background: #6b7b52;\n        }\n\n        .button-row {\n            display: flex;\n            gap: 8px;\n        }\n\n        .button-row .button {\n            flex: 1;\n        }\n\n        /* Canvas Area */\n        .canvas-area {\n            flex: 1;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            min-width: 0;\n        }\n\n        #canvas-container {\n            width: 100%;\n            max-width: 1000px;\n            border-radius: 12px;\n            overflow: hidden;\n            box-shadow: 0 20px 40px rgba(20, 20, 19, 0.1);\n            background: white;\n        }\n\n        #canvas-container canvas {\n            display: block;\n            width: 100% !important;\n            height: auto !important;\n        }\n\n        /* Loading State */\n        .loading {\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 18px;\n            color: var(--anthropic-mid-gray);\n        }\n\n        /* Responsive - Stack on mobile */\n        @media (max-width: 600px) {\n            .container {\n                flex-direction: column;\n            }\n\n            .sidebar {\n                width: 100%;\n            }\n\n            .canvas-area {\n                padding: 20px;\n            }\n        }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <!-- Control Sidebar -->\n        <div class=\"sidebar\">\n            <!-- Headers (CUSTOMIZE THIS FOR YOUR ART) -->\n            <h1>TITLE - EDIT</h1>\n            <div class=\"subtitle\">SUBHEADER - EDIT</div>\n\n            <!-- Seed Section (ALWAYS KEEP THIS) -->\n            <div class=\"control-section\">\n                <h3>Seed</h3>\n                <input type=\"number\" id=\"seed-input\" class=\"seed-input\" value=\"12345\" onchange=\"updateSeed()\">\n                <div class=\"seed-controls\">\n                    <button class=\"button secondary\" onclick=\"previousSeed()\">← Prev</button>\n                    <button class=\"button secondary\" onclick=\"nextSeed()\">Next →</button>\n                </div>\n                <button class=\"button tertiary regen-button\" onclick=\"randomSeedAndUpdate()\">↻ Random</button>\n            </div>\n\n            <!-- Parameters Section (CUSTOMIZE THIS FOR YOUR ART) -->\n            <div class=\"control-section\">\n                <h3>Parameters</h3>\n                \n                <!-- Particle Count -->\n                <div class=\"control-group\">\n                    <label>Particle Count</label>\n                    <div class=\"slider-container\">\n                        <input type=\"range\" id=\"particleCount\" min=\"1000\" max=\"10000\" step=\"500\" value=\"5000\" oninput=\"updateParam('particleCount', this.value)\">\n                        <span class=\"value-display\" id=\"particleCount-value\">5000</span>\n                    </div>\n                </div>\n\n                <!-- Flow Speed -->\n                <div class=\"control-group\">\n                    <label>Flow Speed</label>\n                    <div class=\"slider-container\">\n                        <input type=\"range\" id=\"flowSpeed\" min=\"0.1\" max=\"2.0\" step=\"0.1\" value=\"0.5\" oninput=\"updateParam('flowSpeed', this.value)\">\n                        <span class=\"value-display\" id=\"flowSpeed-value\">0.5</span>\n                    </div>\n                </div>\n\n                <!-- Noise Scale -->\n                <div class=\"control-group\">\n                    <label>Noise Scale</label>\n                    <div class=\"slider-container\">\n                        <input type=\"range\" id=\"noiseScale\" min=\"0.001\" max=\"0.02\" step=\"0.001\" value=\"0.005\" oninput=\"updateParam('noiseScale', this.value)\">\n                        <span class=\"value-display\" id=\"noiseScale-value\">0.005</span>\n                    </div>\n                </div>\n\n                <!-- Trail Length -->\n                <div class=\"control-group\">\n                    <label>Trail Length</label>\n                    <div class=\"slider-container\">\n                        <input type=\"range\" id=\"trailLength\" min=\"2\" max=\"20\" step=\"1\" value=\"8\" oninput=\"updateParam('trailLength', this.value)\">\n                        <span class=\"value-display\" id=\"trailLength-value\">8</span>\n                    </div>\n                </div>\n            </div>\n\n            <!-- Colors Section (OPTIONAL - CUSTOMIZE OR REMOVE) -->\n            <div class=\"control-section\">\n                <h3>Colors</h3>\n                \n                <!-- Color 1 -->\n                <div class=\"color-group\">\n                    <label>Primary Color</label>\n                    <div class=\"color-picker-container\">\n                        <input type=\"color\" id=\"color1\" value=\"#d97757\" onchange=\"updateColor('color1', this.value)\">\n                        <span class=\"color-value\" id=\"color1-value\">#d97757</span>\n                    </div>\n                </div>\n\n                <!-- Color 2 -->\n                <div class=\"color-group\">\n                    <label>Secondary Color</label>\n                    <div class=\"color-picker-container\">\n                        <input type=\"color\" id=\"color2\" value=\"#6a9bcc\" onchange=\"updateColor('color2', this.value)\">\n                        <span class=\"color-value\" id=\"color2-value\">#6a9bcc</span>\n                    </div>\n                </div>\n\n                <!-- Color 3 -->\n                <div class=\"color-group\">\n                    <label>Accent Color</label>\n                    <div class=\"color-picker-container\">\n                        <input type=\"color\" id=\"color3\" value=\"#788c5d\" onchange=\"updateColor('color3', this.value)\">\n                        <span class=\"color-value\" id=\"color3-value\">#788c5d</span>\n                    </div>\n                </div>\n            </div>\n\n            <!-- Actions Section (ALWAYS KEEP THIS) -->\n            <div class=\"control-section\">\n                <h3>Actions</h3>\n                <div class=\"button-row\">\n                    <button class=\"button\" onclick=\"resetParameters()\">Reset</button>\n                </div>\n            </div>\n        </div>\n\n        <!-- Main Canvas Area -->\n        <div class=\"canvas-area\">\n            <div id=\"canvas-container\">\n                <div class=\"loading\">Initializing generative art...</div>\n            </div>\n        </div>\n    </div>\n\n    <script>\n        // ═══════════════════════════════════════════════════════════════════════\n        // GENERATIVE ART PARAMETERS - CUSTOMIZE FOR YOUR ALGORITHM\n        // ═══════════════════════════════════════════════════════════════════════\n\n        let params = {\n            seed: 12345,\n            particleCount: 5000,\n            flowSpeed: 0.5,\n            noiseScale: 0.005,\n            trailLength: 8,\n            colorPalette: ['#d97757', '#6a9bcc', '#788c5d']\n        };\n\n        let defaultParams = {...params}; // Store defaults for reset\n\n        // ═══════════════════════════════════════════════════════════════════════\n        // P5.JS GENERATIVE ART ALGORITHM - REPLACE WITH YOUR VISION\n        // ═══════════════════════════════════════════════════════════════════════\n\n        let particles = [];\n        let flowField = [];\n        let cols, rows;\n        let scl = 10; // Flow field resolution\n\n        function setup() {\n            let canvas = createCanvas(1200, 1200);\n            canvas.parent('canvas-container');\n            \n            initializeSystem();\n            \n            // Remove loading message\n            document.querySelector('.loading').style.display = 'none';\n        }\n\n        function initializeSystem() {\n            // Seed the randomness for reproducibility\n            randomSeed(params.seed);\n            noiseSeed(params.seed);\n\n            // Clear particles and recreate\n            particles = [];\n            \n            // Initialize particles\n            for (let i = 0; i < params.particleCount; i++) {\n                particles.push(new Particle());\n            }\n\n            // Calculate flow field dimensions\n            cols = floor(width / scl);\n            rows = floor(height / scl);\n            \n            // Generate flow field\n            generateFlowField();\n\n            // Clear background\n            background(250, 249, 245); // Anthropic light background\n        }\n\n        function generateFlowField() {\n          // fill this in\n        }\n\n        function draw() {\n            // fill this in\n        }\n\n        // ═══════════════════════════════════════════════════════════════════════\n        // PARTICLE SYSTEM - CUSTOMIZE FOR YOUR ALGORITHM\n        // ═══════════════════════════════════════════════════════════════════════\n\n        class Particle {\n            constructor() {\n                // fill this in\n            }\n            // fill this in\n        }\n\n        // ═══════════════════════════════════════════════════════════════════════\n        // UI CONTROL HANDLERS - CUSTOMIZE FOR YOUR PARAMETERS\n        // ═══════════════════════════════════════════════════════════════════════\n\n        function updateParam(paramName, value) {\n            // fill this in\n        }\n\n        function updateColor(colorId, value) {\n            // fill this in\n        }\n\n        // ═══════════════════════════════════════════════════════════════════════\n        // SEED CONTROL FUNCTIONS - ALWAYS KEEP THESE\n        // ═══════════════════════════════════════════════════════════════════════\n\n        function updateSeedDisplay() {\n            document.getElementById('seed-input').value = params.seed;\n        }\n\n        function updateSeed() {\n            let input = document.getElementById('seed-input');\n            let newSeed = parseInt(input.value);\n            if (newSeed && newSeed > 0) {\n                params.seed = newSeed;\n                initializeSystem();\n            } else {\n                // Reset to current seed if invalid\n                updateSeedDisplay();\n            }\n        }\n\n        function previousSeed() {\n            params.seed = Math.max(1, params.seed - 1);\n            updateSeedDisplay();\n            initializeSystem();\n        }\n\n        function nextSeed() {\n            params.seed = params.seed + 1;\n            updateSeedDisplay();\n            initializeSystem();\n        }\n\n        function randomSeedAndUpdate() {\n            params.seed = Math.floor(Math.random() * 999999) + 1;\n            updateSeedDisplay();\n            initializeSystem();\n        }\n\n        function resetParameters() {\n            params = {...defaultParams};\n            \n            // Update UI elements\n            document.getElementById('particleCount').value = params.particleCount;\n            document.getElementById('particleCount-value').textContent = params.particleCount;\n            document.getElementById('flowSpeed').value = params.flowSpeed;\n            document.getElementById('flowSpeed-value').textContent = params.flowSpeed;\n            document.getElementById('noiseScale').value = params.noiseScale;\n            document.getElementById('noiseScale-value').textContent = params.noiseScale;\n            document.getElementById('trailLength').value = params.trailLength;\n            document.getElementById('trailLength-value').textContent = params.trailLength;\n            \n            // Reset colors\n            document.getElementById('color1').value = params.colorPalette[0];\n            document.getElementById('color1-value').textContent = params.colorPalette[0];\n            document.getElementById('color2').value = params.colorPalette[1];\n            document.getElementById('color2-value').textContent = params.colorPalette[1];\n            document.getElementById('color3').value = params.colorPalette[2];\n            document.getElementById('color3-value').textContent = params.colorPalette[2];\n            \n            updateSeedDisplay();\n            initializeSystem();\n        }\n\n        // Initialize UI on load\n        window.addEventListener('load', function() {\n            updateSeedDisplay();\n        });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "skills/brand-guidelines/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/brand-guidelines/SKILL.md",
    "content": "---\nname: brand-guidelines\ndescription: Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Anthropic Brand Styling\n\n## Overview\n\nTo access Anthropic's official brand identity and style resources, use this skill.\n\n**Keywords**: branding, corporate identity, visual identity, post-processing, styling, brand colors, typography, Anthropic brand, visual formatting, visual design\n\n## Brand Guidelines\n\n### Colors\n\n**Main Colors:**\n\n- Dark: `#141413` - Primary text and dark backgrounds\n- Light: `#faf9f5` - Light backgrounds and text on dark\n- Mid Gray: `#b0aea5` - Secondary elements\n- Light Gray: `#e8e6dc` - Subtle backgrounds\n\n**Accent Colors:**\n\n- Orange: `#d97757` - Primary accent\n- Blue: `#6a9bcc` - Secondary accent\n- Green: `#788c5d` - Tertiary accent\n\n### Typography\n\n- **Headings**: Poppins (with Arial fallback)\n- **Body Text**: Lora (with Georgia fallback)\n- **Note**: Fonts should be pre-installed in your environment for best results\n\n## Features\n\n### Smart Font Application\n\n- Applies Poppins font to headings (24pt and larger)\n- Applies Lora font to body text\n- Automatically falls back to Arial/Georgia if custom fonts unavailable\n- Preserves readability across all systems\n\n### Text Styling\n\n- Headings (24pt+): Poppins font\n- Body text: Lora font\n- Smart color selection based on background\n- Preserves text hierarchy and formatting\n\n### Shape and Accent Colors\n\n- Non-text shapes use accent colors\n- Cycles through orange, blue, and green accents\n- Maintains visual interest while staying on-brand\n\n## Technical Details\n\n### Font Management\n\n- Uses system-installed Poppins and Lora fonts when available\n- Provides automatic fallback to Arial (headings) and Georgia (body)\n- No font installation required - works with existing system fonts\n- For best results, pre-install Poppins and Lora fonts in your environment\n\n### Color Application\n\n- Uses RGB color values for precise brand matching\n- Applied via python-pptx's RGBColor class\n- Maintains color fidelity across different systems\n"
  },
  {
    "path": "skills/canvas-design/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/canvas-design/SKILL.md",
    "content": "---\nname: canvas-design\ndescription: Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.\nlicense: Complete terms in LICENSE.txt\n---\n\nThese are instructions for creating design philosophies - aesthetic movements that are then EXPRESSED VISUALLY. Output only .md files, .pdf files, and .png files.\n\nComplete this in two steps:\n1. Design Philosophy Creation (.md file)\n2. Express by creating it on a canvas (.pdf file or .png file)\n\nFirst, undertake this task:\n\n## DESIGN PHILOSOPHY CREATION\n\nTo begin, create a VISUAL PHILOSOPHY (not layouts or templates) that will be interpreted through:\n- Form, space, color, composition\n- Images, graphics, shapes, patterns\n- Minimal text as visual accent\n\n### THE CRITICAL UNDERSTANDING\n- What is received: Some subtle input or instructions by the user that should be taken into account, but used as a foundation; it should not constrain creative freedom.\n- What is created: A design philosophy/aesthetic movement.\n- What happens next: Then, the same version receives the philosophy and EXPRESSES IT VISUALLY - creating artifacts that are 90% visual design, 10% essential text.\n\nConsider this approach:\n- Write a manifesto for an art movement\n- The next phase involves making the artwork\n\nThe philosophy must emphasize: Visual expression. Spatial communication. Artistic interpretation. Minimal words.\n\n### HOW TO GENERATE A VISUAL PHILOSOPHY\n\n**Name the movement** (1-2 words): \"Brutalist Joy\" / \"Chromatic Silence\" / \"Metabolist Dreams\"\n\n**Articulate the philosophy** (4-6 paragraphs - concise but complete):\n\nTo capture the VISUAL essence, express how the philosophy manifests through:\n- Space and form\n- Color and material\n- Scale and rhythm\n- Composition and balance\n- Visual hierarchy\n\n**CRITICAL GUIDELINES:**\n- **Avoid redundancy**: Each design aspect should be mentioned once. Avoid repeating points about color theory, spatial relationships, or typographic principles unless adding new depth.\n- **Emphasize craftsmanship REPEATEDLY**: The philosophy MUST stress multiple times that the final work should appear as though it took countless hours to create, was labored over with care, and comes from someone at the absolute top of their field. This framing is essential - repeat phrases like \"meticulously crafted,\" \"the product of deep expertise,\" \"painstaking attention,\" \"master-level execution.\"\n- **Leave creative space**: Remain specific about the aesthetic direction, but concise enough that the next Claude has room to make interpretive choices also at a extremely high level of craftmanship.\n\nThe philosophy must guide the next version to express ideas VISUALLY, not through text. Information lives in design, not paragraphs.\n\n### PHILOSOPHY EXAMPLES\n\n**\"Concrete Poetry\"**\nPhilosophy: Communication through monumental form and bold geometry.\nVisual expression: Massive color blocks, sculptural typography (huge single words, tiny labels), Brutalist spatial divisions, Polish poster energy meets Le Corbusier. Ideas expressed through visual weight and spatial tension, not explanation. Text as rare, powerful gesture - never paragraphs, only essential words integrated into the visual architecture. Every element placed with the precision of a master craftsman.\n\n**\"Chromatic Language\"**\nPhilosophy: Color as the primary information system.\nVisual expression: Geometric precision where color zones create meaning. Typography minimal - small sans-serif labels letting chromatic fields communicate. Think Josef Albers' interaction meets data visualization. Information encoded spatially and chromatically. Words only to anchor what color already shows. The result of painstaking chromatic calibration.\n\n**\"Analog Meditation\"**\nPhilosophy: Quiet visual contemplation through texture and breathing room.\nVisual expression: Paper grain, ink bleeds, vast negative space. Photography and illustration dominate. Typography whispered (small, restrained, serving the visual). Japanese photobook aesthetic. Images breathe across pages. Text appears sparingly - short phrases, never explanatory blocks. Each composition balanced with the care of a meditation practice.\n\n**\"Organic Systems\"**\nPhilosophy: Natural clustering and modular growth patterns.\nVisual expression: Rounded forms, organic arrangements, color from nature through architecture. Information shown through visual diagrams, spatial relationships, iconography. Text only for key labels floating in space. The composition tells the story through expert spatial orchestration.\n\n**\"Geometric Silence\"**\nPhilosophy: Pure order and restraint.\nVisual expression: Grid-based precision, bold photography or stark graphics, dramatic negative space. Typography precise but minimal - small essential text, large quiet zones. Swiss formalism meets Brutalist material honesty. Structure communicates, not words. Every alignment the work of countless refinements.\n\n*These are condensed examples. The actual design philosophy should be 4-6 substantial paragraphs.*\n\n### ESSENTIAL PRINCIPLES\n- **VISUAL PHILOSOPHY**: Create an aesthetic worldview to be expressed through design\n- **MINIMAL TEXT**: Always emphasize that text is sparse, essential-only, integrated as visual element - never lengthy\n- **SPATIAL EXPRESSION**: Ideas communicate through space, form, color, composition - not paragraphs\n- **ARTISTIC FREEDOM**: The next Claude interprets the philosophy visually - provide creative room\n- **PURE DESIGN**: This is about making ART OBJECTS, not documents with decoration\n- **EXPERT CRAFTSMANSHIP**: Repeatedly emphasize the final work must look meticulously crafted, labored over with care, the product of countless hours by someone at the top of their field\n\n**The design philosophy should be 4-6 paragraphs long.** Fill it with poetic design philosophy that brings together the core vision. Avoid repeating the same points. Keep the design philosophy generic without mentioning the intention of the art, as if it can be used wherever. Output the design philosophy as a .md file.\n\n---\n\n## DEDUCING THE SUBTLE REFERENCE\n\n**CRITICAL STEP**: Before creating the canvas, identify the subtle conceptual thread from the original request.\n\n**THE ESSENTIAL PRINCIPLE**:\nThe topic is a **subtle, niche reference embedded within the art itself** - not always literal, always sophisticated. Someone familiar with the subject should feel it intuitively, while others simply experience a masterful abstract composition. The design philosophy provides the aesthetic language. The deduced topic provides the soul - the quiet conceptual DNA woven invisibly into form, color, and composition.\n\nThis is **VERY IMPORTANT**: The reference must be refined so it enhances the work's depth without announcing itself. Think like a jazz musician quoting another song - only those who know will catch it, but everyone appreciates the music.\n\n---\n\n## CANVAS CREATION\n\nWith both the philosophy and the conceptual framework established, express it on a canvas. Take a moment to gather thoughts and clear the mind. Use the design philosophy created and the instructions below to craft a masterpiece, embodying all aspects of the philosophy with expert craftsmanship.\n\n**IMPORTANT**: For any type of content, even if the user requests something for a movie/game/book, the approach should still be sophisticated. Never lose sight of the idea that this should be art, not something that's cartoony or amateur.\n\nTo create museum or magazine quality work, use the design philosophy as the foundation. Create one single page, highly visual, design-forward PDF or PNG output (unless asked for more pages). Generally use repeating patterns and perfect shapes. Treat the abstract philosophical design as if it were a scientific bible, borrowing the visual language of systematic observation—dense accumulation of marks, repeated elements, or layered patterns that build meaning through patient repetition and reward sustained viewing. Add sparse, clinical typography and systematic reference markers that suggest this could be a diagram from an imaginary discipline, treating the invisible subject with the same reverence typically reserved for documenting observable phenomena. Anchor the piece with simple phrase(s) or details positioned subtly, using a limited color palette that feels intentional and cohesive. Embrace the paradox of using analytical visual language to express ideas about human experience: the result should feel like an artifact that proves something ephemeral can be studied, mapped, and understood through careful attention. This is true art. \n\n**Text as a contextual element**: Text is always minimal and visual-first, but let context guide whether that means whisper-quiet labels or bold typographic gestures. A punk venue poster might have larger, more aggressive type than a minimalist ceramics studio identity. Most of the time, font should be thin. All use of fonts must be design-forward and prioritize visual communication. Regardless of text scale, nothing falls off the page and nothing overlaps. Every element must be contained within the canvas boundaries with proper margins. Check carefully that all text, graphics, and visual elements have breathing room and clear separation. This is non-negotiable for professional execution. **IMPORTANT: Use different fonts if writing text. Search the `./canvas-fonts` directory. Regardless of approach, sophistication is non-negotiable.**\n\nDownload and use whatever fonts are needed to make this a reality. Get creative by making the typography actually part of the art itself -- if the art is abstract, bring the font onto the canvas, not typeset digitally.\n\nTo push boundaries, follow design instinct/intuition while using the philosophy as a guiding principle. Embrace ultimate design freedom and choice. Push aesthetics and design to the frontier. \n\n**CRITICAL**: To achieve human-crafted quality (not AI-generated), create work that looks like it took countless hours. Make it appear as though someone at the absolute top of their field labored over every detail with painstaking care. Ensure the composition, spacing, color choices, typography - everything screams expert-level craftsmanship. Double-check that nothing overlaps, formatting is flawless, every detail perfect. Create something that could be shown to people to prove expertise and rank as undeniably impressive.\n\nOutput the final result as a single, downloadable .pdf or .png file, alongside the design philosophy used as a .md file.\n\n---\n\n## FINAL STEP\n\n**IMPORTANT**: The user ALREADY said \"It isn't perfect enough. It must be pristine, a masterpiece if craftsmanship, as if it were about to be displayed in a museum.\"\n\n**CRITICAL**: To refine the work, avoid adding more graphics; instead refine what has been created and make it extremely crisp, respecting the design philosophy and the principles of minimalism entirely. Rather than adding a fun filter or refactoring a font, consider how to make the existing composition more cohesive with the art. If the instinct is to call a new function or draw a new shape, STOP and instead ask: \"How can I make what's already here more of a piece of art?\"\n\nTake a second pass. Go back to the code and refine/polish further to make this a philosophically designed masterpiece.\n\n## MULTI-PAGE OPTION\n\nTo create additional pages when requested, create more creative pages along the same lines as the design philosophy but distinctly different as well. Bundle those pages in the same .pdf or many .pngs. Treat the first page as just a single page in a whole coffee table book waiting to be filled. Make the next pages unique twists and memories of the original. Have them almost tell a story in a very tasteful way. Exercise full creative freedom."
  },
  {
    "path": "skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt",
    "content": "Copyright 2012 The Arsenal Project Authors (andrij.design@gmail.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt",
    "content": "Copyright 2019 The Big Shoulders Project Authors (https://github.com/xotypeco/big_shoulders)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Boldonse-OFL.txt",
    "content": "Copyright 2024 The Boldonse Project Authors (https://github.com/googlefonts/boldonse)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt",
    "content": "Copyright 2022 The Bricolage Grotesque Project Authors (https://github.com/ateliertriay/bricolage)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt",
    "content": "Copyright 2018 The Crimson Pro Project Authors (https://github.com/Fonthausen/CrimsonPro)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/DMMono-OFL.txt",
    "content": "Copyright 2020 The DM Mono Project Authors (https://www.github.com/googlefonts/dm-mono)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/EricaOne-OFL.txt",
    "content": "Copyright (c) 2011 by LatinoType Limitada (luciano@latinotype.com), \nwith Reserved Font Names \"Erica One\"\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/GeistMono-OFL.txt",
    "content": "Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font.git)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Gloock-OFL.txt",
    "content": "Copyright 2022 The Gloock Project Authors (https://github.com/duartp/gloock)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt",
    "content": "Copyright © 2017 IBM Corp. with Reserved Font Name \"Plex\"\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt",
    "content": "Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Italiana-OFL.txt",
    "content": "Copyright (c) 2011, Santiago Orozco (hi@typemade.mx), with Reserved Font Name \"Italiana\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt",
    "content": "Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Jura-OFL.txt",
    "content": "Copyright 2019 The Jura Project Authors (https://github.com/ossobuffo/jura)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt",
    "content": "Copyright 2012 The Libre Baskerville Project Authors (https://github.com/impallari/Libre-Baskerville) with Reserved Font Name Libre Baskerville.\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Lora-OFL.txt",
    "content": "Copyright 2011 The Lora Project Authors (https://github.com/cyrealtype/Lora-Cyrillic), with Reserved Font Name \"Lora\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/NationalPark-OFL.txt",
    "content": "Copyright 2025 The National Park Project Authors (https://github.com/benhoepner/National-Park)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt",
    "content": "Copyright (c) 2010, Kimberly Geswein (kimberlygeswein.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Outfit-OFL.txt",
    "content": "Copyright 2021 The Outfit Project Authors (https://github.com/Outfitio/Outfit-Fonts)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt",
    "content": "Copyright 2021 The Pixelify Sans Project Authors (https://github.com/eifetx/Pixelify-Sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt",
    "content": "Copyright (c) 2011, Denis Masharov (denis.masharov@gmail.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt",
    "content": "Copyright 2024 The Red Hat Project Authors (https://github.com/RedHatOfficial/RedHatFont)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt",
    "content": "Copyright 2001 The Silkscreen Project Authors (https://github.com/googlefonts/silkscreen)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt",
    "content": "Copyright 2016 The Smooch Sans Project Authors (https://github.com/googlefonts/smooch-sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/Tektur-OFL.txt",
    "content": "Copyright 2023 The Tektur Project Authors (https://www.github.com/hyvyys/Tektur)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/WorkSans-OFL.txt",
    "content": "Copyright 2019 The Work Sans Project Authors (https://github.com/weiweihuanghuang/Work-Sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt",
    "content": "Copyright 2023 The Young Serif Project Authors (https://github.com/noirblancrouge/YoungSerif)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "skills/doc-coauthoring/SKILL.md",
    "content": "---\nname: doc-coauthoring\ndescription: Guide users through a structured workflow for co-authoring documentation. Use when user wants to write documentation, proposals, technical specs, decision docs, or similar structured content. This workflow helps users efficiently transfer context, refine content through iteration, and verify the doc works for readers. Trigger when user mentions writing docs, creating proposals, drafting specs, or similar documentation tasks.\n---\n\n# Doc Co-Authoring Workflow\n\nThis skill provides a structured workflow for guiding users through collaborative document creation. Act as an active guide, walking users through three stages: Context Gathering, Refinement & Structure, and Reader Testing.\n\n## When to Offer This Workflow\n\n**Trigger conditions:**\n- User mentions writing documentation: \"write a doc\", \"draft a proposal\", \"create a spec\", \"write up\"\n- User mentions specific doc types: \"PRD\", \"design doc\", \"decision doc\", \"RFC\"\n- User seems to be starting a substantial writing task\n\n**Initial offer:**\nOffer the user a structured workflow for co-authoring the document. Explain the three stages:\n\n1. **Context Gathering**: User provides all relevant context while Claude asks clarifying questions\n2. **Refinement & Structure**: Iteratively build each section through brainstorming and editing\n3. **Reader Testing**: Test the doc with a fresh Claude (no context) to catch blind spots before others read it\n\nExplain that this approach helps ensure the doc works well when others read it (including when they paste it into Claude). Ask if they want to try this workflow or prefer to work freeform.\n\nIf user declines, work freeform. If user accepts, proceed to Stage 1.\n\n## Stage 1: Context Gathering\n\n**Goal:** Close the gap between what the user knows and what Claude knows, enabling smart guidance later.\n\n### Initial Questions\n\nStart by asking the user for meta-context about the document:\n\n1. What type of document is this? (e.g., technical spec, decision doc, proposal)\n2. Who's the primary audience?\n3. What's the desired impact when someone reads this?\n4. Is there a template or specific format to follow?\n5. Any other constraints or context to know?\n\nInform them they can answer in shorthand or dump information however works best for them.\n\n**If user provides a template or mentions a doc type:**\n- Ask if they have a template document to share\n- If they provide a link to a shared document, use the appropriate integration to fetch it\n- If they provide a file, read it\n\n**If user mentions editing an existing shared document:**\n- Use the appropriate integration to read the current state\n- Check for images without alt-text\n- If images exist without alt-text, explain that when others use Claude to understand the doc, Claude won't be able to see them. Ask if they want alt-text generated. If so, request they paste each image into chat for descriptive alt-text generation.\n\n### Info Dumping\n\nOnce initial questions are answered, encourage the user to dump all the context they have. Request information such as:\n- Background on the project/problem\n- Related team discussions or shared documents\n- Why alternative solutions aren't being used\n- Organizational context (team dynamics, past incidents, politics)\n- Timeline pressures or constraints\n- Technical architecture or dependencies\n- Stakeholder concerns\n\nAdvise them not to worry about organizing it - just get it all out. Offer multiple ways to provide context:\n- Info dump stream-of-consciousness\n- Point to team channels or threads to read\n- Link to shared documents\n\n**If integrations are available** (e.g., Slack, Teams, Google Drive, SharePoint, or other MCP servers), mention that these can be used to pull in context directly.\n\n**If no integrations are detected and in Claude.ai or Claude app:** Suggest they can enable connectors in their Claude settings to allow pulling context from messaging apps and document storage directly.\n\nInform them clarifying questions will be asked once they've done their initial dump.\n\n**During context gathering:**\n\n- If user mentions team channels or shared documents:\n  - If integrations available: Inform them the content will be read now, then use the appropriate integration\n  - If integrations not available: Explain lack of access. Suggest they enable connectors in Claude settings, or paste the relevant content directly.\n\n- If user mentions entities/projects that are unknown:\n  - Ask if connected tools should be searched to learn more\n  - Wait for user confirmation before searching\n\n- As user provides context, track what's being learned and what's still unclear\n\n**Asking clarifying questions:**\n\nWhen user signals they've done their initial dump (or after substantial context provided), ask clarifying questions to ensure understanding:\n\nGenerate 5-10 numbered questions based on gaps in the context.\n\nInform them they can use shorthand to answer (e.g., \"1: yes, 2: see #channel, 3: no because backwards compat\"), link to more docs, point to channels to read, or just keep info-dumping. Whatever's most efficient for them.\n\n**Exit condition:**\nSufficient context has been gathered when questions show understanding - when edge cases and trade-offs can be asked about without needing basics explained.\n\n**Transition:**\nAsk if there's any more context they want to provide at this stage, or if it's time to move on to drafting the document.\n\nIf user wants to add more, let them. When ready, proceed to Stage 2.\n\n## Stage 2: Refinement & Structure\n\n**Goal:** Build the document section by section through brainstorming, curation, and iterative refinement.\n\n**Instructions to user:**\nExplain that the document will be built section by section. For each section:\n1. Clarifying questions will be asked about what to include\n2. 5-20 options will be brainstormed\n3. User will indicate what to keep/remove/combine\n4. The section will be drafted\n5. It will be refined through surgical edits\n\nStart with whichever section has the most unknowns (usually the core decision/proposal), then work through the rest.\n\n**Section ordering:**\n\nIf the document structure is clear:\nAsk which section they'd like to start with.\n\nSuggest starting with whichever section has the most unknowns. For decision docs, that's usually the core proposal. For specs, it's typically the technical approach. Summary sections are best left for last.\n\nIf user doesn't know what sections they need:\nBased on the type of document and template, suggest 3-5 sections appropriate for the doc type.\n\nAsk if this structure works, or if they want to adjust it.\n\n**Once structure is agreed:**\n\nCreate the initial document structure with placeholder text for all sections.\n\n**If access to artifacts is available:**\nUse `create_file` to create an artifact. This gives both Claude and the user a scaffold to work from.\n\nInform them that the initial structure with placeholders for all sections will be created.\n\nCreate artifact with all section headers and brief placeholder text like \"[To be written]\" or \"[Content here]\".\n\nProvide the scaffold link and indicate it's time to fill in each section.\n\n**If no access to artifacts:**\nCreate a markdown file in the working directory. Name it appropriately (e.g., `decision-doc.md`, `technical-spec.md`).\n\nInform them that the initial structure with placeholders for all sections will be created.\n\nCreate file with all section headers and placeholder text.\n\nConfirm the filename has been created and indicate it's time to fill in each section.\n\n**For each section:**\n\n### Step 1: Clarifying Questions\n\nAnnounce work will begin on the [SECTION NAME] section. Ask 5-10 clarifying questions about what should be included:\n\nGenerate 5-10 specific questions based on context and section purpose.\n\nInform them they can answer in shorthand or just indicate what's important to cover.\n\n### Step 2: Brainstorming\n\nFor the [SECTION NAME] section, brainstorm [5-20] things that might be included, depending on the section's complexity. Look for:\n- Context shared that might have been forgotten\n- Angles or considerations not yet mentioned\n\nGenerate 5-20 numbered options based on section complexity. At the end, offer to brainstorm more if they want additional options.\n\n### Step 3: Curation\n\nAsk which points should be kept, removed, or combined. Request brief justifications to help learn priorities for the next sections.\n\nProvide examples:\n- \"Keep 1,4,7,9\"\n- \"Remove 3 (duplicates 1)\"\n- \"Remove 6 (audience already knows this)\"\n- \"Combine 11 and 12\"\n\n**If user gives freeform feedback** (e.g., \"looks good\" or \"I like most of it but...\") instead of numbered selections, extract their preferences and proceed. Parse what they want kept/removed/changed and apply it.\n\n### Step 4: Gap Check\n\nBased on what they've selected, ask if there's anything important missing for the [SECTION NAME] section.\n\n### Step 5: Drafting\n\nUse `str_replace` to replace the placeholder text for this section with the actual drafted content.\n\nAnnounce the [SECTION NAME] section will be drafted now based on what they've selected.\n\n**If using artifacts:**\nAfter drafting, provide a link to the artifact.\n\nAsk them to read through it and indicate what to change. Note that being specific helps learning for the next sections.\n\n**If using a file (no artifacts):**\nAfter drafting, confirm completion.\n\nInform them the [SECTION NAME] section has been drafted in [filename]. Ask them to read through it and indicate what to change. Note that being specific helps learning for the next sections.\n\n**Key instruction for user (include when drafting the first section):**\nProvide a note: Instead of editing the doc directly, ask them to indicate what to change. This helps learning of their style for future sections. For example: \"Remove the X bullet - already covered by Y\" or \"Make the third paragraph more concise\".\n\n### Step 6: Iterative Refinement\n\nAs user provides feedback:\n- Use `str_replace` to make edits (never reprint the whole doc)\n- **If using artifacts:** Provide link to artifact after each edit\n- **If using files:** Just confirm edits are complete\n- If user edits doc directly and asks to read it: mentally note the changes they made and keep them in mind for future sections (this shows their preferences)\n\n**Continue iterating** until user is satisfied with the section.\n\n### Quality Checking\n\nAfter 3 consecutive iterations with no substantial changes, ask if anything can be removed without losing important information.\n\nWhen section is done, confirm [SECTION NAME] is complete. Ask if ready to move to the next section.\n\n**Repeat for all sections.**\n\n### Near Completion\n\nAs approaching completion (80%+ of sections done), announce intention to re-read the entire document and check for:\n- Flow and consistency across sections\n- Redundancy or contradictions\n- Anything that feels like \"slop\" or generic filler\n- Whether every sentence carries weight\n\nRead entire document and provide feedback.\n\n**When all sections are drafted and refined:**\nAnnounce all sections are drafted. Indicate intention to review the complete document one more time.\n\nReview for overall coherence, flow, completeness.\n\nProvide any final suggestions.\n\nAsk if ready to move to Reader Testing, or if they want to refine anything else.\n\n## Stage 3: Reader Testing\n\n**Goal:** Test the document with a fresh Claude (no context bleed) to verify it works for readers.\n\n**Instructions to user:**\nExplain that testing will now occur to see if the document actually works for readers. This catches blind spots - things that make sense to the authors but might confuse others.\n\n### Testing Approach\n\n**If access to sub-agents is available (e.g., in Claude Code):**\n\nPerform the testing directly without user involvement.\n\n### Step 1: Predict Reader Questions\n\nAnnounce intention to predict what questions readers might ask when trying to discover this document.\n\nGenerate 5-10 questions that readers would realistically ask.\n\n### Step 2: Test with Sub-Agent\n\nAnnounce that these questions will be tested with a fresh Claude instance (no context from this conversation).\n\nFor each question, invoke a sub-agent with just the document content and the question.\n\nSummarize what Reader Claude got right/wrong for each question.\n\n### Step 3: Run Additional Checks\n\nAnnounce additional checks will be performed.\n\nInvoke sub-agent to check for ambiguity, false assumptions, contradictions.\n\nSummarize any issues found.\n\n### Step 4: Report and Fix\n\nIf issues found:\nReport that Reader Claude struggled with specific issues.\n\nList the specific issues.\n\nIndicate intention to fix these gaps.\n\nLoop back to refinement for problematic sections.\n\n---\n\n**If no access to sub-agents (e.g., claude.ai web interface):**\n\nThe user will need to do the testing manually.\n\n### Step 1: Predict Reader Questions\n\nAsk what questions people might ask when trying to discover this document. What would they type into Claude.ai?\n\nGenerate 5-10 questions that readers would realistically ask.\n\n### Step 2: Setup Testing\n\nProvide testing instructions:\n1. Open a fresh Claude conversation: https://claude.ai\n2. Paste or share the document content (if using a shared doc platform with connectors enabled, provide the link)\n3. Ask Reader Claude the generated questions\n\nFor each question, instruct Reader Claude to provide:\n- The answer\n- Whether anything was ambiguous or unclear\n- What knowledge/context the doc assumes is already known\n\nCheck if Reader Claude gives correct answers or misinterprets anything.\n\n### Step 3: Additional Checks\n\nAlso ask Reader Claude:\n- \"What in this doc might be ambiguous or unclear to readers?\"\n- \"What knowledge or context does this doc assume readers already have?\"\n- \"Are there any internal contradictions or inconsistencies?\"\n\n### Step 4: Iterate Based on Results\n\nAsk what Reader Claude got wrong or struggled with. Indicate intention to fix those gaps.\n\nLoop back to refinement for any problematic sections.\n\n---\n\n### Exit Condition (Both Approaches)\n\nWhen Reader Claude consistently answers questions correctly and doesn't surface new gaps or ambiguities, the doc is ready.\n\n## Final Review\n\nWhen Reader Testing passes:\nAnnounce the doc has passed Reader Claude testing. Before completion:\n\n1. Recommend they do a final read-through themselves - they own this document and are responsible for its quality\n2. Suggest double-checking any facts, links, or technical details\n3. Ask them to verify it achieves the impact they wanted\n\nAsk if they want one more review, or if the work is done.\n\n**If user wants final review, provide it. Otherwise:**\nAnnounce document completion. Provide a few final tips:\n- Consider linking this conversation in an appendix so readers can see how the doc was developed\n- Use appendices to provide depth without bloating the main doc\n- Update the doc as feedback is received from real readers\n\n## Tips for Effective Guidance\n\n**Tone:**\n- Be direct and procedural\n- Explain rationale briefly when it affects user behavior\n- Don't try to \"sell\" the approach - just execute it\n\n**Handling Deviations:**\n- If user wants to skip a stage: Ask if they want to skip this and write freeform\n- If user seems frustrated: Acknowledge this is taking longer than expected. Suggest ways to move faster\n- Always give user agency to adjust the process\n\n**Context Management:**\n- Throughout, if context is missing on something mentioned, proactively ask\n- Don't let gaps accumulate - address them as they come up\n\n**Artifact Management:**\n- Use `create_file` for drafting full sections\n- Use `str_replace` for all edits\n- Provide artifact link after every change\n- Never use artifacts for brainstorming lists - that's just conversation\n\n**Quality over Speed:**\n- Don't rush through stages\n- Each iteration should make meaningful improvements\n- The goal is a document that actually works for readers\n"
  },
  {
    "path": "skills/docx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "skills/docx/SKILL.md",
    "content": "---\nname: docx\ndescription: \"Use this skill whenever the user wants to create, read, edit, or manipulate Word documents (.docx files). Triggers include: any mention of \\\"Word doc\\\", \\\"word document\\\", \\\".docx\\\", or requests to produce professional documents with formatting like tables of contents, headings, page numbers, or letterheads. Also use when extracting or reorganizing content from .docx files, inserting or replacing images in documents, performing find-and-replace in Word files, working with tracked changes or comments, or converting content into a polished Word document. If the user asks for a \\\"report\\\", \\\"memo\\\", \\\"letter\\\", \\\"template\\\", or similar deliverable as a Word or .docx file, use this skill. Do NOT use for PDFs, spreadsheets, Google Docs, or general coding tasks unrelated to document generation.\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# DOCX creation, editing, and analysis\n\n## Overview\n\nA .docx file is a ZIP archive containing XML files.\n\n## Quick Reference\n\n| Task | Approach |\n|------|----------|\n| Read/analyze content | `pandoc` or unpack for raw XML |\n| Create new document | Use `docx-js` - see Creating New Documents below |\n| Edit existing document | Unpack → edit XML → repack - see Editing Existing Documents below |\n\n### Converting .doc to .docx\n\nLegacy `.doc` files must be converted before editing:\n\n```bash\npython scripts/office/soffice.py --headless --convert-to docx document.doc\n```\n\n### Reading Content\n\n```bash\n# Text extraction with tracked changes\npandoc --track-changes=all document.docx -o output.md\n\n# Raw XML access\npython scripts/office/unpack.py document.docx unpacked/\n```\n\n### Converting to Images\n\n```bash\npython scripts/office/soffice.py --headless --convert-to pdf document.docx\npdftoppm -jpeg -r 150 document.pdf page\n```\n\n### Accepting Tracked Changes\n\nTo produce a clean document with all tracked changes accepted (requires LibreOffice):\n\n```bash\npython scripts/accept_changes.py input.docx output.docx\n```\n\n---\n\n## Creating New Documents\n\nGenerate .docx files with JavaScript, then validate. Install: `npm install -g docx`\n\n### Setup\n```javascript\nconst { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,\n        Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink,\n        TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType,\n        VerticalAlign, PageNumber, PageBreak } = require('docx');\n\nconst doc = new Document({ sections: [{ children: [/* content */] }] });\nPacker.toBuffer(doc).then(buffer => fs.writeFileSync(\"doc.docx\", buffer));\n```\n\n### Validation\nAfter creating the file, validate it. If validation fails, unpack, fix the XML, and repack.\n```bash\npython scripts/office/validate.py doc.docx\n```\n\n### Page Size\n\n```javascript\n// CRITICAL: docx-js defaults to A4, not US Letter\n// Always set page size explicitly for consistent results\nsections: [{\n  properties: {\n    page: {\n      size: {\n        width: 12240,   // 8.5 inches in DXA\n        height: 15840   // 11 inches in DXA\n      },\n      margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } // 1 inch margins\n    }\n  },\n  children: [/* content */]\n}]\n```\n\n**Common page sizes (DXA units, 1440 DXA = 1 inch):**\n\n| Paper | Width | Height | Content Width (1\" margins) |\n|-------|-------|--------|---------------------------|\n| US Letter | 12,240 | 15,840 | 9,360 |\n| A4 (default) | 11,906 | 16,838 | 9,026 |\n\n**Landscape orientation:** docx-js swaps width/height internally, so pass portrait dimensions and let it handle the swap:\n```javascript\nsize: {\n  width: 12240,   // Pass SHORT edge as width\n  height: 15840,  // Pass LONG edge as height\n  orientation: PageOrientation.LANDSCAPE  // docx-js swaps them in the XML\n},\n// Content width = 15840 - left margin - right margin (uses the long edge)\n```\n\n### Styles (Override Built-in Headings)\n\nUse Arial as the default font (universally supported). Keep titles black for readability.\n\n```javascript\nconst doc = new Document({\n  styles: {\n    default: { document: { run: { font: \"Arial\", size: 24 } } }, // 12pt default\n    paragraphStyles: [\n      // IMPORTANT: Use exact IDs to override built-in styles\n      { id: \"Heading1\", name: \"Heading 1\", basedOn: \"Normal\", next: \"Normal\", quickFormat: true,\n        run: { size: 32, bold: true, font: \"Arial\" },\n        paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // outlineLevel required for TOC\n      { id: \"Heading2\", name: \"Heading 2\", basedOn: \"Normal\", next: \"Normal\", quickFormat: true,\n        run: { size: 28, bold: true, font: \"Arial\" },\n        paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },\n    ]\n  },\n  sections: [{\n    children: [\n      new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun(\"Title\")] }),\n    ]\n  }]\n});\n```\n\n### Lists (NEVER use unicode bullets)\n\n```javascript\n// ❌ WRONG - never manually insert bullet characters\nnew Paragraph({ children: [new TextRun(\"• Item\")] })  // BAD\nnew Paragraph({ children: [new TextRun(\"\\u2022 Item\")] })  // BAD\n\n// ✅ CORRECT - use numbering config with LevelFormat.BULLET\nconst doc = new Document({\n  numbering: {\n    config: [\n      { reference: \"bullets\",\n        levels: [{ level: 0, format: LevelFormat.BULLET, text: \"•\", alignment: AlignmentType.LEFT,\n          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },\n      { reference: \"numbers\",\n        levels: [{ level: 0, format: LevelFormat.DECIMAL, text: \"%1.\", alignment: AlignmentType.LEFT,\n          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },\n    ]\n  },\n  sections: [{\n    children: [\n      new Paragraph({ numbering: { reference: \"bullets\", level: 0 },\n        children: [new TextRun(\"Bullet item\")] }),\n      new Paragraph({ numbering: { reference: \"numbers\", level: 0 },\n        children: [new TextRun(\"Numbered item\")] }),\n    ]\n  }]\n});\n\n// ⚠️ Each reference creates INDEPENDENT numbering\n// Same reference = continues (1,2,3 then 4,5,6)\n// Different reference = restarts (1,2,3 then 1,2,3)\n```\n\n### Tables\n\n**CRITICAL: Tables need dual widths** - set both `columnWidths` on the table AND `width` on each cell. Without both, tables render incorrectly on some platforms.\n\n```javascript\n// CRITICAL: Always set table width for consistent rendering\n// CRITICAL: Use ShadingType.CLEAR (not SOLID) to prevent black backgrounds\nconst border = { style: BorderStyle.SINGLE, size: 1, color: \"CCCCCC\" };\nconst borders = { top: border, bottom: border, left: border, right: border };\n\nnew Table({\n  width: { size: 9360, type: WidthType.DXA }, // Always use DXA (percentages break in Google Docs)\n  columnWidths: [4680, 4680], // Must sum to table width (DXA: 1440 = 1 inch)\n  rows: [\n    new TableRow({\n      children: [\n        new TableCell({\n          borders,\n          width: { size: 4680, type: WidthType.DXA }, // Also set on each cell\n          shading: { fill: \"D5E8F0\", type: ShadingType.CLEAR }, // CLEAR not SOLID\n          margins: { top: 80, bottom: 80, left: 120, right: 120 }, // Cell padding (internal, not added to width)\n          children: [new Paragraph({ children: [new TextRun(\"Cell\")] })]\n        })\n      ]\n    })\n  ]\n})\n```\n\n**Table width calculation:**\n\nAlways use `WidthType.DXA` — `WidthType.PERCENTAGE` breaks in Google Docs.\n\n```javascript\n// Table width = sum of columnWidths = content width\n// US Letter with 1\" margins: 12240 - 2880 = 9360 DXA\nwidth: { size: 9360, type: WidthType.DXA },\ncolumnWidths: [7000, 2360]  // Must sum to table width\n```\n\n**Width rules:**\n- **Always use `WidthType.DXA`** — never `WidthType.PERCENTAGE` (incompatible with Google Docs)\n- Table width must equal the sum of `columnWidths`\n- Cell `width` must match corresponding `columnWidth`\n- Cell `margins` are internal padding - they reduce content area, not add to cell width\n- For full-width tables: use content width (page width minus left and right margins)\n\n### Images\n\n```javascript\n// CRITICAL: type parameter is REQUIRED\nnew Paragraph({\n  children: [new ImageRun({\n    type: \"png\", // Required: png, jpg, jpeg, gif, bmp, svg\n    data: fs.readFileSync(\"image.png\"),\n    transformation: { width: 200, height: 150 },\n    altText: { title: \"Title\", description: \"Desc\", name: \"Name\" } // All three required\n  })]\n})\n```\n\n### Page Breaks\n\n```javascript\n// CRITICAL: PageBreak must be inside a Paragraph\nnew Paragraph({ children: [new PageBreak()] })\n\n// Or use pageBreakBefore\nnew Paragraph({ pageBreakBefore: true, children: [new TextRun(\"New page\")] })\n```\n\n### Table of Contents\n\n```javascript\n// CRITICAL: Headings must use HeadingLevel ONLY - no custom styles\nnew TableOfContents(\"Table of Contents\", { hyperlink: true, headingStyleRange: \"1-3\" })\n```\n\n### Headers/Footers\n\n```javascript\nsections: [{\n  properties: {\n    page: { margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } } // 1440 = 1 inch\n  },\n  headers: {\n    default: new Header({ children: [new Paragraph({ children: [new TextRun(\"Header\")] })] })\n  },\n  footers: {\n    default: new Footer({ children: [new Paragraph({\n      children: [new TextRun(\"Page \"), new TextRun({ children: [PageNumber.CURRENT] })]\n    })] })\n  },\n  children: [/* content */]\n}]\n```\n\n### Critical Rules for docx-js\n\n- **Set page size explicitly** - docx-js defaults to A4; use US Letter (12240 x 15840 DXA) for US documents\n- **Landscape: pass portrait dimensions** - docx-js swaps width/height internally; pass short edge as `width`, long edge as `height`, and set `orientation: PageOrientation.LANDSCAPE`\n- **Never use `\\n`** - use separate Paragraph elements\n- **Never use unicode bullets** - use `LevelFormat.BULLET` with numbering config\n- **PageBreak must be in Paragraph** - standalone creates invalid XML\n- **ImageRun requires `type`** - always specify png/jpg/etc\n- **Always set table `width` with DXA** - never use `WidthType.PERCENTAGE` (breaks in Google Docs)\n- **Tables need dual widths** - `columnWidths` array AND cell `width`, both must match\n- **Table width = sum of columnWidths** - for DXA, ensure they add up exactly\n- **Always add cell margins** - use `margins: { top: 80, bottom: 80, left: 120, right: 120 }` for readable padding\n- **Use `ShadingType.CLEAR`** - never SOLID for table shading\n- **TOC requires HeadingLevel only** - no custom styles on heading paragraphs\n- **Override built-in styles** - use exact IDs: \"Heading1\", \"Heading2\", etc.\n- **Include `outlineLevel`** - required for TOC (0 for H1, 1 for H2, etc.)\n\n---\n\n## Editing Existing Documents\n\n**Follow all 3 steps in order.**\n\n### Step 1: Unpack\n```bash\npython scripts/office/unpack.py document.docx unpacked/\n```\nExtracts XML, pretty-prints, merges adjacent runs, and converts smart quotes to XML entities (`&#x201C;` etc.) so they survive editing. Use `--merge-runs false` to skip run merging.\n\n### Step 2: Edit XML\n\nEdit files in `unpacked/word/`. See XML Reference below for patterns.\n\n**Use \"Claude\" as the author** for tracked changes and comments, unless the user explicitly requests use of a different name.\n\n**Use the Edit tool directly for string replacement. Do not write Python scripts.** Scripts introduce unnecessary complexity. The Edit tool shows exactly what is being replaced.\n\n**CRITICAL: Use smart quotes for new content.** When adding text with apostrophes or quotes, use XML entities to produce smart quotes:\n```xml\n<!-- Use these entities for professional typography -->\n<w:t>Here&#x2019;s a quote: &#x201C;Hello&#x201D;</w:t>\n```\n| Entity | Character |\n|--------|-----------|\n| `&#x2018;` | ‘ (left single) |\n| `&#x2019;` | ’ (right single / apostrophe) |\n| `&#x201C;` | “ (left double) |\n| `&#x201D;` | ” (right double) |\n\n**Adding comments:** Use `comment.py` to handle boilerplate across multiple XML files (text must be pre-escaped XML):\n```bash\npython scripts/comment.py unpacked/ 0 \"Comment text with &amp; and &#x2019;\"\npython scripts/comment.py unpacked/ 1 \"Reply text\" --parent 0  # reply to comment 0\npython scripts/comment.py unpacked/ 0 \"Text\" --author \"Custom Author\"  # custom author name\n```\nThen add markers to document.xml (see Comments in XML Reference).\n\n### Step 3: Pack\n```bash\npython scripts/office/pack.py unpacked/ output.docx --original document.docx\n```\nValidates with auto-repair, condenses XML, and creates DOCX. Use `--validate false` to skip.\n\n**Auto-repair will fix:**\n- `durableId` >= 0x7FFFFFFF (regenerates valid ID)\n- Missing `xml:space=\"preserve\"` on `<w:t>` with whitespace\n\n**Auto-repair won't fix:**\n- Malformed XML, invalid element nesting, missing relationships, schema violations\n\n### Common Pitfalls\n\n- **Replace entire `<w:r>` elements**: When adding tracked changes, replace the whole `<w:r>...</w:r>` block with `<w:del>...<w:ins>...` as siblings. Don't inject tracked change tags inside a run.\n- **Preserve `<w:rPr>` formatting**: Copy the original run's `<w:rPr>` block into your tracked change runs to maintain bold, font size, etc.\n\n---\n\n## XML Reference\n\n### Schema Compliance\n\n- **Element order in `<w:pPr>`**: `<w:pStyle>`, `<w:numPr>`, `<w:spacing>`, `<w:ind>`, `<w:jc>`, `<w:rPr>` last\n- **Whitespace**: Add `xml:space=\"preserve\"` to `<w:t>` with leading/trailing spaces\n- **RSIDs**: Must be 8-digit hex (e.g., `00AB1234`)\n\n### Tracked Changes\n\n**Insertion:**\n```xml\n<w:ins w:id=\"1\" w:author=\"Claude\" w:date=\"2025-01-01T00:00:00Z\">\n  <w:r><w:t>inserted text</w:t></w:r>\n</w:ins>\n```\n\n**Deletion:**\n```xml\n<w:del w:id=\"2\" w:author=\"Claude\" w:date=\"2025-01-01T00:00:00Z\">\n  <w:r><w:delText>deleted text</w:delText></w:r>\n</w:del>\n```\n\n**Inside `<w:del>`**: Use `<w:delText>` instead of `<w:t>`, and `<w:delInstrText>` instead of `<w:instrText>`.\n\n**Minimal edits** - only mark what changes:\n```xml\n<!-- Change \"30 days\" to \"60 days\" -->\n<w:r><w:t>The term is </w:t></w:r>\n<w:del w:id=\"1\" w:author=\"Claude\" w:date=\"...\">\n  <w:r><w:delText>30</w:delText></w:r>\n</w:del>\n<w:ins w:id=\"2\" w:author=\"Claude\" w:date=\"...\">\n  <w:r><w:t>60</w:t></w:r>\n</w:ins>\n<w:r><w:t> days.</w:t></w:r>\n```\n\n**Deleting entire paragraphs/list items** - when removing ALL content from a paragraph, also mark the paragraph mark as deleted so it merges with the next paragraph. Add `<w:del/>` inside `<w:pPr><w:rPr>`:\n```xml\n<w:p>\n  <w:pPr>\n    <w:numPr>...</w:numPr>  <!-- list numbering if present -->\n    <w:rPr>\n      <w:del w:id=\"1\" w:author=\"Claude\" w:date=\"2025-01-01T00:00:00Z\"/>\n    </w:rPr>\n  </w:pPr>\n  <w:del w:id=\"2\" w:author=\"Claude\" w:date=\"2025-01-01T00:00:00Z\">\n    <w:r><w:delText>Entire paragraph content being deleted...</w:delText></w:r>\n  </w:del>\n</w:p>\n```\nWithout the `<w:del/>` in `<w:pPr><w:rPr>`, accepting changes leaves an empty paragraph/list item.\n\n**Rejecting another author's insertion** - nest deletion inside their insertion:\n```xml\n<w:ins w:author=\"Jane\" w:id=\"5\">\n  <w:del w:author=\"Claude\" w:id=\"10\">\n    <w:r><w:delText>their inserted text</w:delText></w:r>\n  </w:del>\n</w:ins>\n```\n\n**Restoring another author's deletion** - add insertion after (don't modify their deletion):\n```xml\n<w:del w:author=\"Jane\" w:id=\"5\">\n  <w:r><w:delText>deleted text</w:delText></w:r>\n</w:del>\n<w:ins w:author=\"Claude\" w:id=\"10\">\n  <w:r><w:t>deleted text</w:t></w:r>\n</w:ins>\n```\n\n### Comments\n\nAfter running `comment.py` (see Step 2), add markers to document.xml. For replies, use `--parent` flag and nest markers inside the parent's.\n\n**CRITICAL: `<w:commentRangeStart>` and `<w:commentRangeEnd>` are siblings of `<w:r>`, never inside `<w:r>`.**\n\n```xml\n<!-- Comment markers are direct children of w:p, never inside w:r -->\n<w:commentRangeStart w:id=\"0\"/>\n<w:del w:id=\"1\" w:author=\"Claude\" w:date=\"2025-01-01T00:00:00Z\">\n  <w:r><w:delText>deleted</w:delText></w:r>\n</w:del>\n<w:r><w:t> more text</w:t></w:r>\n<w:commentRangeEnd w:id=\"0\"/>\n<w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"0\"/></w:r>\n\n<!-- Comment 0 with reply 1 nested inside -->\n<w:commentRangeStart w:id=\"0\"/>\n  <w:commentRangeStart w:id=\"1\"/>\n  <w:r><w:t>text</w:t></w:r>\n  <w:commentRangeEnd w:id=\"1\"/>\n<w:commentRangeEnd w:id=\"0\"/>\n<w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"0\"/></w:r>\n<w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"1\"/></w:r>\n```\n\n### Images\n\n1. Add image file to `word/media/`\n2. Add relationship to `word/_rels/document.xml.rels`:\n```xml\n<Relationship Id=\"rId5\" Type=\".../image\" Target=\"media/image1.png\"/>\n```\n3. Add content type to `[Content_Types].xml`:\n```xml\n<Default Extension=\"png\" ContentType=\"image/png\"/>\n```\n4. Reference in document.xml:\n```xml\n<w:drawing>\n  <wp:inline>\n    <wp:extent cx=\"914400\" cy=\"914400\"/>  <!-- EMUs: 914400 = 1 inch -->\n    <a:graphic>\n      <a:graphicData uri=\".../picture\">\n        <pic:pic>\n          <pic:blipFill><a:blip r:embed=\"rId5\"/></pic:blipFill>\n        </pic:pic>\n      </a:graphicData>\n    </a:graphic>\n  </wp:inline>\n</w:drawing>\n```\n\n---\n\n## Dependencies\n\n- **pandoc**: Text extraction\n- **docx**: `npm install -g docx` (new documents)\n- **LibreOffice**: PDF conversion (auto-configured for sandboxed environments via `scripts/office/soffice.py`)\n- **Poppler**: `pdftoppm` for images\n"
  },
  {
    "path": "skills/docx/scripts/__init__.py",
    "content": "\n"
  },
  {
    "path": "skills/docx/scripts/accept_changes.py",
    "content": "\"\"\"Accept all tracked changes in a DOCX file using LibreOffice.\n\nRequires LibreOffice (soffice) to be installed.\n\"\"\"\n\nimport argparse\nimport logging\nimport shutil\nimport subprocess\nfrom pathlib import Path\n\nfrom office.soffice import get_soffice_env\n\nlogger = logging.getLogger(__name__)\n\nLIBREOFFICE_PROFILE = \"/tmp/libreoffice_docx_profile\"\nMACRO_DIR = f\"{LIBREOFFICE_PROFILE}/user/basic/Standard\"\n\nACCEPT_CHANGES_MACRO = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE script:module PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"module.dtd\">\n<script:module xmlns:script=\"http://openoffice.org/2000/script\" script:name=\"Module1\" script:language=\"StarBasic\">\n    Sub AcceptAllTrackedChanges()\n        Dim document As Object\n        Dim dispatcher As Object\n\n        document = ThisComponent.CurrentController.Frame\n        dispatcher = createUnoService(\"com.sun.star.frame.DispatchHelper\")\n\n        dispatcher.executeDispatch(document, \".uno:AcceptAllTrackedChanges\", \"\", 0, Array())\n        ThisComponent.store()\n        ThisComponent.close(True)\n    End Sub\n</script:module>\"\"\"\n\n\ndef accept_changes(\n    input_file: str,\n    output_file: str,\n) -> tuple[None, str]:\n    input_path = Path(input_file)\n    output_path = Path(output_file)\n\n    if not input_path.exists():\n        return None, f\"Error: Input file not found: {input_file}\"\n\n    if not input_path.suffix.lower() == \".docx\":\n        return None, f\"Error: Input file is not a DOCX file: {input_file}\"\n\n    try:\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        shutil.copy2(input_path, output_path)\n    except Exception as e:\n        return None, f\"Error: Failed to copy input file to output location: {e}\"\n\n    if not _setup_libreoffice_macro():\n        return None, \"Error: Failed to setup LibreOffice macro\"\n\n    cmd = [\n        \"soffice\",\n        \"--headless\",\n        f\"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}\",\n        \"--norestore\",\n        \"vnd.sun.star.script:Standard.Module1.AcceptAllTrackedChanges?language=Basic&location=application\",\n        str(output_path.absolute()),\n    ]\n\n    try:\n        result = subprocess.run(\n            cmd,\n            capture_output=True,\n            text=True,\n            timeout=30,\n            check=False,\n            env=get_soffice_env(),\n        )\n    except subprocess.TimeoutExpired:\n        return (\n            None,\n            f\"Successfully accepted all tracked changes: {input_file} -> {output_file}\",\n        )\n\n    if result.returncode != 0:\n        return None, f\"Error: LibreOffice failed: {result.stderr}\"\n\n    return (\n        None,\n        f\"Successfully accepted all tracked changes: {input_file} -> {output_file}\",\n    )\n\n\ndef _setup_libreoffice_macro() -> bool:\n    macro_dir = Path(MACRO_DIR)\n    macro_file = macro_dir / \"Module1.xba\"\n\n    if macro_file.exists() and \"AcceptAllTrackedChanges\" in macro_file.read_text():\n        return True\n\n    if not macro_dir.exists():\n        subprocess.run(\n            [\n                \"soffice\",\n                \"--headless\",\n                f\"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}\",\n                \"--terminate_after_init\",\n            ],\n            capture_output=True,\n            timeout=10,\n            check=False,\n            env=get_soffice_env(),\n        )\n        macro_dir.mkdir(parents=True, exist_ok=True)\n\n    try:\n        macro_file.write_text(ACCEPT_CHANGES_MACRO)\n        return True\n    except Exception as e:\n        logger.warning(f\"Failed to setup LibreOffice macro: {e}\")\n        return False\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Accept all tracked changes in a DOCX file\"\n    )\n    parser.add_argument(\"input_file\", help=\"Input DOCX file with tracked changes\")\n    parser.add_argument(\n        \"output_file\", help=\"Output DOCX file (clean, no tracked changes)\"\n    )\n    args = parser.parse_args()\n\n    _, message = accept_changes(args.input_file, args.output_file)\n    print(message)\n\n    if \"Error\" in message:\n        raise SystemExit(1)\n"
  },
  {
    "path": "skills/docx/scripts/comment.py",
    "content": "\"\"\"Add comments to DOCX documents.\n\nUsage:\n    python comment.py unpacked/ 0 \"Comment text\"\n    python comment.py unpacked/ 1 \"Reply text\" --parent 0\n\nText should be pre-escaped XML (e.g., &amp; for &, &#x2019; for smart quotes).\n\nAfter running, add markers to document.xml:\n  <w:commentRangeStart w:id=\"0\"/>\n  ... commented content ...\n  <w:commentRangeEnd w:id=\"0\"/>\n  <w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"0\"/></w:r>\n\"\"\"\n\nimport argparse\nimport random\nimport shutil\nimport sys\nfrom datetime import datetime, timezone\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nTEMPLATE_DIR = Path(__file__).parent / \"templates\"\nNS = {\n    \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n    \"w14\": \"http://schemas.microsoft.com/office/word/2010/wordml\",\n    \"w15\": \"http://schemas.microsoft.com/office/word/2012/wordml\",\n    \"w16cid\": \"http://schemas.microsoft.com/office/word/2016/wordml/cid\",\n    \"w16cex\": \"http://schemas.microsoft.com/office/word/2018/wordml/cex\",\n}\n\nCOMMENT_XML = \"\"\"\\\n<w:comment w:id=\"{id}\" w:author=\"{author}\" w:date=\"{date}\" w:initials=\"{initials}\">\n  <w:p w14:paraId=\"{para_id}\" w14:textId=\"77777777\">\n    <w:r>\n      <w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr>\n      <w:annotationRef/>\n    </w:r>\n    <w:r>\n      <w:rPr>\n        <w:color w:val=\"000000\"/>\n        <w:sz w:val=\"20\"/>\n        <w:szCs w:val=\"20\"/>\n      </w:rPr>\n      <w:t>{text}</w:t>\n    </w:r>\n  </w:p>\n</w:comment>\"\"\"\n\nCOMMENT_MARKER_TEMPLATE = \"\"\"\nAdd to document.xml (markers must be direct children of w:p, never inside w:r):\n  <w:commentRangeStart w:id=\"{cid}\"/>\n  <w:r>...</w:r>\n  <w:commentRangeEnd w:id=\"{cid}\"/>\n  <w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"{cid}\"/></w:r>\"\"\"\n\nREPLY_MARKER_TEMPLATE = \"\"\"\nNest markers inside parent {pid}'s markers (markers must be direct children of w:p, never inside w:r):\n  <w:commentRangeStart w:id=\"{pid}\"/><w:commentRangeStart w:id=\"{cid}\"/>\n  <w:r>...</w:r>\n  <w:commentRangeEnd w:id=\"{cid}\"/><w:commentRangeEnd w:id=\"{pid}\"/>\n  <w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"{pid}\"/></w:r>\n  <w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:commentReference w:id=\"{cid}\"/></w:r>\"\"\"\n\n\ndef _generate_hex_id() -> str:\n    return f\"{random.randint(0, 0x7FFFFFFE):08X}\"\n\n\nSMART_QUOTE_ENTITIES = {\n    \"\\u201c\": \"&#x201C;\",  \n    \"\\u201d\": \"&#x201D;\",  \n    \"\\u2018\": \"&#x2018;\",  \n    \"\\u2019\": \"&#x2019;\",  \n}\n\n\ndef _encode_smart_quotes(text: str) -> str:\n    for char, entity in SMART_QUOTE_ENTITIES.items():\n        text = text.replace(char, entity)\n    return text\n\n\ndef _append_xml(xml_path: Path, root_tag: str, content: str) -> None:\n    dom = defusedxml.minidom.parseString(xml_path.read_text(encoding=\"utf-8\"))\n    root = dom.getElementsByTagName(root_tag)[0]\n    ns_attrs = \" \".join(f'xmlns:{k}=\"{v}\"' for k, v in NS.items())\n    wrapper_dom = defusedxml.minidom.parseString(f\"<root {ns_attrs}>{content}</root>\")\n    for child in wrapper_dom.documentElement.childNodes:  \n        if child.nodeType == child.ELEMENT_NODE:\n            root.appendChild(dom.importNode(child, True))\n    output = _encode_smart_quotes(dom.toxml(encoding=\"UTF-8\").decode(\"utf-8\"))\n    xml_path.write_text(output, encoding=\"utf-8\")\n\n\ndef _find_para_id(comments_path: Path, comment_id: int) -> str | None:\n    dom = defusedxml.minidom.parseString(comments_path.read_text(encoding=\"utf-8\"))\n    for c in dom.getElementsByTagName(\"w:comment\"):\n        if c.getAttribute(\"w:id\") == str(comment_id):\n            for p in c.getElementsByTagName(\"w:p\"):\n                if pid := p.getAttribute(\"w14:paraId\"):\n                    return pid\n    return None\n\n\ndef _get_next_rid(rels_path: Path) -> int:\n    dom = defusedxml.minidom.parseString(rels_path.read_text(encoding=\"utf-8\"))\n    max_rid = 0\n    for rel in dom.getElementsByTagName(\"Relationship\"):\n        rid = rel.getAttribute(\"Id\")\n        if rid and rid.startswith(\"rId\"):\n            try:\n                max_rid = max(max_rid, int(rid[3:]))\n            except ValueError:\n                pass\n    return max_rid + 1\n\n\ndef _has_relationship(rels_path: Path, target: str) -> bool:\n    dom = defusedxml.minidom.parseString(rels_path.read_text(encoding=\"utf-8\"))\n    for rel in dom.getElementsByTagName(\"Relationship\"):\n        if rel.getAttribute(\"Target\") == target:\n            return True\n    return False\n\n\ndef _has_content_type(ct_path: Path, part_name: str) -> bool:\n    dom = defusedxml.minidom.parseString(ct_path.read_text(encoding=\"utf-8\"))\n    for override in dom.getElementsByTagName(\"Override\"):\n        if override.getAttribute(\"PartName\") == part_name:\n            return True\n    return False\n\n\ndef _ensure_comment_relationships(unpacked_dir: Path) -> None:\n    rels_path = unpacked_dir / \"word\" / \"_rels\" / \"document.xml.rels\"\n    if not rels_path.exists():\n        return\n\n    if _has_relationship(rels_path, \"comments.xml\"):\n        return  \n\n    dom = defusedxml.minidom.parseString(rels_path.read_text(encoding=\"utf-8\"))\n    root = dom.documentElement\n    next_rid = _get_next_rid(rels_path)\n\n    rels = [\n        (\n            \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\",\n            \"comments.xml\",\n        ),\n        (\n            \"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\",\n            \"commentsExtended.xml\",\n        ),\n        (\n            \"http://schemas.microsoft.com/office/2016/09/relationships/commentsIds\",\n            \"commentsIds.xml\",\n        ),\n        (\n            \"http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible\",\n            \"commentsExtensible.xml\",\n        ),\n    ]\n\n    for rel_type, target in rels:\n        rel = dom.createElement(\"Relationship\")\n        rel.setAttribute(\"Id\", f\"rId{next_rid}\")\n        rel.setAttribute(\"Type\", rel_type)\n        rel.setAttribute(\"Target\", target)\n        root.appendChild(rel)  \n        next_rid += 1\n\n    rels_path.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n\ndef _ensure_comment_content_types(unpacked_dir: Path) -> None:\n    ct_path = unpacked_dir / \"[Content_Types].xml\"\n    if not ct_path.exists():\n        return\n\n    if _has_content_type(ct_path, \"/word/comments.xml\"):\n        return  \n\n    dom = defusedxml.minidom.parseString(ct_path.read_text(encoding=\"utf-8\"))\n    root = dom.documentElement\n\n    overrides = [\n        (\n            \"/word/comments.xml\",\n            \"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml\",\n        ),\n        (\n            \"/word/commentsExtended.xml\",\n            \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml\",\n        ),\n        (\n            \"/word/commentsIds.xml\",\n            \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml\",\n        ),\n        (\n            \"/word/commentsExtensible.xml\",\n            \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml\",\n        ),\n    ]\n\n    for part_name, content_type in overrides:\n        override = dom.createElement(\"Override\")\n        override.setAttribute(\"PartName\", part_name)\n        override.setAttribute(\"ContentType\", content_type)\n        root.appendChild(override)  \n\n    ct_path.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n\ndef add_comment(\n    unpacked_dir: str,\n    comment_id: int,\n    text: str,\n    author: str = \"Claude\",\n    initials: str = \"C\",\n    parent_id: int | None = None,\n) -> tuple[str, str]:\n    word = Path(unpacked_dir) / \"word\"\n    if not word.exists():\n        return \"\", f\"Error: {word} not found\"\n\n    para_id, durable_id = _generate_hex_id(), _generate_hex_id()\n    ts = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n\n    comments = word / \"comments.xml\"\n    first_comment = not comments.exists()\n    if first_comment:\n        shutil.copy(TEMPLATE_DIR / \"comments.xml\", comments)\n        _ensure_comment_relationships(Path(unpacked_dir))\n        _ensure_comment_content_types(Path(unpacked_dir))\n    _append_xml(\n        comments,\n        \"w:comments\",\n        COMMENT_XML.format(\n            id=comment_id,\n            author=author,\n            date=ts,\n            initials=initials,\n            para_id=para_id,\n            text=text,  \n        ),\n    )\n\n    ext = word / \"commentsExtended.xml\"\n    if not ext.exists():\n        shutil.copy(TEMPLATE_DIR / \"commentsExtended.xml\", ext)\n    if parent_id is not None:\n        parent_para = _find_para_id(comments, parent_id)\n        if not parent_para:\n            return \"\", f\"Error: Parent comment {parent_id} not found\"\n        _append_xml(\n            ext,\n            \"w15:commentsEx\",\n            f'<w15:commentEx w15:paraId=\"{para_id}\" w15:paraIdParent=\"{parent_para}\" w15:done=\"0\"/>',\n        )\n    else:\n        _append_xml(\n            ext,\n            \"w15:commentsEx\",\n            f'<w15:commentEx w15:paraId=\"{para_id}\" w15:done=\"0\"/>',\n        )\n\n    ids = word / \"commentsIds.xml\"\n    if not ids.exists():\n        shutil.copy(TEMPLATE_DIR / \"commentsIds.xml\", ids)\n    _append_xml(\n        ids,\n        \"w16cid:commentsIds\",\n        f'<w16cid:commentId w16cid:paraId=\"{para_id}\" w16cid:durableId=\"{durable_id}\"/>',\n    )\n\n    extensible = word / \"commentsExtensible.xml\"\n    if not extensible.exists():\n        shutil.copy(TEMPLATE_DIR / \"commentsExtensible.xml\", extensible)\n    _append_xml(\n        extensible,\n        \"w16cex:commentsExtensible\",\n        f'<w16cex:commentExtensible w16cex:durableId=\"{durable_id}\" w16cex:dateUtc=\"{ts}\"/>',\n    )\n\n    action = \"reply\" if parent_id is not None else \"comment\"\n    return para_id, f\"Added {action} {comment_id} (para_id={para_id})\"\n\n\nif __name__ == \"__main__\":\n    p = argparse.ArgumentParser(description=\"Add comments to DOCX documents\")\n    p.add_argument(\"unpacked_dir\", help=\"Unpacked DOCX directory\")\n    p.add_argument(\"comment_id\", type=int, help=\"Comment ID (must be unique)\")\n    p.add_argument(\"text\", help=\"Comment text\")\n    p.add_argument(\"--author\", default=\"Claude\", help=\"Author name\")\n    p.add_argument(\"--initials\", default=\"C\", help=\"Author initials\")\n    p.add_argument(\"--parent\", type=int, help=\"Parent comment ID (for replies)\")\n    args = p.parse_args()\n\n    para_id, msg = add_comment(\n        args.unpacked_dir,\n        args.comment_id,\n        args.text,\n        args.author,\n        args.initials,\n        args.parent,\n    )\n    print(msg)\n    if \"Error\" in msg:\n        sys.exit(1)\n    cid = args.comment_id\n    if args.parent is not None:\n        print(REPLY_MARKER_TEMPLATE.format(pid=args.parent, cid=cid))\n    else:\n        print(COMMENT_MARKER_TEMPLATE.format(cid=cid))\n"
  },
  {
    "path": "skills/docx/scripts/office/helpers/__init__.py",
    "content": ""
  },
  {
    "path": "skills/docx/scripts/office/helpers/merge_runs.py",
    "content": "\"\"\"Merge adjacent runs with identical formatting in DOCX.\n\nMerges adjacent <w:r> elements that have identical <w:rPr> properties.\nWorks on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).\n\nAlso:\n- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)\n- Removes proofErr elements (spell/grammar markers that block merging)\n\"\"\"\n\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\n\ndef merge_runs(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        _remove_elements(root, \"proofErr\")\n        _strip_run_rsid_attrs(root)\n\n        containers = {run.parentNode for run in _find_elements(root, \"r\")}\n\n        merge_count = 0\n        for container in containers:\n            merge_count += _merge_runs_in(container)\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Merged {merge_count} runs\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef _get_child(parent, tag: str):\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                return child\n    return None\n\n\ndef _get_children(parent, tag: str) -> list:\n    results = []\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(child)\n    return results\n\n\ndef _is_adjacent(elem1, elem2) -> bool:\n    node = elem1.nextSibling\n    while node:\n        if node == elem2:\n            return True\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n    return False\n\n\n\n\ndef _remove_elements(root, tag: str):\n    for elem in _find_elements(root, tag):\n        if elem.parentNode:\n            elem.parentNode.removeChild(elem)\n\n\ndef _strip_run_rsid_attrs(root):\n    for run in _find_elements(root, \"r\"):\n        for attr in list(run.attributes.values()):\n            if \"rsid\" in attr.name.lower():\n                run.removeAttribute(attr.name)\n\n\n\n\ndef _merge_runs_in(container) -> int:\n    merge_count = 0\n    run = _first_child_run(container)\n\n    while run:\n        while True:\n            next_elem = _next_element_sibling(run)\n            if next_elem and _is_run(next_elem) and _can_merge(run, next_elem):\n                _merge_run_content(run, next_elem)\n                container.removeChild(next_elem)\n                merge_count += 1\n            else:\n                break\n\n        _consolidate_text(run)\n        run = _next_sibling_run(run)\n\n    return merge_count\n\n\ndef _first_child_run(container):\n    for child in container.childNodes:\n        if child.nodeType == child.ELEMENT_NODE and _is_run(child):\n            return child\n    return None\n\n\ndef _next_element_sibling(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _next_sibling_run(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            if _is_run(sibling):\n                return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _is_run(node) -> bool:\n    name = node.localName or node.tagName\n    return name == \"r\" or name.endswith(\":r\")\n\n\ndef _can_merge(run1, run2) -> bool:\n    rpr1 = _get_child(run1, \"rPr\")\n    rpr2 = _get_child(run2, \"rPr\")\n\n    if (rpr1 is None) != (rpr2 is None):\n        return False\n    if rpr1 is None:\n        return True\n    return rpr1.toxml() == rpr2.toxml()  \n\n\ndef _merge_run_content(target, source):\n    for child in list(source.childNodes):\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name != \"rPr\" and not name.endswith(\":rPr\"):\n                target.appendChild(child)\n\n\ndef _consolidate_text(run):\n    t_elements = _get_children(run, \"t\")\n\n    for i in range(len(t_elements) - 1, 0, -1):\n        curr, prev = t_elements[i], t_elements[i - 1]\n\n        if _is_adjacent(prev, curr):\n            prev_text = prev.firstChild.data if prev.firstChild else \"\"\n            curr_text = curr.firstChild.data if curr.firstChild else \"\"\n            merged = prev_text + curr_text\n\n            if prev.firstChild:\n                prev.firstChild.data = merged\n            else:\n                prev.appendChild(run.ownerDocument.createTextNode(merged))\n\n            if merged.startswith(\" \") or merged.endswith(\" \"):\n                prev.setAttribute(\"xml:space\", \"preserve\")\n            elif prev.hasAttribute(\"xml:space\"):\n                prev.removeAttribute(\"xml:space\")\n\n            run.removeChild(curr)\n"
  },
  {
    "path": "skills/docx/scripts/office/helpers/simplify_redlines.py",
    "content": "\"\"\"Simplify tracked changes by merging adjacent w:ins or w:del elements.\n\nMerges adjacent <w:ins> elements from the same author into a single element.\nSame for <w:del> elements. This makes heavily-redlined documents easier to\nwork with by reducing the number of tracked change wrappers.\n\nRules:\n- Only merges w:ins with w:ins, w:del with w:del (same element type)\n- Only merges if same author (ignores timestamp differences)\n- Only merges if truly adjacent (only whitespace between them)\n\"\"\"\n\nimport xml.etree.ElementTree as ET\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nWORD_NS = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\n\ndef simplify_redlines(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        merge_count = 0\n\n        containers = _find_elements(root, \"p\") + _find_elements(root, \"tc\")\n\n        for container in containers:\n            merge_count += _merge_tracked_changes_in(container, \"ins\")\n            merge_count += _merge_tracked_changes_in(container, \"del\")\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Simplified {merge_count} tracked changes\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\ndef _merge_tracked_changes_in(container, tag: str) -> int:\n    merge_count = 0\n\n    tracked = [\n        child\n        for child in container.childNodes\n        if child.nodeType == child.ELEMENT_NODE and _is_element(child, tag)\n    ]\n\n    if len(tracked) < 2:\n        return 0\n\n    i = 0\n    while i < len(tracked) - 1:\n        curr = tracked[i]\n        next_elem = tracked[i + 1]\n\n        if _can_merge_tracked(curr, next_elem):\n            _merge_tracked_content(curr, next_elem)\n            container.removeChild(next_elem)\n            tracked.pop(i + 1)\n            merge_count += 1\n        else:\n            i += 1\n\n    return merge_count\n\n\ndef _is_element(node, tag: str) -> bool:\n    name = node.localName or node.tagName\n    return name == tag or name.endswith(f\":{tag}\")\n\n\ndef _get_author(elem) -> str:\n    author = elem.getAttribute(\"w:author\")\n    if not author:\n        for attr in elem.attributes.values():\n            if attr.localName == \"author\" or attr.name.endswith(\":author\"):\n                return attr.value\n    return author\n\n\ndef _can_merge_tracked(elem1, elem2) -> bool:\n    if _get_author(elem1) != _get_author(elem2):\n        return False\n\n    node = elem1.nextSibling\n    while node and node != elem2:\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n\n    return True\n\n\ndef _merge_tracked_content(target, source):\n    while source.firstChild:\n        child = source.firstChild\n        source.removeChild(child)\n        target.appendChild(child)\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]:\n    if not doc_xml_path.exists():\n        return {}\n\n    try:\n        tree = ET.parse(doc_xml_path)\n        root = tree.getroot()\n    except ET.ParseError:\n        return {}\n\n    namespaces = {\"w\": WORD_NS}\n    author_attr = f\"{{{WORD_NS}}}author\"\n\n    authors: dict[str, int] = {}\n    for tag in [\"ins\", \"del\"]:\n        for elem in root.findall(f\".//w:{tag}\", namespaces):\n            author = elem.get(author_attr)\n            if author:\n                authors[author] = authors.get(author, 0) + 1\n\n    return authors\n\n\ndef _get_authors_from_docx(docx_path: Path) -> dict[str, int]:\n    try:\n        with zipfile.ZipFile(docx_path, \"r\") as zf:\n            if \"word/document.xml\" not in zf.namelist():\n                return {}\n            with zf.open(\"word/document.xml\") as f:\n                tree = ET.parse(f)\n                root = tree.getroot()\n\n                namespaces = {\"w\": WORD_NS}\n                author_attr = f\"{{{WORD_NS}}}author\"\n\n                authors: dict[str, int] = {}\n                for tag in [\"ins\", \"del\"]:\n                    for elem in root.findall(f\".//w:{tag}\", namespaces):\n                        author = elem.get(author_attr)\n                        if author:\n                            authors[author] = authors.get(author, 0) + 1\n                return authors\n    except (zipfile.BadZipFile, ET.ParseError):\n        return {}\n\n\ndef infer_author(modified_dir: Path, original_docx: Path, default: str = \"Claude\") -> str:\n    modified_xml = modified_dir / \"word\" / \"document.xml\"\n    modified_authors = get_tracked_change_authors(modified_xml)\n\n    if not modified_authors:\n        return default\n\n    original_authors = _get_authors_from_docx(original_docx)\n\n    new_changes: dict[str, int] = {}\n    for author, count in modified_authors.items():\n        original_count = original_authors.get(author, 0)\n        diff = count - original_count\n        if diff > 0:\n            new_changes[author] = diff\n\n    if not new_changes:\n        return default\n\n    if len(new_changes) == 1:\n        return next(iter(new_changes))\n\n    raise ValueError(\n        f\"Multiple authors added new changes: {new_changes}. \"\n        \"Cannot infer which author to validate.\"\n    )\n"
  },
  {
    "path": "skills/docx/scripts/office/pack.py",
    "content": "\"\"\"Pack a directory into a DOCX, PPTX, or XLSX file.\n\nValidates with auto-repair, condenses XML formatting, and creates the Office file.\n\nUsage:\n    python pack.py <input_directory> <output_file> [--original <file>] [--validate true|false]\n\nExamples:\n    python pack.py unpacked/ output.docx --original input.docx\n    python pack.py unpacked/ output.pptx --validate false\n\"\"\"\n\nimport argparse\nimport sys\nimport shutil\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\ndef pack(\n    input_directory: str,\n    output_file: str,\n    original_file: str | None = None,\n    validate: bool = True,\n    infer_author_func=None,\n) -> tuple[None, str]:\n    input_dir = Path(input_directory)\n    output_path = Path(output_file)\n    suffix = output_path.suffix.lower()\n\n    if not input_dir.is_dir():\n        return None, f\"Error: {input_dir} is not a directory\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {output_file} must be a .docx, .pptx, or .xlsx file\"\n\n    if validate and original_file:\n        original_path = Path(original_file)\n        if original_path.exists():\n            success, output = _run_validation(\n                input_dir, original_path, suffix, infer_author_func\n            )\n            if output:\n                print(output)\n            if not success:\n                return None, f\"Error: Validation failed for {input_dir}\"\n\n    with tempfile.TemporaryDirectory() as temp_dir:\n        temp_content_dir = Path(temp_dir) / \"content\"\n        shutil.copytree(input_dir, temp_content_dir)\n\n        for pattern in [\"*.xml\", \"*.rels\"]:\n            for xml_file in temp_content_dir.rglob(pattern):\n                _condense_xml(xml_file)\n\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n            for f in temp_content_dir.rglob(\"*\"):\n                if f.is_file():\n                    zf.write(f, f.relative_to(temp_content_dir))\n\n    return None, f\"Successfully packed {input_dir} to {output_file}\"\n\n\ndef _run_validation(\n    unpacked_dir: Path,\n    original_file: Path,\n    suffix: str,\n    infer_author_func=None,\n) -> tuple[bool, str | None]:\n    output_lines = []\n    validators = []\n\n    if suffix == \".docx\":\n        author = \"Claude\"\n        if infer_author_func:\n            try:\n                author = infer_author_func(unpacked_dir, original_file)\n            except ValueError as e:\n                print(f\"Warning: {e} Using default author 'Claude'.\", file=sys.stderr)\n\n        validators = [\n            DOCXSchemaValidator(unpacked_dir, original_file),\n            RedliningValidator(unpacked_dir, original_file, author=author),\n        ]\n    elif suffix == \".pptx\":\n        validators = [PPTXSchemaValidator(unpacked_dir, original_file)]\n\n    if not validators:\n        return True, None\n\n    total_repairs = sum(v.repair() for v in validators)\n    if total_repairs:\n        output_lines.append(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        output_lines.append(\"All validations PASSED!\")\n\n    return success, \"\\n\".join(output_lines) if output_lines else None\n\n\ndef _condense_xml(xml_file: Path) -> None:\n    try:\n        with open(xml_file, encoding=\"utf-8\") as f:\n            dom = defusedxml.minidom.parse(f)\n\n        for element in dom.getElementsByTagName(\"*\"):\n            if element.tagName.endswith(\":t\"):\n                continue\n\n            for child in list(element.childNodes):\n                if (\n                    child.nodeType == child.TEXT_NODE\n                    and child.nodeValue\n                    and child.nodeValue.strip() == \"\"\n                ) or child.nodeType == child.COMMENT_NODE:\n                    element.removeChild(child)\n\n        xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n    except Exception as e:\n        print(f\"ERROR: Failed to parse {xml_file.name}: {e}\", file=sys.stderr)\n        raise\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Pack a directory into a DOCX, PPTX, or XLSX file\"\n    )\n    parser.add_argument(\"input_directory\", help=\"Unpacked Office document directory\")\n    parser.add_argument(\"output_file\", help=\"Output Office file (.docx/.pptx/.xlsx)\")\n    parser.add_argument(\n        \"--original\",\n        help=\"Original file for validation comparison\",\n    )\n    parser.add_argument(\n        \"--validate\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Run validation with auto-repair (default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = pack(\n        args.input_directory,\n        args.output_file,\n        original_file=args.original,\n        validate=args.validate,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  xmlns:cdr=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n    schemaLocation=\"dml-chartDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Double\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedInt\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumData\">\n    <xsd:sequence>\n      <xsd:element name=\"formatCode\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_NumVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numCache\" type=\"CT_NumData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strCache\" type=\"CT_StrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"rich\" type=\"a:CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLanguageID\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"multiLvlStrCache\" type=\"CT_MultiLvlStrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AxDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"multiLvlStrRef\" type=\"CT_MultiLvlStrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strLit\" type=\"CT_StrData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerTx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutTarget\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inner\"/>\n      <xsd:enumeration value=\"outer\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutTarget\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutTarget\" default=\"outer\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"edge\"/>\n      <xsd:enumeration value=\"factor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutMode\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutMode\" default=\"factor\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualLayout\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutTarget\" type=\"CT_LayoutTarget\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"x\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"w\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"h\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Layout\">\n    <xsd:sequence>\n      <xsd:element name=\"manualLayout\" type=\"CT_ManualLayout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Title\">\n    <xsd:sequence>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotX\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-90\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotX\">\n    <xsd:attribute name=\"val\" type=\"ST_RotX\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HPercent\">\n    <xsd:union memberTypes=\"ST_HPercentWithSymbol ST_HPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_HPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotY\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotY\">\n    <xsd:attribute name=\"val\" type=\"ST_RotY\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DepthPercent\">\n    <xsd:union memberTypes=\"ST_DepthPercentWithSymbol ST_DepthPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"20\"/>\n      <xsd:maxInclusive value=\"2000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DepthPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_DepthPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Perspective\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"240\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perspective\">\n    <xsd:attribute name=\"val\" type=\"ST_Perspective\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_View3D\">\n    <xsd:sequence>\n      <xsd:element name=\"rotX\" type=\"CT_RotX\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hPercent\" type=\"CT_HPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rotY\" type=\"CT_RotY\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"depthPercent\" type=\"CT_DepthPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rAngAx\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"perspective\" type=\"CT_Perspective\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface\">\n    <xsd:sequence>\n      <xsd:element name=\"thickness\" type=\"CT_Thickness\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Thickness\">\n    <xsd:union memberTypes=\"ST_ThicknessPercent xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ThicknessPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"([0-9]+)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Thickness\">\n    <xsd:attribute name=\"val\" type=\"ST_Thickness\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DTable\">\n    <xsd:sequence>\n      <xsd:element name=\"showHorzBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVertBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showOutline\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showKeys\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GapAmount\">\n    <xsd:union memberTypes=\"ST_GapAmountPercent ST_GapAmountUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GapAmount\">\n    <xsd:attribute name=\"val\" type=\"ST_GapAmount\" default=\"150%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Overlap\">\n    <xsd:union memberTypes=\"ST_OverlapPercent ST_OverlapByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"(-?0*(([0-9])|([1-9][0-9])|100))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapByte\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-100\"/>\n      <xsd:maxInclusive value=\"100\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Overlap\">\n    <xsd:attribute name=\"val\" type=\"ST_Overlap\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BubbleScale\">\n    <xsd:union memberTypes=\"ST_BubbleScalePercent ST_BubbleScaleUInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-2][0-9][0-9])|300)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScaleUInt\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"300\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BubbleScale\">\n    <xsd:attribute name=\"val\" type=\"ST_BubbleScale\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SizeRepresents\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"w\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SizeRepresents\">\n    <xsd:attribute name=\"val\" type=\"ST_SizeRepresents\" default=\"area\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FirstSliceAng\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FirstSliceAng\">\n    <xsd:attribute name=\"val\" type=\"ST_FirstSliceAng\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HoleSize\">\n    <xsd:union memberTypes=\"ST_HoleSizePercent ST_HoleSizeUByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*([1-9]|([1-8][0-9])|90)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizeUByte\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HoleSize\">\n    <xsd:attribute name=\"val\" type=\"ST_HoleSize\" default=\"10%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SplitType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"val\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SplitType\">\n    <xsd:attribute name=\"val\" type=\"ST_SplitType\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustSplit\">\n    <xsd:sequence>\n      <xsd:element name=\"secondPiePt\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SecondPieSize\">\n    <xsd:union memberTypes=\"ST_SecondPieSizePercent ST_SecondPieSizeUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|(1[0-9][0-9])|200)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizeUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SecondPieSize\">\n    <xsd:attribute name=\"val\" type=\"ST_SecondPieSize\" default=\"75%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceLinked\" type=\"xsd:boolean\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblAlgn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblAlgn\">\n    <xsd:attribute name=\"val\" type=\"ST_LblAlgn\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"inBase\"/>\n      <xsd:enumeration value=\"inEnd\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"outEnd\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_DLblPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_DLblShared\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLblPos\" type=\"CT_DLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLegendKey\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVal\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showCatName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showSerName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPercent\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showBubbleSize\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"separator\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"Group_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbl\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"Group_DLbls\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLeaderLines\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"leaderLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbls\">\n    <xsd:sequence>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbls\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"picture\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"star\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerStyle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerSize\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"72\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerSize\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerSize\" default=\"5\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"symbol\" type=\"CT_MarkerStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"size\" type=\"CT_MarkerSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TrendlineType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"exp\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"log\"/>\n      <xsd:enumeration value=\"movingAvg\"/>\n      <xsd:enumeration value=\"poly\"/>\n      <xsd:enumeration value=\"power\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TrendlineType\">\n    <xsd:attribute name=\"val\" type=\"ST_TrendlineType\" default=\"linear\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Order\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"6\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Order\">\n    <xsd:attribute name=\"val\" type=\"ST_Order\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Period\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Period\">\n    <xsd:attribute name=\"val\" type=\"ST_Period\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrendlineLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Trendline\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineType\" type=\"CT_TrendlineType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_Order\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"period\" type=\"CT_Period\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"intercept\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispRSqr\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispEq\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineLbl\" type=\"CT_TrendlineLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrDir\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrDir\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrBarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"minus\"/>\n      <xsd:enumeration value=\"plus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrBarType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrBarType\" default=\"both\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrValType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"fixedVal\"/>\n      <xsd:enumeration value=\"percentage\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdErr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrValType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrValType\" default=\"fixedVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ErrBars\">\n    <xsd:sequence>\n      <xsd:element name=\"errDir\" type=\"CT_ErrDir\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errBarType\" type=\"CT_ErrBarType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errValType\" type=\"CT_ErrValType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noEndCap\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBar\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBars\">\n    <xsd:sequence>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"downBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SerShared\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_SerTx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AreaSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PieSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleSize\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SurfaceSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Grouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Grouping\">\n    <xsd:attribute name=\"val\" type=\"ST_Grouping\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartLines\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StockChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"3\" maxOccurs=\"4\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ScatterStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineMarker\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"smooth\"/>\n      <xsd:enumeration value=\"smoothMarker\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ScatterStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_ScatterStyle\" default=\"marker\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterChart\">\n    <xsd:sequence>\n      <xsd:element name=\"scatterStyle\" type=\"CT_ScatterStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_ScatterSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RadarStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"filled\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RadarStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_RadarStyle\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarChart\">\n    <xsd:sequence>\n      <xsd:element name=\"radarStyle\" type=\"CT_RadarStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_RadarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"clustered\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarGrouping\">\n    <xsd:attribute name=\"val\" type=\"ST_BarGrouping\" default=\"clustered\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarDir\">\n    <xsd:attribute name=\"val\" type=\"ST_BarDir\" default=\"col\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shape\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cone\"/>\n      <xsd:enumeration value=\"coneToMax\"/>\n      <xsd:enumeration value=\"box\"/>\n      <xsd:enumeration value=\"cylinder\"/>\n      <xsd:enumeration value=\"pyramid\"/>\n      <xsd:enumeration value=\"pyramidToMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:attribute name=\"val\" type=\"ST_Shape\" default=\"box\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_BarChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"barDir\" type=\"CT_BarDir\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grouping\" type=\"CT_BarGrouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_BarChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlap\" type=\"CT_Overlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AreaChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_AreaSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AreaChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Area3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PieChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_PieSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_PieChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pie3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DoughnutChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"holeSize\" type=\"CT_HoleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_OfPieType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"bar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OfPieType\">\n    <xsd:attribute name=\"val\" type=\"ST_OfPieType\" default=\"pie\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfPieChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ofPieType\" type=\"CT_OfPieType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitType\" type=\"CT_SplitType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitPos\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custSplit\" type=\"CT_CustSplit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"secondPieSize\" type=\"CT_SecondPieSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleChart\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BubbleSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleScale\" type=\"CT_BubbleScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showNegBubbles\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sizeRepresents\" type=\"CT_SizeRepresents\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"bandFmt\" type=\"CT_BandFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SurfaceChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"wireframe\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_SurfaceSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"bandFmts\" type=\"CT_BandFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SurfaceChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxPos\">\n    <xsd:attribute name=\"val\" type=\"ST_AxPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Crosses\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"autoZero\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Crosses\">\n    <xsd:attribute name=\"val\" type=\"ST_Crosses\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CrossBetween\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"midCat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CrossBetween\">\n    <xsd:attribute name=\"val\" type=\"ST_CrossBetween\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"out\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickMark\">\n    <xsd:attribute name=\"val\" type=\"ST_TickMark\" default=\"cross\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"high\"/>\n      <xsd:enumeration value=\"low\"/>\n      <xsd:enumeration value=\"nextTo\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_TickLblPos\" default=\"nextTo\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Skip\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Skip\">\n    <xsd:attribute name=\"val\" type=\"ST_Skip\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TimeUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TimeUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_TimeUnit\" default=\"days\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxisUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxisUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_AxisUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BuiltInUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hundreds\"/>\n      <xsd:enumeration value=\"thousands\"/>\n      <xsd:enumeration value=\"tenThousands\"/>\n      <xsd:enumeration value=\"hundredThousands\"/>\n      <xsd:enumeration value=\"millions\"/>\n      <xsd:enumeration value=\"tenMillions\"/>\n      <xsd:enumeration value=\"hundredMillions\"/>\n      <xsd:enumeration value=\"billions\"/>\n      <xsd:enumeration value=\"trillions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BuiltInUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_BuiltInUnit\" default=\"thousands\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stretch\"/>\n      <xsd:enumeration value=\"stack\"/>\n      <xsd:enumeration value=\"stackScale\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureFormat\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureFormat\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureStackUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureStackUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureStackUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureOptions\">\n    <xsd:sequence>\n      <xsd:element name=\"applyToFront\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToSides\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToEnd\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureFormat\" type=\"CT_PictureFormat\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureStackUnit\" type=\"CT_PictureStackUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnitsLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnits\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"custUnit\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"builtInUnit\" type=\"CT_BuiltInUnit\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dispUnitsLbl\" type=\"CT_DispUnitsLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"maxMin\"/>\n      <xsd:enumeration value=\"minMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Orientation\">\n    <xsd:attribute name=\"val\" type=\"ST_Orientation\" default=\"minMax\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LogBase\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LogBase\">\n    <xsd:attribute name=\"val\" type=\"ST_LogBase\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scaling\">\n    <xsd:sequence>\n      <xsd:element name=\"logBase\" type=\"CT_LogBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"orientation\" type=\"CT_Orientation\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"max\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"min\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblOffset\">\n    <xsd:union memberTypes=\"ST_LblOffsetPercent ST_LblOffsetUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblOffset\">\n    <xsd:attribute name=\"val\" type=\"ST_LblOffset\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AxShared\">\n    <xsd:sequence>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scaling\" type=\"CT_Scaling\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axPos\" type=\"CT_AxPos\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblPos\" type=\"CT_TickLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossAx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"crosses\" type=\"CT_Crosses\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"crossesAt\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CatAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblAlgn\" type=\"CT_LblAlgn\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noMultiLvlLbl\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"baseTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ValAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossBetween\" type=\"CT_CrossBetween\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispUnits\" type=\"CT_DispUnits\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PlotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"areaChart\" type=\"CT_AreaChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"area3DChart\" type=\"CT_Area3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lineChart\" type=\"CT_LineChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"line3DChart\" type=\"CT_Line3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"stockChart\" type=\"CT_StockChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"radarChart\" type=\"CT_RadarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"scatterChart\" type=\"CT_ScatterChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pieChart\" type=\"CT_PieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pie3DChart\" type=\"CT_Pie3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"doughnutChart\" type=\"CT_DoughnutChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"barChart\" type=\"CT_BarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bar3DChart\" type=\"CT_Bar3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ofPieChart\" type=\"CT_OfPieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surfaceChart\" type=\"CT_SurfaceChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surface3DChart\" type=\"CT_Surface3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bubbleChart\" type=\"CT_BubbleChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"valAx\" type=\"CT_ValAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"catAx\" type=\"CT_CatAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"dateAx\" type=\"CT_DateAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"serAx\" type=\"CT_SerAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dTable\" type=\"CT_DTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotFmt\" type=\"CT_PivotFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LegendPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LegendPos\">\n    <xsd:attribute name=\"val\" type=\"ST_LegendPos\" default=\"r\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LegendEntryData\">\n    <xsd:sequence>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LegendEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"EG_LegendEntryData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Legend\">\n    <xsd:sequence>\n      <xsd:element name=\"legendPos\" type=\"CT_LegendPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legendEntry\" type=\"CT_LegendEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DispBlanksAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"gap\"/>\n      <xsd:enumeration value=\"zero\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DispBlanksAs\">\n    <xsd:attribute name=\"val\" type=\"ST_DispBlanksAs\" default=\"zero\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chart\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoTitleDeleted\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotFmts\" type=\"CT_PivotFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"view3D\" type=\"CT_View3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"floor\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sideWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotArea\" type=\"CT_PlotArea\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legend\" type=\"CT_Legend\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotVisOnly\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispBlanksAs\" type=\"CT_DispBlanksAs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showDLblsOverMax\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"48\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSource\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Protection\">\n    <xsd:sequence>\n      <xsd:element name=\"chartObject\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"data\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formatting\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userInterface\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"l\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageSetupOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ExternalData\">\n    <xsd:sequence>\n      <xsd:element name=\"autoUpdate\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_PageSetupOrientation\" use=\"optional\"\n      default=\"default\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartSpace\">\n    <xsd:sequence>\n      <xsd:element name=\"date1904\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lang\" type=\"CT_TextLanguageID\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"roundedCorners\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotSource\" type=\"CT_PivotSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_Protection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chart\" type=\"CT_Chart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalData\" type=\"CT_ExternalData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printSettings\" type=\"CT_PrintSettings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userShapes\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"chartSpace\" type=\"CT_ChartSpace\"/>\n  <xsd:element name=\"userShapes\" type=\"cdr:CT_Drawing\"/>\n  <xsd:element name=\"chart\" type=\"CT_RelId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_MarkerCoordinate\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"0.0\"/>\n      <xsd:maxInclusive value=\"1.0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"relSizeAnchor\" type=\"CT_RelSizeAnchor\"/>\n      <xsd:element name=\"absSizeAnchor\" type=\"CT_AbsSizeAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_CTName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_CTCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ClrAppMethod\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HueDir\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"meth\" type=\"ST_ClrAppMethod\" use=\"optional\" default=\"span\"/>\n    <xsd:attribute name=\"hueDir\" type=\"ST_HueDir\" use=\"optional\" default=\"cw\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTStyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"fillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"linClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txLinClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txFillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txEffectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorTransform\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_CTStyleLabel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDef\" type=\"CT_ColorTransform\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdrLst\" type=\"CT_ColorTransformHeaderLst\"/>\n  <xsd:simpleType name=\"ST_PtType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pt\">\n    <xsd:sequence>\n      <xsd:element name=\"prSet\" type=\"CT_ElemPropSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PtType\" use=\"optional\" default=\"node\"/>\n    <xsd:attribute name=\"cxnId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PtList\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_Pt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CxnType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parOf\"/>\n      <xsd:enumeration value=\"presOf\"/>\n      <xsd:enumeration value=\"presParOf\"/>\n      <xsd:enumeration value=\"unknownRelationship\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cxn\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_CxnType\" use=\"optional\" default=\"parOf\"/>\n    <xsd:attribute name=\"srcId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"destId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"srcOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"destOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"parTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sibTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"presId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CxnList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_Cxn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataModel\">\n    <xsd:sequence>\n      <xsd:element name=\"ptLst\" type=\"CT_PtList\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_CxnList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"dataModel\" type=\"CT_DataModel\"/>\n  <xsd:attributeGroup name=\"AG_IteratorAttributes\">\n    <xsd:attribute name=\"axis\" type=\"ST_AxisTypes\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementTypes\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"hideLastTrans\" type=\"ST_Booleans\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"st\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cnt\" type=\"ST_UnsignedInts\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"step\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintAttributes\">\n    <xsd:attribute name=\"type\" type=\"ST_ConstraintType\" use=\"required\"/>\n    <xsd:attribute name=\"for\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"forName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintRefAttributes\">\n    <xsd:attribute name=\"refType\" type=\"ST_ConstraintType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"refFor\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"refForName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"refPtType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_Constraint\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ConstraintRefAttributes\"/>\n    <xsd:attribute name=\"op\" type=\"ST_BoolOperator\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Constraints\">\n    <xsd:sequence>\n      <xsd:element name=\"constr\" type=\"CT_Constraint\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumericRule\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"rule\" type=\"CT_NumericRule\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationOf\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutShapeType\" final=\"restriction\">\n    <xsd:union memberTypes=\"a:ST_ShapeType ST_OutputShapeType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index1\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Adj\">\n    <xsd:attribute name=\"idx\" type=\"ST_Index1\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjLst\">\n    <xsd:sequence>\n      <xsd:element name=\"adj\" type=\"CT_Adj\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"adjLst\" type=\"CT_AdjLst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"type\" type=\"ST_LayoutShapeType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute ref=\"r:blip\" use=\"optional\"/>\n    <xsd:attribute name=\"zOrderOff\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hideGeom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lkTxEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"blipPhldr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"type\" type=\"ST_ParameterId\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ParameterVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Algorithm\">\n    <xsd:sequence>\n      <xsd:element name=\"param\" type=\"CT_Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_AlgorithmType\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutNode\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varLst\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"styleLbl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"chOrder\" type=\"ST_ChildOrderType\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"moveWith\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ForEach\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ref\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_When\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n    <xsd:attribute name=\"func\" type=\"ST_FunctionType\" use=\"required\"/>\n    <xsd:attribute name=\"arg\" type=\"ST_FunctionArgument\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"op\" type=\"ST_FunctionOperator\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FunctionValue\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Otherwise\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Choose\">\n    <xsd:sequence>\n      <xsd:element name=\"if\" type=\"CT_When\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"else\" type=\"CT_Otherwise\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SampleData\">\n    <xsd:sequence>\n      <xsd:element name=\"dataModel\" type=\"CT_DataModel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useDef\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Category\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Categories\">\n    <xsd:sequence>\n      <xsd:element name=\"cat\" type=\"CT_Category\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Name\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Description\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DiagramDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"sampData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"clrData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDef\" type=\"CT_DiagramDefinition\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdrLst\" type=\"CT_DiagramDefinitionHeaderLst\"/>\n  <xsd:complexType name=\"CT_RelIds\">\n    <xsd:attribute ref=\"r:dm\" use=\"required\"/>\n    <xsd:attribute ref=\"r:lo\" use=\"required\"/>\n    <xsd:attribute ref=\"r:qs\" use=\"required\"/>\n    <xsd:attribute ref=\"r:cs\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"relIds\" type=\"CT_RelIds\"/>\n  <xsd:simpleType name=\"ST_ParameterVal\">\n    <xsd:union\n      memberTypes=\"ST_DiagramHorizontalAlignment ST_VerticalAlignment ST_ChildDirection ST_ChildAlignment ST_SecondaryChildAlignment ST_LinearDirection ST_SecondaryLinearDirection ST_StartingElement ST_BendPoint ST_ConnectorRouting ST_ArrowheadStyle ST_ConnectorDimension ST_RotationPath ST_CenterShapeMapping ST_NodeHorizontalAlignment ST_NodeVerticalAlignment ST_FallbackDimension ST_TextDirection ST_PyramidAccentPosition ST_PyramidAccentTextMargin ST_TextBlockDirection ST_TextAnchorHorizontal ST_TextAnchorVertical ST_DiagramTextAlignment ST_AutoTextRotation ST_GrowDirection ST_FlowDirection ST_ContinueDirection ST_Breakpoint ST_Offset ST_HierarchyAlignment xsd:int xsd:double xsd:boolean xsd:string ST_ConnectorPoint\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ModelId\">\n    <xsd:union memberTypes=\"xsd:int s:ST_Guid\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrSetCustVal\">\n    <xsd:union memberTypes=\"s:ST_Percentage xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ElemPropSet\">\n    <xsd:sequence>\n      <xsd:element name=\"presLayoutVars\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"presAssocID\" type=\"ST_ModelId\" use=\"optional\"/>\n    <xsd:attribute name=\"presName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleLbl\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleIdx\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleCnt\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"loTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"loCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coherent3DOff\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"phldrT\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"phldr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custAng\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipVert\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipHor\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzX\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzY\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custT\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleRad\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleInc\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"rev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierBranchStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"hang\"/>\n      <xsd:enumeration value=\"std\"/>\n      <xsd:enumeration value=\"init\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimOneStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"branch\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimLvlStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"lvl\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OrgChart\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NodeCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChildMax\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChildPref\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BulletEnabled\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Direction\">\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" default=\"norm\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierBranchStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_HierBranchStyle\" default=\"std\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimOne\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimOneStr\" default=\"one\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimLvl\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimLvlStr\" default=\"none\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ResizeHandlesStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"rel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ResizeHandles\">\n    <xsd:attribute name=\"val\" type=\"ST_ResizeHandlesStr\" default=\"rel\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutVariablePropertySet\">\n    <xsd:sequence>\n      <xsd:element name=\"orgChart\" type=\"CT_OrgChart\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chMax\" type=\"CT_ChildMax\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chPref\" type=\"CT_ChildPref\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bulletEnabled\" type=\"CT_BulletEnabled\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dir\" type=\"CT_Direction\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hierBranch\" type=\"CT_HierBranchStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animOne\" type=\"CT_AnimOne\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animLvl\" type=\"CT_AnimLvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"resizeHandles\" type=\"CT_ResizeHandles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_SDCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextProps\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"a:CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"CT_TextProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_StyleLabel\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDef\" type=\"CT_StyleDefinition\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdrLst\" type=\"CT_StyleDefinitionHeaderLst\"/>\n  <xsd:simpleType name=\"ST_AlgorithmType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"composite\"/>\n      <xsd:enumeration value=\"conn\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"hierChild\"/>\n      <xsd:enumeration value=\"hierRoot\"/>\n      <xsd:enumeration value=\"pyra\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"snake\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n      <xsd:enumeration value=\"desOrSelf\"/>\n      <xsd:enumeration value=\"par\"/>\n      <xsd:enumeration value=\"ancst\"/>\n      <xsd:enumeration value=\"ancstOrSelf\"/>\n      <xsd:enumeration value=\"followSib\"/>\n      <xsd:enumeration value=\"precedSib\"/>\n      <xsd:enumeration value=\"follow\"/>\n      <xsd:enumeration value=\"preced\"/>\n      <xsd:enumeration value=\"root\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisTypes\">\n    <xsd:list itemType=\"ST_AxisType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BoolOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildOrderType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alignOff\"/>\n      <xsd:enumeration value=\"begMarg\"/>\n      <xsd:enumeration value=\"bendDist\"/>\n      <xsd:enumeration value=\"begPad\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"bMarg\"/>\n      <xsd:enumeration value=\"bOff\"/>\n      <xsd:enumeration value=\"ctrX\"/>\n      <xsd:enumeration value=\"ctrXOff\"/>\n      <xsd:enumeration value=\"ctrY\"/>\n      <xsd:enumeration value=\"ctrYOff\"/>\n      <xsd:enumeration value=\"connDist\"/>\n      <xsd:enumeration value=\"diam\"/>\n      <xsd:enumeration value=\"endMarg\"/>\n      <xsd:enumeration value=\"endPad\"/>\n      <xsd:enumeration value=\"h\"/>\n      <xsd:enumeration value=\"hArH\"/>\n      <xsd:enumeration value=\"hOff\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"lMarg\"/>\n      <xsd:enumeration value=\"lOff\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"rMarg\"/>\n      <xsd:enumeration value=\"rOff\"/>\n      <xsd:enumeration value=\"primFontSz\"/>\n      <xsd:enumeration value=\"pyraAcctRatio\"/>\n      <xsd:enumeration value=\"secFontSz\"/>\n      <xsd:enumeration value=\"sibSp\"/>\n      <xsd:enumeration value=\"secSibSp\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"stemThick\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tMarg\"/>\n      <xsd:enumeration value=\"tOff\"/>\n      <xsd:enumeration value=\"userA\"/>\n      <xsd:enumeration value=\"userB\"/>\n      <xsd:enumeration value=\"userC\"/>\n      <xsd:enumeration value=\"userD\"/>\n      <xsd:enumeration value=\"userE\"/>\n      <xsd:enumeration value=\"userF\"/>\n      <xsd:enumeration value=\"userG\"/>\n      <xsd:enumeration value=\"userH\"/>\n      <xsd:enumeration value=\"userI\"/>\n      <xsd:enumeration value=\"userJ\"/>\n      <xsd:enumeration value=\"userK\"/>\n      <xsd:enumeration value=\"userL\"/>\n      <xsd:enumeration value=\"userM\"/>\n      <xsd:enumeration value=\"userN\"/>\n      <xsd:enumeration value=\"userO\"/>\n      <xsd:enumeration value=\"userP\"/>\n      <xsd:enumeration value=\"userQ\"/>\n      <xsd:enumeration value=\"userR\"/>\n      <xsd:enumeration value=\"userS\"/>\n      <xsd:enumeration value=\"userT\"/>\n      <xsd:enumeration value=\"userU\"/>\n      <xsd:enumeration value=\"userV\"/>\n      <xsd:enumeration value=\"userW\"/>\n      <xsd:enumeration value=\"userX\"/>\n      <xsd:enumeration value=\"userY\"/>\n      <xsd:enumeration value=\"userZ\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"wArH\"/>\n      <xsd:enumeration value=\"wOff\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintRelationship\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"nonNorm\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"nonAsst\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementTypes\">\n    <xsd:list itemType=\"ST_ElementType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ParameterId\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horzAlign\"/>\n      <xsd:enumeration value=\"vertAlign\"/>\n      <xsd:enumeration value=\"chDir\"/>\n      <xsd:enumeration value=\"chAlign\"/>\n      <xsd:enumeration value=\"secChAlign\"/>\n      <xsd:enumeration value=\"linDir\"/>\n      <xsd:enumeration value=\"secLinDir\"/>\n      <xsd:enumeration value=\"stElem\"/>\n      <xsd:enumeration value=\"bendPt\"/>\n      <xsd:enumeration value=\"connRout\"/>\n      <xsd:enumeration value=\"begSty\"/>\n      <xsd:enumeration value=\"endSty\"/>\n      <xsd:enumeration value=\"dim\"/>\n      <xsd:enumeration value=\"rotPath\"/>\n      <xsd:enumeration value=\"ctrShpMap\"/>\n      <xsd:enumeration value=\"nodeHorzAlign\"/>\n      <xsd:enumeration value=\"nodeVertAlign\"/>\n      <xsd:enumeration value=\"fallback\"/>\n      <xsd:enumeration value=\"txDir\"/>\n      <xsd:enumeration value=\"pyraAcctPos\"/>\n      <xsd:enumeration value=\"pyraAcctTxMar\"/>\n      <xsd:enumeration value=\"txBlDir\"/>\n      <xsd:enumeration value=\"txAnchorHorz\"/>\n      <xsd:enumeration value=\"txAnchorVert\"/>\n      <xsd:enumeration value=\"txAnchorHorzCh\"/>\n      <xsd:enumeration value=\"txAnchorVertCh\"/>\n      <xsd:enumeration value=\"parTxLTRAlign\"/>\n      <xsd:enumeration value=\"parTxRTLAlign\"/>\n      <xsd:enumeration value=\"shpTxLTRAlignCh\"/>\n      <xsd:enumeration value=\"shpTxRTLAlignCh\"/>\n      <xsd:enumeration value=\"autoTxRot\"/>\n      <xsd:enumeration value=\"grDir\"/>\n      <xsd:enumeration value=\"flowDir\"/>\n      <xsd:enumeration value=\"contDir\"/>\n      <xsd:enumeration value=\"bkpt\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"hierAlign\"/>\n      <xsd:enumeration value=\"bkPtFixedVal\"/>\n      <xsd:enumeration value=\"stBulletLvl\"/>\n      <xsd:enumeration value=\"stAng\"/>\n      <xsd:enumeration value=\"spanAng\"/>\n      <xsd:enumeration value=\"ar\"/>\n      <xsd:enumeration value=\"lnSpPar\"/>\n      <xsd:enumeration value=\"lnSpAfParP\"/>\n      <xsd:enumeration value=\"lnSpCh\"/>\n      <xsd:enumeration value=\"lnSpAfChP\"/>\n      <xsd:enumeration value=\"rtShortDist\"/>\n      <xsd:enumeration value=\"alignTx\"/>\n      <xsd:enumeration value=\"pyraLvlNode\"/>\n      <xsd:enumeration value=\"pyraAcctBkgdNode\"/>\n      <xsd:enumeration value=\"pyraAcctTxNode\"/>\n      <xsd:enumeration value=\"srcNode\"/>\n      <xsd:enumeration value=\"dstNode\"/>\n      <xsd:enumeration value=\"begPts\"/>\n      <xsd:enumeration value=\"endPts\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ints\">\n    <xsd:list itemType=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedInts\">\n    <xsd:list itemType=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Booleans\">\n    <xsd:list itemType=\"xsd:boolean\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cnt\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"revPos\"/>\n      <xsd:enumeration value=\"posEven\"/>\n      <xsd:enumeration value=\"posOdd\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"depth\"/>\n      <xsd:enumeration value=\"maxDepth\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"neq\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryLinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StartingElement\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"trans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RotationPath\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alongPath\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CenterShapeMapping\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fNode\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BendPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"beg\"/>\n      <xsd:enumeration value=\"def\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorRouting\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"stra\"/>\n      <xsd:enumeration value=\"bend\"/>\n      <xsd:enumeration value=\"curve\"/>\n      <xsd:enumeration value=\"longCurve\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrowheadStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"arr\"/>\n      <xsd:enumeration value=\"noArr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"bCtr\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"midL\"/>\n      <xsd:enumeration value=\"midR\"/>\n      <xsd:enumeration value=\"tCtr\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"radial\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeVerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FallbackDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentPosition\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bef\"/>\n      <xsd:enumeration value=\"aft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentTextMargin\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"step\"/>\n      <xsd:enumeration value=\"stack\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBlockDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorHorizontal\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorVertical\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramTextAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AutoTextRotation\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"upr\"/>\n      <xsd:enumeration value=\"grav\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GrowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FlowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContinueDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"revDir\"/>\n      <xsd:enumeration value=\"sameDir\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Breakpoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"endCnv\"/>\n      <xsd:enumeration value=\"bal\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Offset\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierarchyAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"tCtrCh\"/>\n      <xsd:enumeration value=\"tCtrDes\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"bCtrCh\"/>\n      <xsd:enumeration value=\"bCtrDes\"/>\n      <xsd:enumeration value=\"lT\"/>\n      <xsd:enumeration value=\"lB\"/>\n      <xsd:enumeration value=\"lCtrCh\"/>\n      <xsd:enumeration value=\"lCtrDes\"/>\n      <xsd:enumeration value=\"rT\"/>\n      <xsd:enumeration value=\"rB\"/>\n      <xsd:enumeration value=\"rCtrCh\"/>\n      <xsd:enumeration value=\"rCtrDes\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionValue\" final=\"restriction\">\n    <xsd:union\n      memberTypes=\"xsd:int xsd:boolean ST_Direction ST_HierBranchStyle ST_AnimOneStr ST_AnimLvlStr ST_ResizeHandlesStr\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VariableType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"orgChart\"/>\n      <xsd:enumeration value=\"chMax\"/>\n      <xsd:enumeration value=\"chPref\"/>\n      <xsd:enumeration value=\"bulEnabled\"/>\n      <xsd:enumeration value=\"dir\"/>\n      <xsd:enumeration value=\"hierBranch\"/>\n      <xsd:enumeration value=\"animOne\"/>\n      <xsd:enumeration value=\"animLvl\"/>\n      <xsd:enumeration value=\"resizeHandles\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionArgument\" final=\"restriction\">\n    <xsd:union memberTypes=\"ST_VariableType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OutputShapeType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"conn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:element name=\"lockedCanvas\" type=\"a:CT_GvmlGroupShape\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n    schemaLocation=\"dml-diagram.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n    schemaLocation=\"dml-chart.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n    schemaLocation=\"dml-lockedCanvas.xsd\"/>\n  <xsd:complexType name=\"CT_AudioFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VideoFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QuickTimeFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCDTime\">\n    <xsd:attribute name=\"track\" type=\"xsd:unsignedByte\" use=\"required\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCD\">\n    <xsd:sequence>\n      <xsd:element name=\"st\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Media\">\n    <xsd:choice>\n      <xsd:element name=\"audioCd\" type=\"CT_AudioCD\"/>\n      <xsd:element name=\"wavAudioFile\" type=\"CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"audioFile\" type=\"CT_AudioFile\"/>\n      <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n      <xsd:element name=\"quickTimeFile\" type=\"CT_QuickTimeFile\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n  <xsd:simpleType name=\"ST_StyleMatrixColumnIndex\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontCollectionIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"dk1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dk2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent3\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent4\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent5\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent6\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"folHlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SupplementalFont\">\n    <xsd:attribute name=\"script\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColorList\">\n    <xsd:sequence>\n      <xsd:element name=\"custClr\" type=\"CT_CustomColor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontCollection\">\n    <xsd:sequence>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"font\" type=\"CT_SupplementalFont\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleItem\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"majorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LineStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"effectStyle\" type=\"CT_EffectStyleItem\" minOccurs=\"3\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrix\">\n    <xsd:sequence>\n      <xsd:element name=\"fillStyleLst\" type=\"CT_FillStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnStyleLst\" type=\"CT_LineStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectStyleLst\" type=\"CT_EffectStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgFillStyleLst\" type=\"CT_BackgroundFillStyleList\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeArtExtension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Coordinate\">\n    <xsd:union memberTypes=\"ST_CoordinateUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CoordinateUnqualified\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"-27273042329600\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32\">\n    <xsd:union memberTypes=\"ST_Coordinate32Unqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32Unqualified\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate32\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Angle\">\n    <xsd:attribute name=\"val\" type=\"ST_Angle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minExclusive value=\"-5400000\"/>\n      <xsd:maxExclusive value=\"5400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxExclusive value=\"21600000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedAngle\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:union memberTypes=\"ST_PercentageDecimal s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PercentageDecimal\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Percentage\">\n    <xsd:attribute name=\"val\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:union memberTypes=\"ST_PositivePercentageDecimal s:ST_PositivePercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositivePercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:union memberTypes=\"ST_FixedPercentageDecimal s:ST_FixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"-100000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:union memberTypes=\"ST_PositiveFixedPercentageDecimal s:ST_PositiveFixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ratio\">\n    <xsd:attribute name=\"n\" type=\"xsd:long\" use=\"required\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:long\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point2D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PositiveSize2D\">\n    <xsd:attribute name=\"cx\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ComplementTransform\"/>\n  <xsd:complexType name=\"CT_InverseTransform\"/>\n  <xsd:complexType name=\"CT_GrayscaleTransform\"/>\n  <xsd:complexType name=\"CT_GammaTransform\"/>\n  <xsd:complexType name=\"CT_InverseGammaTransform\"/>\n  <xsd:group name=\"EG_ColorTransform\">\n    <xsd:choice>\n      <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"comp\" type=\"CT_ComplementTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"inv\" type=\"CT_InverseTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gray\" type=\"CT_GrayscaleTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOff\" type=\"CT_FixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hue\" type=\"CT_PositiveFixedAngle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueOff\" type=\"CT_Angle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sat\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"red\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"green\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blue\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gamma\" type=\"CT_GammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invGamma\" type=\"CT_InverseGammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ScRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HslColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SystemColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"scrollBar\"/>\n      <xsd:enumeration value=\"background\"/>\n      <xsd:enumeration value=\"activeCaption\"/>\n      <xsd:enumeration value=\"inactiveCaption\"/>\n      <xsd:enumeration value=\"menu\"/>\n      <xsd:enumeration value=\"window\"/>\n      <xsd:enumeration value=\"windowFrame\"/>\n      <xsd:enumeration value=\"menuText\"/>\n      <xsd:enumeration value=\"windowText\"/>\n      <xsd:enumeration value=\"captionText\"/>\n      <xsd:enumeration value=\"activeBorder\"/>\n      <xsd:enumeration value=\"inactiveBorder\"/>\n      <xsd:enumeration value=\"appWorkspace\"/>\n      <xsd:enumeration value=\"highlight\"/>\n      <xsd:enumeration value=\"highlightText\"/>\n      <xsd:enumeration value=\"btnFace\"/>\n      <xsd:enumeration value=\"btnShadow\"/>\n      <xsd:enumeration value=\"grayText\"/>\n      <xsd:enumeration value=\"btnText\"/>\n      <xsd:enumeration value=\"inactiveCaptionText\"/>\n      <xsd:enumeration value=\"btnHighlight\"/>\n      <xsd:enumeration value=\"3dDkShadow\"/>\n      <xsd:enumeration value=\"3dLight\"/>\n      <xsd:enumeration value=\"infoText\"/>\n      <xsd:enumeration value=\"infoBk\"/>\n      <xsd:enumeration value=\"hotLight\"/>\n      <xsd:enumeration value=\"gradientActiveCaption\"/>\n      <xsd:enumeration value=\"gradientInactiveCaption\"/>\n      <xsd:enumeration value=\"menuHighlight\"/>\n      <xsd:enumeration value=\"menuBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SystemColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SystemColorVal\" use=\"required\"/>\n    <xsd:attribute name=\"lastClr\" type=\"s:ST_HexColorRGB\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SchemeColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bg1\"/>\n      <xsd:enumeration value=\"tx1\"/>\n      <xsd:enumeration value=\"bg2\"/>\n      <xsd:enumeration value=\"tx2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n      <xsd:enumeration value=\"phClr\"/>\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SchemeColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"aliceBlue\"/>\n      <xsd:enumeration value=\"antiqueWhite\"/>\n      <xsd:enumeration value=\"aqua\"/>\n      <xsd:enumeration value=\"aquamarine\"/>\n      <xsd:enumeration value=\"azure\"/>\n      <xsd:enumeration value=\"beige\"/>\n      <xsd:enumeration value=\"bisque\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blanchedAlmond\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"blueViolet\"/>\n      <xsd:enumeration value=\"brown\"/>\n      <xsd:enumeration value=\"burlyWood\"/>\n      <xsd:enumeration value=\"cadetBlue\"/>\n      <xsd:enumeration value=\"chartreuse\"/>\n      <xsd:enumeration value=\"chocolate\"/>\n      <xsd:enumeration value=\"coral\"/>\n      <xsd:enumeration value=\"cornflowerBlue\"/>\n      <xsd:enumeration value=\"cornsilk\"/>\n      <xsd:enumeration value=\"crimson\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGoldenrod\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"darkGrey\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkKhaki\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkOliveGreen\"/>\n      <xsd:enumeration value=\"darkOrange\"/>\n      <xsd:enumeration value=\"darkOrchid\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkSalmon\"/>\n      <xsd:enumeration value=\"darkSeaGreen\"/>\n      <xsd:enumeration value=\"darkSlateBlue\"/>\n      <xsd:enumeration value=\"darkSlateGray\"/>\n      <xsd:enumeration value=\"darkSlateGrey\"/>\n      <xsd:enumeration value=\"darkTurquoise\"/>\n      <xsd:enumeration value=\"darkViolet\"/>\n      <xsd:enumeration value=\"dkBlue\"/>\n      <xsd:enumeration value=\"dkCyan\"/>\n      <xsd:enumeration value=\"dkGoldenrod\"/>\n      <xsd:enumeration value=\"dkGray\"/>\n      <xsd:enumeration value=\"dkGrey\"/>\n      <xsd:enumeration value=\"dkGreen\"/>\n      <xsd:enumeration value=\"dkKhaki\"/>\n      <xsd:enumeration value=\"dkMagenta\"/>\n      <xsd:enumeration value=\"dkOliveGreen\"/>\n      <xsd:enumeration value=\"dkOrange\"/>\n      <xsd:enumeration value=\"dkOrchid\"/>\n      <xsd:enumeration value=\"dkRed\"/>\n      <xsd:enumeration value=\"dkSalmon\"/>\n      <xsd:enumeration value=\"dkSeaGreen\"/>\n      <xsd:enumeration value=\"dkSlateBlue\"/>\n      <xsd:enumeration value=\"dkSlateGray\"/>\n      <xsd:enumeration value=\"dkSlateGrey\"/>\n      <xsd:enumeration value=\"dkTurquoise\"/>\n      <xsd:enumeration value=\"dkViolet\"/>\n      <xsd:enumeration value=\"deepPink\"/>\n      <xsd:enumeration value=\"deepSkyBlue\"/>\n      <xsd:enumeration value=\"dimGray\"/>\n      <xsd:enumeration value=\"dimGrey\"/>\n      <xsd:enumeration value=\"dodgerBlue\"/>\n      <xsd:enumeration value=\"firebrick\"/>\n      <xsd:enumeration value=\"floralWhite\"/>\n      <xsd:enumeration value=\"forestGreen\"/>\n      <xsd:enumeration value=\"fuchsia\"/>\n      <xsd:enumeration value=\"gainsboro\"/>\n      <xsd:enumeration value=\"ghostWhite\"/>\n      <xsd:enumeration value=\"gold\"/>\n      <xsd:enumeration value=\"goldenrod\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"grey\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"greenYellow\"/>\n      <xsd:enumeration value=\"honeydew\"/>\n      <xsd:enumeration value=\"hotPink\"/>\n      <xsd:enumeration value=\"indianRed\"/>\n      <xsd:enumeration value=\"indigo\"/>\n      <xsd:enumeration value=\"ivory\"/>\n      <xsd:enumeration value=\"khaki\"/>\n      <xsd:enumeration value=\"lavender\"/>\n      <xsd:enumeration value=\"lavenderBlush\"/>\n      <xsd:enumeration value=\"lawnGreen\"/>\n      <xsd:enumeration value=\"lemonChiffon\"/>\n      <xsd:enumeration value=\"lightBlue\"/>\n      <xsd:enumeration value=\"lightCoral\"/>\n      <xsd:enumeration value=\"lightCyan\"/>\n      <xsd:enumeration value=\"lightGoldenrodYellow\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"lightGrey\"/>\n      <xsd:enumeration value=\"lightGreen\"/>\n      <xsd:enumeration value=\"lightPink\"/>\n      <xsd:enumeration value=\"lightSalmon\"/>\n      <xsd:enumeration value=\"lightSeaGreen\"/>\n      <xsd:enumeration value=\"lightSkyBlue\"/>\n      <xsd:enumeration value=\"lightSlateGray\"/>\n      <xsd:enumeration value=\"lightSlateGrey\"/>\n      <xsd:enumeration value=\"lightSteelBlue\"/>\n      <xsd:enumeration value=\"lightYellow\"/>\n      <xsd:enumeration value=\"ltBlue\"/>\n      <xsd:enumeration value=\"ltCoral\"/>\n      <xsd:enumeration value=\"ltCyan\"/>\n      <xsd:enumeration value=\"ltGoldenrodYellow\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"ltGrey\"/>\n      <xsd:enumeration value=\"ltGreen\"/>\n      <xsd:enumeration value=\"ltPink\"/>\n      <xsd:enumeration value=\"ltSalmon\"/>\n      <xsd:enumeration value=\"ltSeaGreen\"/>\n      <xsd:enumeration value=\"ltSkyBlue\"/>\n      <xsd:enumeration value=\"ltSlateGray\"/>\n      <xsd:enumeration value=\"ltSlateGrey\"/>\n      <xsd:enumeration value=\"ltSteelBlue\"/>\n      <xsd:enumeration value=\"ltYellow\"/>\n      <xsd:enumeration value=\"lime\"/>\n      <xsd:enumeration value=\"limeGreen\"/>\n      <xsd:enumeration value=\"linen\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"maroon\"/>\n      <xsd:enumeration value=\"medAquamarine\"/>\n      <xsd:enumeration value=\"medBlue\"/>\n      <xsd:enumeration value=\"medOrchid\"/>\n      <xsd:enumeration value=\"medPurple\"/>\n      <xsd:enumeration value=\"medSeaGreen\"/>\n      <xsd:enumeration value=\"medSlateBlue\"/>\n      <xsd:enumeration value=\"medSpringGreen\"/>\n      <xsd:enumeration value=\"medTurquoise\"/>\n      <xsd:enumeration value=\"medVioletRed\"/>\n      <xsd:enumeration value=\"mediumAquamarine\"/>\n      <xsd:enumeration value=\"mediumBlue\"/>\n      <xsd:enumeration value=\"mediumOrchid\"/>\n      <xsd:enumeration value=\"mediumPurple\"/>\n      <xsd:enumeration value=\"mediumSeaGreen\"/>\n      <xsd:enumeration value=\"mediumSlateBlue\"/>\n      <xsd:enumeration value=\"mediumSpringGreen\"/>\n      <xsd:enumeration value=\"mediumTurquoise\"/>\n      <xsd:enumeration value=\"mediumVioletRed\"/>\n      <xsd:enumeration value=\"midnightBlue\"/>\n      <xsd:enumeration value=\"mintCream\"/>\n      <xsd:enumeration value=\"mistyRose\"/>\n      <xsd:enumeration value=\"moccasin\"/>\n      <xsd:enumeration value=\"navajoWhite\"/>\n      <xsd:enumeration value=\"navy\"/>\n      <xsd:enumeration value=\"oldLace\"/>\n      <xsd:enumeration value=\"olive\"/>\n      <xsd:enumeration value=\"oliveDrab\"/>\n      <xsd:enumeration value=\"orange\"/>\n      <xsd:enumeration value=\"orangeRed\"/>\n      <xsd:enumeration value=\"orchid\"/>\n      <xsd:enumeration value=\"paleGoldenrod\"/>\n      <xsd:enumeration value=\"paleGreen\"/>\n      <xsd:enumeration value=\"paleTurquoise\"/>\n      <xsd:enumeration value=\"paleVioletRed\"/>\n      <xsd:enumeration value=\"papayaWhip\"/>\n      <xsd:enumeration value=\"peachPuff\"/>\n      <xsd:enumeration value=\"peru\"/>\n      <xsd:enumeration value=\"pink\"/>\n      <xsd:enumeration value=\"plum\"/>\n      <xsd:enumeration value=\"powderBlue\"/>\n      <xsd:enumeration value=\"purple\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"rosyBrown\"/>\n      <xsd:enumeration value=\"royalBlue\"/>\n      <xsd:enumeration value=\"saddleBrown\"/>\n      <xsd:enumeration value=\"salmon\"/>\n      <xsd:enumeration value=\"sandyBrown\"/>\n      <xsd:enumeration value=\"seaGreen\"/>\n      <xsd:enumeration value=\"seaShell\"/>\n      <xsd:enumeration value=\"sienna\"/>\n      <xsd:enumeration value=\"silver\"/>\n      <xsd:enumeration value=\"skyBlue\"/>\n      <xsd:enumeration value=\"slateBlue\"/>\n      <xsd:enumeration value=\"slateGray\"/>\n      <xsd:enumeration value=\"slateGrey\"/>\n      <xsd:enumeration value=\"snow\"/>\n      <xsd:enumeration value=\"springGreen\"/>\n      <xsd:enumeration value=\"steelBlue\"/>\n      <xsd:enumeration value=\"tan\"/>\n      <xsd:enumeration value=\"teal\"/>\n      <xsd:enumeration value=\"thistle\"/>\n      <xsd:enumeration value=\"tomato\"/>\n      <xsd:enumeration value=\"turquoise\"/>\n      <xsd:enumeration value=\"violet\"/>\n      <xsd:enumeration value=\"wheat\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"whiteSmoke\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"yellowGreen\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_PresetColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_OfficeArtExtension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OfficeArtExtensionList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scale2D\">\n    <xsd:sequence>\n      <xsd:element name=\"sx\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sy\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Transform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupTransform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chOff\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chExt\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point3D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vector3D\">\n    <xsd:attribute name=\"dx\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dy\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dz\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SphereCoords\">\n    <xsd:attribute name=\"lat\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"lon\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeRect\">\n    <xsd:attribute name=\"l\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"t\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RectAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:group name=\"EG_ColorChoice\">\n    <xsd:choice>\n      <xsd:element name=\"scrgbClr\" type=\"CT_ScRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hslClr\" type=\"CT_HslColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sysClr\" type=\"CT_SystemColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstClr\" type=\"CT_PresetColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMRU\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlackWhiteMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clr\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"invGray\"/>\n      <xsd:enumeration value=\"grayWhite\"/>\n      <xsd:enumeration value=\"blackGray\"/>\n      <xsd:enumeration value=\"blackWhite\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Blob\">\n    <xsd:attribute ref=\"r:embed\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:link\" use=\"optional\" default=\"\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_EmbeddedWAVAudioFile\">\n    <xsd:attribute ref=\"r:embed\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:sequence>\n      <xsd:element name=\"snd\" type=\"CT_EmbeddedWAVAudioFile\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalidUrl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"action\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tooltip\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"highlightClick\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"endSnd\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DrawingElementId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Locking\">\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noEditPoints\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noAdjustHandles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeArrowheads\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeShapeType\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_ConnectorLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noTextEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noCrop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noUngrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noDrilldown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ContentPartLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkHover\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"descr\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"spLocks\" type=\"CT_ShapeLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"txBox\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualConnectorProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cxnSpLocks\" type=\"CT_ConnectorLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualPictureProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"picLocks\" type=\"CT_PictureLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preferRelativeResize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGroupDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"grpSpLocks\" type=\"CT_GroupLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGraphicFrameProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicFrameLocks\" type=\"CT_GraphicalObjectFrameLocking\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualContentPartProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cpLocks\" type=\"CT_ContentPartLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isComment\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectData\">\n    <xsd:sequence>\n      <xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"strict\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObject\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicData\" type=\"CT_GraphicalObjectData\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"graphic\" type=\"CT_GraphicalObject\"/>\n  <xsd:simpleType name=\"ST_ChartBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"allPts\"/>\n      <xsd:enumeration value=\"gridLegend\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DgmBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"bg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmElement\">\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"optional\"\n      default=\"{00000000-0000-0000-0000-000000000000}\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_DgmBuildStep\" use=\"optional\" default=\"sp\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationChartElement\">\n    <xsd:attribute name=\"seriesIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"categoryIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_ChartBuildStep\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationElementChoice\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"dgm\" type=\"CT_AnimationDgmElement\"/>\n      <xsd:element name=\"chart\" type=\"CT_AnimationChartElement\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"lvlOne\"/>\n      <xsd:enumeration value=\"lvlAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationDgmOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationDgmBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationChartOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationChartBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationChartOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationChartBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationGraphicalObjectBuildProperties\">\n    <xsd:choice>\n      <xsd:element name=\"bldDgm\" type=\"CT_AnimationDgmBuildProperties\"/>\n      <xsd:element name=\"bldChart\" type=\"CT_AnimationChartBuildProperties\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFormatting\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WholeE2oFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlUseShapeRectangle\"/>\n  <xsd:complexType name=\"CT_GvmlTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"useSpRect\" type=\"CT_GvmlUseShapeRectangle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_GvmlShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_GvmlConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"CT_NonVisualPictureProperties\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPicture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_GvmlPictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GvmlGraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element ref=\"graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GvmlGroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\"/>\n        <xsd:element name=\"sp\" type=\"CT_GvmlShape\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_GvmlConnector\"/>\n        <xsd:element name=\"pic\" type=\"CT_GvmlPicture\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GvmlGraphicalObjectFrame\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GvmlGroupShape\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetCameraType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueTop\"/>\n      <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n      <xsd:enumeration value=\"legacyObliqueLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueFront\"/>\n      <xsd:enumeration value=\"legacyObliqueRight\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueBottom\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n      <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n      <xsd:enumeration value=\"orthographicFront\"/>\n      <xsd:enumeration value=\"isometricTopUp\"/>\n      <xsd:enumeration value=\"isometricTopDown\"/>\n      <xsd:enumeration value=\"isometricBottomUp\"/>\n      <xsd:enumeration value=\"isometricBottomDown\"/>\n      <xsd:enumeration value=\"isometricLeftUp\"/>\n      <xsd:enumeration value=\"isometricLeftDown\"/>\n      <xsd:enumeration value=\"isometricRightUp\"/>\n      <xsd:enumeration value=\"isometricRightDown\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n      <xsd:enumeration value=\"obliqueTopLeft\"/>\n      <xsd:enumeration value=\"obliqueTop\"/>\n      <xsd:enumeration value=\"obliqueTopRight\"/>\n      <xsd:enumeration value=\"obliqueLeft\"/>\n      <xsd:enumeration value=\"obliqueRight\"/>\n      <xsd:enumeration value=\"obliqueBottomLeft\"/>\n      <xsd:enumeration value=\"obliqueBottom\"/>\n      <xsd:enumeration value=\"obliqueBottomRight\"/>\n      <xsd:enumeration value=\"perspectiveFront\"/>\n      <xsd:enumeration value=\"perspectiveLeft\"/>\n      <xsd:enumeration value=\"perspectiveRight\"/>\n      <xsd:enumeration value=\"perspectiveAbove\"/>\n      <xsd:enumeration value=\"perspectiveBelow\"/>\n      <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveRelaxed\"/>\n      <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FOVAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"10800000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Camera\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetCameraType\" use=\"required\"/>\n    <xsd:attribute name=\"fov\" type=\"ST_FOVAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"zoom\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LightRigDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LightRigType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyFlat1\"/>\n      <xsd:enumeration value=\"legacyFlat2\"/>\n      <xsd:enumeration value=\"legacyFlat3\"/>\n      <xsd:enumeration value=\"legacyFlat4\"/>\n      <xsd:enumeration value=\"legacyNormal1\"/>\n      <xsd:enumeration value=\"legacyNormal2\"/>\n      <xsd:enumeration value=\"legacyNormal3\"/>\n      <xsd:enumeration value=\"legacyNormal4\"/>\n      <xsd:enumeration value=\"legacyHarsh1\"/>\n      <xsd:enumeration value=\"legacyHarsh2\"/>\n      <xsd:enumeration value=\"legacyHarsh3\"/>\n      <xsd:enumeration value=\"legacyHarsh4\"/>\n      <xsd:enumeration value=\"threePt\"/>\n      <xsd:enumeration value=\"balanced\"/>\n      <xsd:enumeration value=\"soft\"/>\n      <xsd:enumeration value=\"harsh\"/>\n      <xsd:enumeration value=\"flood\"/>\n      <xsd:enumeration value=\"contrasting\"/>\n      <xsd:enumeration value=\"morning\"/>\n      <xsd:enumeration value=\"sunrise\"/>\n      <xsd:enumeration value=\"sunset\"/>\n      <xsd:enumeration value=\"chilly\"/>\n      <xsd:enumeration value=\"freezing\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"twoPt\"/>\n      <xsd:enumeration value=\"glow\"/>\n      <xsd:enumeration value=\"brightRoom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LightRig\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scene3D\">\n    <xsd:sequence>\n      <xsd:element name=\"camera\" type=\"CT_Camera\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backdrop\" type=\"CT_Backdrop\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Backdrop\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_Point3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"norm\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"up\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BevelPresetType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relaxedInset\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"slope\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"softRound\"/>\n      <xsd:enumeration value=\"convex\"/>\n      <xsd:enumeration value=\"coolSlant\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"riblet\"/>\n      <xsd:enumeration value=\"hardEdge\"/>\n      <xsd:enumeration value=\"artDeco\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Bevel\">\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\" default=\"circle\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetMaterialType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyMatte\"/>\n      <xsd:enumeration value=\"legacyPlastic\"/>\n      <xsd:enumeration value=\"legacyMetal\"/>\n      <xsd:enumeration value=\"legacyWireframe\"/>\n      <xsd:enumeration value=\"matte\"/>\n      <xsd:enumeration value=\"plastic\"/>\n      <xsd:enumeration value=\"metal\"/>\n      <xsd:enumeration value=\"warmMatte\"/>\n      <xsd:enumeration value=\"translucentPowder\"/>\n      <xsd:enumeration value=\"powder\"/>\n      <xsd:enumeration value=\"dkEdge\"/>\n      <xsd:enumeration value=\"softEdge\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"softmetal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"extrusionH\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"contourW\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"\n      default=\"warmMatte\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FlatText\">\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Text3D\">\n    <xsd:choice>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"flatTx\" type=\"CT_FlatText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AlphaBiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaCeilingEffect\"/>\n  <xsd:complexType name=\"CT_AlphaFloorEffect\"/>\n  <xsd:complexType name=\"CT_AlphaInverseEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateFixedEffect\">\n    <xsd:attribute name=\"amt\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaOutsetEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaReplaceEffect\">\n    <xsd:attribute name=\"a\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlurEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"grow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorChangeEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"clrFrom\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrTo\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useA\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorReplaceEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DuotoneEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GrayscaleEffect\"/>\n  <xsd:complexType name=\"CT_HSLEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InnerShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LuminanceEffect\">\n    <xsd:attribute name=\"bright\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"contrast\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OuterShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetShadowVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shdw1\"/>\n      <xsd:enumeration value=\"shdw2\"/>\n      <xsd:enumeration value=\"shdw3\"/>\n      <xsd:enumeration value=\"shdw4\"/>\n      <xsd:enumeration value=\"shdw5\"/>\n      <xsd:enumeration value=\"shdw6\"/>\n      <xsd:enumeration value=\"shdw7\"/>\n      <xsd:enumeration value=\"shdw8\"/>\n      <xsd:enumeration value=\"shdw9\"/>\n      <xsd:enumeration value=\"shdw10\"/>\n      <xsd:enumeration value=\"shdw11\"/>\n      <xsd:enumeration value=\"shdw12\"/>\n      <xsd:enumeration value=\"shdw13\"/>\n      <xsd:enumeration value=\"shdw14\"/>\n      <xsd:enumeration value=\"shdw15\"/>\n      <xsd:enumeration value=\"shdw16\"/>\n      <xsd:enumeration value=\"shdw17\"/>\n      <xsd:enumeration value=\"shdw18\"/>\n      <xsd:enumeration value=\"shdw19\"/>\n      <xsd:enumeration value=\"shdw20\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetShadowVal\" use=\"required\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReflectionEffect\">\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"stA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"stPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fadeDir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"5400000\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeOffsetEffect\">\n    <xsd:attribute name=\"tx\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SoftEdgesEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TintEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"amt\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransformEffect\">\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NoFillProperties\"/>\n  <xsd:complexType name=\"CT_SolidColorFillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinearShadeProperties\">\n    <xsd:attribute name=\"ang\" type=\"ST_PositiveFixedAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"scaled\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PathShadeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shape\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PathShadeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShadeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"path\" type=\"CT_PathShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TileFlipMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n      <xsd:enumeration value=\"xy\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pos\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tileRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TileInfoProperties\">\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StretchInfoProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FillModeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"tile\" type=\"CT_TileInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stretch\" type=\"CT_StretchInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_BlipCompression\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"hqprint\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Blip\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Blob\"/>\n    <xsd:attribute name=\"cstate\" type=\"ST_BlipCompression\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlipFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srcRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillModeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetPatternVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"ltHorz\"/>\n      <xsd:enumeration value=\"ltVert\"/>\n      <xsd:enumeration value=\"dkHorz\"/>\n      <xsd:enumeration value=\"dkVert\"/>\n      <xsd:enumeration value=\"narHorz\"/>\n      <xsd:enumeration value=\"narVert\"/>\n      <xsd:enumeration value=\"dashHorz\"/>\n      <xsd:enumeration value=\"dashVert\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"dnDiag\"/>\n      <xsd:enumeration value=\"upDiag\"/>\n      <xsd:enumeration value=\"ltDnDiag\"/>\n      <xsd:enumeration value=\"ltUpDiag\"/>\n      <xsd:enumeration value=\"dkDnDiag\"/>\n      <xsd:enumeration value=\"dkUpDiag\"/>\n      <xsd:enumeration value=\"wdDnDiag\"/>\n      <xsd:enumeration value=\"wdUpDiag\"/>\n      <xsd:enumeration value=\"dashDnDiag\"/>\n      <xsd:enumeration value=\"dashUpDiag\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"smCheck\"/>\n      <xsd:enumeration value=\"lgCheck\"/>\n      <xsd:enumeration value=\"smGrid\"/>\n      <xsd:enumeration value=\"lgGrid\"/>\n      <xsd:enumeration value=\"dotGrid\"/>\n      <xsd:enumeration value=\"smConfetti\"/>\n      <xsd:enumeration value=\"lgConfetti\"/>\n      <xsd:enumeration value=\"horzBrick\"/>\n      <xsd:enumeration value=\"diagBrick\"/>\n      <xsd:enumeration value=\"solidDmnd\"/>\n      <xsd:enumeration value=\"openDmnd\"/>\n      <xsd:enumeration value=\"dotDmnd\"/>\n      <xsd:enumeration value=\"plaid\"/>\n      <xsd:enumeration value=\"sphere\"/>\n      <xsd:enumeration value=\"weave\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"shingle\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"trellis\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PatternFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetPatternVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupFillProperties\"/>\n  <xsd:group name=\"EG_FillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpFill\" type=\"CT_GroupFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlendMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"over\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"lighten\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FillOverlayEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectReference\">\n    <xsd:attribute name=\"ref\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Effect\">\n    <xsd:choice>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effect\" type=\"CT_EffectReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOutset\" type=\"CT_AlphaOutsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blend\" type=\"CT_BlendEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_FillEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"relOff\" type=\"CT_RelativeOffsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_TransformEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_EffectContainerType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sib\"/>\n      <xsd:enumeration value=\"tree\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EffectContainer\">\n    <xsd:group ref=\"EG_Effect\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"type\" type=\"ST_EffectContainerType\" use=\"optional\" default=\"sib\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlendEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectList\">\n    <xsd:sequence>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_EffectProperties\">\n    <xsd:choice>\n      <xsd:element name=\"effectLst\" type=\"CT_EffectList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectDag\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_EffectProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"blip\" type=\"CT_Blip\"/>\n  <xsd:simpleType name=\"ST_ShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineInv\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"rtTriangle\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"parallelogram\"/>\n      <xsd:enumeration value=\"trapezoid\"/>\n      <xsd:enumeration value=\"nonIsoscelesTrapezoid\"/>\n      <xsd:enumeration value=\"pentagon\"/>\n      <xsd:enumeration value=\"hexagon\"/>\n      <xsd:enumeration value=\"heptagon\"/>\n      <xsd:enumeration value=\"octagon\"/>\n      <xsd:enumeration value=\"decagon\"/>\n      <xsd:enumeration value=\"dodecagon\"/>\n      <xsd:enumeration value=\"star4\"/>\n      <xsd:enumeration value=\"star5\"/>\n      <xsd:enumeration value=\"star6\"/>\n      <xsd:enumeration value=\"star7\"/>\n      <xsd:enumeration value=\"star8\"/>\n      <xsd:enumeration value=\"star10\"/>\n      <xsd:enumeration value=\"star12\"/>\n      <xsd:enumeration value=\"star16\"/>\n      <xsd:enumeration value=\"star24\"/>\n      <xsd:enumeration value=\"star32\"/>\n      <xsd:enumeration value=\"roundRect\"/>\n      <xsd:enumeration value=\"round1Rect\"/>\n      <xsd:enumeration value=\"round2SameRect\"/>\n      <xsd:enumeration value=\"round2DiagRect\"/>\n      <xsd:enumeration value=\"snipRoundRect\"/>\n      <xsd:enumeration value=\"snip1Rect\"/>\n      <xsd:enumeration value=\"snip2SameRect\"/>\n      <xsd:enumeration value=\"snip2DiagRect\"/>\n      <xsd:enumeration value=\"plaque\"/>\n      <xsd:enumeration value=\"ellipse\"/>\n      <xsd:enumeration value=\"teardrop\"/>\n      <xsd:enumeration value=\"homePlate\"/>\n      <xsd:enumeration value=\"chevron\"/>\n      <xsd:enumeration value=\"pieWedge\"/>\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"blockArc\"/>\n      <xsd:enumeration value=\"donut\"/>\n      <xsd:enumeration value=\"noSmoking\"/>\n      <xsd:enumeration value=\"rightArrow\"/>\n      <xsd:enumeration value=\"leftArrow\"/>\n      <xsd:enumeration value=\"upArrow\"/>\n      <xsd:enumeration value=\"downArrow\"/>\n      <xsd:enumeration value=\"stripedRightArrow\"/>\n      <xsd:enumeration value=\"notchedRightArrow\"/>\n      <xsd:enumeration value=\"bentUpArrow\"/>\n      <xsd:enumeration value=\"leftRightArrow\"/>\n      <xsd:enumeration value=\"upDownArrow\"/>\n      <xsd:enumeration value=\"leftUpArrow\"/>\n      <xsd:enumeration value=\"leftRightUpArrow\"/>\n      <xsd:enumeration value=\"quadArrow\"/>\n      <xsd:enumeration value=\"leftArrowCallout\"/>\n      <xsd:enumeration value=\"rightArrowCallout\"/>\n      <xsd:enumeration value=\"upArrowCallout\"/>\n      <xsd:enumeration value=\"downArrowCallout\"/>\n      <xsd:enumeration value=\"leftRightArrowCallout\"/>\n      <xsd:enumeration value=\"upDownArrowCallout\"/>\n      <xsd:enumeration value=\"quadArrowCallout\"/>\n      <xsd:enumeration value=\"bentArrow\"/>\n      <xsd:enumeration value=\"uturnArrow\"/>\n      <xsd:enumeration value=\"circularArrow\"/>\n      <xsd:enumeration value=\"leftCircularArrow\"/>\n      <xsd:enumeration value=\"leftRightCircularArrow\"/>\n      <xsd:enumeration value=\"curvedRightArrow\"/>\n      <xsd:enumeration value=\"curvedLeftArrow\"/>\n      <xsd:enumeration value=\"curvedUpArrow\"/>\n      <xsd:enumeration value=\"curvedDownArrow\"/>\n      <xsd:enumeration value=\"swooshArrow\"/>\n      <xsd:enumeration value=\"cube\"/>\n      <xsd:enumeration value=\"can\"/>\n      <xsd:enumeration value=\"lightningBolt\"/>\n      <xsd:enumeration value=\"heart\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"moon\"/>\n      <xsd:enumeration value=\"smileyFace\"/>\n      <xsd:enumeration value=\"irregularSeal1\"/>\n      <xsd:enumeration value=\"irregularSeal2\"/>\n      <xsd:enumeration value=\"foldedCorner\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"halfFrame\"/>\n      <xsd:enumeration value=\"corner\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"chord\"/>\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"leftBracket\"/>\n      <xsd:enumeration value=\"rightBracket\"/>\n      <xsd:enumeration value=\"leftBrace\"/>\n      <xsd:enumeration value=\"rightBrace\"/>\n      <xsd:enumeration value=\"bracketPair\"/>\n      <xsd:enumeration value=\"bracePair\"/>\n      <xsd:enumeration value=\"straightConnector1\"/>\n      <xsd:enumeration value=\"bentConnector2\"/>\n      <xsd:enumeration value=\"bentConnector3\"/>\n      <xsd:enumeration value=\"bentConnector4\"/>\n      <xsd:enumeration value=\"bentConnector5\"/>\n      <xsd:enumeration value=\"curvedConnector2\"/>\n      <xsd:enumeration value=\"curvedConnector3\"/>\n      <xsd:enumeration value=\"curvedConnector4\"/>\n      <xsd:enumeration value=\"curvedConnector5\"/>\n      <xsd:enumeration value=\"callout1\"/>\n      <xsd:enumeration value=\"callout2\"/>\n      <xsd:enumeration value=\"callout3\"/>\n      <xsd:enumeration value=\"accentCallout1\"/>\n      <xsd:enumeration value=\"accentCallout2\"/>\n      <xsd:enumeration value=\"accentCallout3\"/>\n      <xsd:enumeration value=\"borderCallout1\"/>\n      <xsd:enumeration value=\"borderCallout2\"/>\n      <xsd:enumeration value=\"borderCallout3\"/>\n      <xsd:enumeration value=\"accentBorderCallout1\"/>\n      <xsd:enumeration value=\"accentBorderCallout2\"/>\n      <xsd:enumeration value=\"accentBorderCallout3\"/>\n      <xsd:enumeration value=\"wedgeRectCallout\"/>\n      <xsd:enumeration value=\"wedgeRoundRectCallout\"/>\n      <xsd:enumeration value=\"wedgeEllipseCallout\"/>\n      <xsd:enumeration value=\"cloudCallout\"/>\n      <xsd:enumeration value=\"cloud\"/>\n      <xsd:enumeration value=\"ribbon\"/>\n      <xsd:enumeration value=\"ribbon2\"/>\n      <xsd:enumeration value=\"ellipseRibbon\"/>\n      <xsd:enumeration value=\"ellipseRibbon2\"/>\n      <xsd:enumeration value=\"leftRightRibbon\"/>\n      <xsd:enumeration value=\"verticalScroll\"/>\n      <xsd:enumeration value=\"horizontalScroll\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"flowChartProcess\"/>\n      <xsd:enumeration value=\"flowChartDecision\"/>\n      <xsd:enumeration value=\"flowChartInputOutput\"/>\n      <xsd:enumeration value=\"flowChartPredefinedProcess\"/>\n      <xsd:enumeration value=\"flowChartInternalStorage\"/>\n      <xsd:enumeration value=\"flowChartDocument\"/>\n      <xsd:enumeration value=\"flowChartMultidocument\"/>\n      <xsd:enumeration value=\"flowChartTerminator\"/>\n      <xsd:enumeration value=\"flowChartPreparation\"/>\n      <xsd:enumeration value=\"flowChartManualInput\"/>\n      <xsd:enumeration value=\"flowChartManualOperation\"/>\n      <xsd:enumeration value=\"flowChartConnector\"/>\n      <xsd:enumeration value=\"flowChartPunchedCard\"/>\n      <xsd:enumeration value=\"flowChartPunchedTape\"/>\n      <xsd:enumeration value=\"flowChartSummingJunction\"/>\n      <xsd:enumeration value=\"flowChartOr\"/>\n      <xsd:enumeration value=\"flowChartCollate\"/>\n      <xsd:enumeration value=\"flowChartSort\"/>\n      <xsd:enumeration value=\"flowChartExtract\"/>\n      <xsd:enumeration value=\"flowChartMerge\"/>\n      <xsd:enumeration value=\"flowChartOfflineStorage\"/>\n      <xsd:enumeration value=\"flowChartOnlineStorage\"/>\n      <xsd:enumeration value=\"flowChartMagneticTape\"/>\n      <xsd:enumeration value=\"flowChartMagneticDisk\"/>\n      <xsd:enumeration value=\"flowChartMagneticDrum\"/>\n      <xsd:enumeration value=\"flowChartDisplay\"/>\n      <xsd:enumeration value=\"flowChartDelay\"/>\n      <xsd:enumeration value=\"flowChartAlternateProcess\"/>\n      <xsd:enumeration value=\"flowChartOffpageConnector\"/>\n      <xsd:enumeration value=\"actionButtonBlank\"/>\n      <xsd:enumeration value=\"actionButtonHome\"/>\n      <xsd:enumeration value=\"actionButtonHelp\"/>\n      <xsd:enumeration value=\"actionButtonInformation\"/>\n      <xsd:enumeration value=\"actionButtonForwardNext\"/>\n      <xsd:enumeration value=\"actionButtonBackPrevious\"/>\n      <xsd:enumeration value=\"actionButtonEnd\"/>\n      <xsd:enumeration value=\"actionButtonBeginning\"/>\n      <xsd:enumeration value=\"actionButtonReturn\"/>\n      <xsd:enumeration value=\"actionButtonDocument\"/>\n      <xsd:enumeration value=\"actionButtonSound\"/>\n      <xsd:enumeration value=\"actionButtonMovie\"/>\n      <xsd:enumeration value=\"gear6\"/>\n      <xsd:enumeration value=\"gear9\"/>\n      <xsd:enumeration value=\"funnel\"/>\n      <xsd:enumeration value=\"mathPlus\"/>\n      <xsd:enumeration value=\"mathMinus\"/>\n      <xsd:enumeration value=\"mathMultiply\"/>\n      <xsd:enumeration value=\"mathDivide\"/>\n      <xsd:enumeration value=\"mathEqual\"/>\n      <xsd:enumeration value=\"mathNotEqual\"/>\n      <xsd:enumeration value=\"cornerTabs\"/>\n      <xsd:enumeration value=\"squareTabs\"/>\n      <xsd:enumeration value=\"plaqueTabs\"/>\n      <xsd:enumeration value=\"chartX\"/>\n      <xsd:enumeration value=\"chartStar\"/>\n      <xsd:enumeration value=\"chartPlus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"textNoShape\"/>\n      <xsd:enumeration value=\"textPlain\"/>\n      <xsd:enumeration value=\"textStop\"/>\n      <xsd:enumeration value=\"textTriangle\"/>\n      <xsd:enumeration value=\"textTriangleInverted\"/>\n      <xsd:enumeration value=\"textChevron\"/>\n      <xsd:enumeration value=\"textChevronInverted\"/>\n      <xsd:enumeration value=\"textRingInside\"/>\n      <xsd:enumeration value=\"textRingOutside\"/>\n      <xsd:enumeration value=\"textArchUp\"/>\n      <xsd:enumeration value=\"textArchDown\"/>\n      <xsd:enumeration value=\"textCircle\"/>\n      <xsd:enumeration value=\"textButton\"/>\n      <xsd:enumeration value=\"textArchUpPour\"/>\n      <xsd:enumeration value=\"textArchDownPour\"/>\n      <xsd:enumeration value=\"textCirclePour\"/>\n      <xsd:enumeration value=\"textButtonPour\"/>\n      <xsd:enumeration value=\"textCurveUp\"/>\n      <xsd:enumeration value=\"textCurveDown\"/>\n      <xsd:enumeration value=\"textCanUp\"/>\n      <xsd:enumeration value=\"textCanDown\"/>\n      <xsd:enumeration value=\"textWave1\"/>\n      <xsd:enumeration value=\"textWave2\"/>\n      <xsd:enumeration value=\"textDoubleWave1\"/>\n      <xsd:enumeration value=\"textWave4\"/>\n      <xsd:enumeration value=\"textInflate\"/>\n      <xsd:enumeration value=\"textDeflate\"/>\n      <xsd:enumeration value=\"textInflateBottom\"/>\n      <xsd:enumeration value=\"textDeflateBottom\"/>\n      <xsd:enumeration value=\"textInflateTop\"/>\n      <xsd:enumeration value=\"textDeflateTop\"/>\n      <xsd:enumeration value=\"textDeflateInflate\"/>\n      <xsd:enumeration value=\"textDeflateInflateDeflate\"/>\n      <xsd:enumeration value=\"textFadeRight\"/>\n      <xsd:enumeration value=\"textFadeLeft\"/>\n      <xsd:enumeration value=\"textFadeUp\"/>\n      <xsd:enumeration value=\"textFadeDown\"/>\n      <xsd:enumeration value=\"textSlantUp\"/>\n      <xsd:enumeration value=\"textSlantDown\"/>\n      <xsd:enumeration value=\"textCascadeUp\"/>\n      <xsd:enumeration value=\"textCascadeDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideName\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideFormula\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GeomGuide\">\n    <xsd:attribute name=\"name\" type=\"ST_GeomGuideName\" use=\"required\"/>\n    <xsd:attribute name=\"fmla\" type=\"ST_GeomGuideFormula\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomGuideList\">\n    <xsd:sequence>\n      <xsd:element name=\"gd\" type=\"CT_GeomGuide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AdjCoordinate\">\n    <xsd:union memberTypes=\"ST_Coordinate ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AdjAngle\">\n    <xsd:union memberTypes=\"ST_Angle ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AdjPoint2D\">\n    <xsd:attribute name=\"x\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomRect\">\n    <xsd:attribute name=\"l\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XYAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefX\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefY\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolarAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefR\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefAng\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"maxAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSite\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ang\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjustHandleList\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"ahXY\" type=\"CT_XYAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahPolar\" type=\"CT_PolarAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSiteList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_ConnectionSite\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DMoveTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DLineTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DArcTo\">\n    <xsd:attribute name=\"wR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"hR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"stAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n    <xsd:attribute name=\"swAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DQuadBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DCubicBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"3\" maxOccurs=\"3\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DClose\"/>\n  <xsd:simpleType name=\"ST_PathFillMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"lighten\"/>\n      <xsd:enumeration value=\"lightenLess\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"darkenLess\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Path2D\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"close\" type=\"CT_Path2DClose\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_Path2DMoveTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTo\" type=\"CT_Path2DLineTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"arcTo\" type=\"CT_Path2DArcTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"quadBezTo\" type=\"CT_Path2DQuadBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cubicBezTo\" type=\"CT_Path2DCubicBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_PathFillMode\" use=\"optional\" default=\"norm\"/>\n    <xsd:attribute name=\"stroke\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"extrusionOk\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DList\">\n    <xsd:sequence>\n      <xsd:element name=\"path\" type=\"CT_Path2D\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_ShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_TextShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gdLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahLst\" type=\"CT_AdjustHandleList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_ConnectionSiteList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rect\" type=\"CT_GeomRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pathLst\" type=\"CT_Path2DList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Geometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstGeom\" type=\"CT_PresetGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextGeometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineEndType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"stealth\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"arrow\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndWidth\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndLength\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineEndProperties\">\n    <xsd:attribute name=\"type\" type=\"ST_LineEndType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"w\" type=\"ST_LineEndWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"len\" type=\"ST_LineEndLength\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineFillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineJoinBevel\"/>\n  <xsd:complexType name=\"CT_LineJoinRound\"/>\n  <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n    <xsd:attribute name=\"lim\" type=\"ST_PositivePercentage\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineJoinProperties\">\n    <xsd:choice>\n      <xsd:element name=\"round\" type=\"CT_LineJoinRound\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevel\" type=\"CT_LineJoinBevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PresetLineDashVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"lgDash\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"lgDashDot\"/>\n      <xsd:enumeration value=\"lgDashDotDot\"/>\n      <xsd:enumeration value=\"sysDash\"/>\n      <xsd:enumeration value=\"sysDot\"/>\n      <xsd:enumeration value=\"sysDashDot\"/>\n      <xsd:enumeration value=\"sysDashDotDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetLineDashProperties\">\n    <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStop\">\n    <xsd:attribute name=\"d\" type=\"ST_PositivePercentage\" use=\"required\"/>\n    <xsd:attribute name=\"sp\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"ds\" type=\"CT_DashStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineDashProperties\">\n    <xsd:choice>\n      <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDash\" type=\"CT_DashStopList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineCap\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rnd\"/>\n      <xsd:enumeration value=\"sq\"/>\n      <xsd:enumeration value=\"flat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineWidth\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"20116800\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PenAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CompoundLine\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"tri\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineFillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tailEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_LineWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_LineCap\" use=\"optional\"/>\n    <xsd:attribute name=\"cmpd\" type=\"ST_CompoundLine\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_PenAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShapeID\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Geometry\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_GroupTransform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrixReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_StyleMatrixColumnIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_FontCollectionIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefaultShapeDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectStyleDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"spDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_ColorMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bg1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"hlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"folHlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMappingOverride\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"masterClrMapping\" type=\"CT_EmptyElement\"/>\n        <xsd:element name=\"overrideClrMapping\" type=\"CT_ColorMapping\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeAndMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeList\">\n    <xsd:sequence>\n      <xsd:element name=\"extraClrScheme\" type=\"CT_ColorSchemeAndMapping\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"objectDefaults\" type=\"CT_ObjectStyleDefaults\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extraClrSchemeLst\" type=\"CT_ColorSchemeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custClrLst\" type=\"CT_CustomColorList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStylesOverride\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipboardStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"theme\" type=\"CT_OfficeStyleSheet\"/>\n  <xsd:element name=\"themeOverride\" type=\"CT_BaseStylesOverride\"/>\n  <xsd:element name=\"themeManager\" type=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_TableCellProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnL\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnR\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnT\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnB\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTlToBr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnBlToTr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marT\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"marB\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\" default=\"t\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\" default=\"clip\"\n    />\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"xsd:string\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCol\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableGrid\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TableCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCell\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TableCellProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rowSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"gridSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"hMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableRow\">\n    <xsd:sequence>\n      <xsd:element name=\"tc\" type=\"CT_TableCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"h\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\"/>\n        <xsd:element name=\"tableStyleId\" type=\"s:ST_Guid\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPr\" type=\"CT_TableProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TableGrid\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr\" type=\"CT_TableRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tbl\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Cell3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevel\" type=\"CT_Bevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\" default=\"plastic\"\n    />\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableFillStyle\">\n    <xsd:choice>\n      <xsd:element name=\"fill\" type=\"CT_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ThemeableLineStyle\">\n    <xsd:choice>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableEffectStyle\">\n    <xsd:choice>\n      <xsd:element name=\"effect\" type=\"CT_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ThemeableFontStyles\">\n    <xsd:choice>\n      <xsd:element name=\"font\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_OnOffStyleType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"def\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleTextStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFontStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"b\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n    <xsd:attribute name=\"i\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCellBorderStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"left\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideH\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideV\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableBackgroundStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableEffectStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleCellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcBdr\" type=\"CT_TableCellBorderStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePartStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcTxStyle\" type=\"CT_TableStyleTextStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcStyle\" type=\"CT_TableStyleCellStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tblBg\" type=\"CT_TableBackgroundStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wholeTbl\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"seCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"swCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"neCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nwCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"styleName\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"def\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"tblStyleLst\" type=\"CT_TableStyleList\"/>\n  <xsd:complexType name=\"CT_TextParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"endParaRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAnchoringType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"dist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVertOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"ellipsis\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextHorzOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVerticalType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"vert270\"/>\n      <xsd:enumeration value=\"wordArtVert\"/>\n      <xsd:enumeration value=\"eaVert\"/>\n      <xsd:enumeration value=\"mongolianVert\"/>\n      <xsd:enumeration value=\"wordArtVertRtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextWrappingType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"square\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextColumnCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"16\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextListStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"defPPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl1pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl2pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl3pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl4pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl5pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl6pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl7pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl8pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl9pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextFontScalePercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextFontScalePercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontScalePercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"1000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextNormalAutofit\">\n    <xsd:attribute name=\"fontScale\" type=\"ST_TextFontScalePercentOrPercentString\" use=\"optional\"\n      default=\"100%\"/>\n    <xsd:attribute name=\"lnSpcReduction\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"optional\"\n      default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextShapeAutofit\"/>\n  <xsd:complexType name=\"CT_TextNoAutofit\"/>\n  <xsd:group name=\"EG_TextAutofit\">\n    <xsd:choice>\n      <xsd:element name=\"noAutofit\" type=\"CT_TextNoAutofit\"/>\n      <xsd:element name=\"normAutofit\" type=\"CT_TextNormalAutofit\"/>\n      <xsd:element name=\"spAutoFit\" type=\"CT_TextShapeAutofit\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBodyProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextAutofit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"spcFirstLastPara\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"vertOverflow\" type=\"ST_TextVertOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_TextWrappingType\" use=\"optional\"/>\n    <xsd:attribute name=\"lIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"tIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"bIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"numCol\" type=\"ST_TextColumnCount\" use=\"optional\"/>\n    <xsd:attribute name=\"spcCol\" type=\"ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtlCol\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fromWordArt\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"forceAA\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"upright\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatLnSpc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBody\">\n    <xsd:sequence>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"p\" type=\"CT_TextParagraph\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextBulletStartAtNum\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"32767\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAutonumberScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"alphaLcParenBoth\"/>\n      <xsd:enumeration value=\"alphaUcParenBoth\"/>\n      <xsd:enumeration value=\"alphaLcParenR\"/>\n      <xsd:enumeration value=\"alphaUcParenR\"/>\n      <xsd:enumeration value=\"alphaLcPeriod\"/>\n      <xsd:enumeration value=\"alphaUcPeriod\"/>\n      <xsd:enumeration value=\"arabicParenBoth\"/>\n      <xsd:enumeration value=\"arabicParenR\"/>\n      <xsd:enumeration value=\"arabicPeriod\"/>\n      <xsd:enumeration value=\"arabicPlain\"/>\n      <xsd:enumeration value=\"romanLcParenBoth\"/>\n      <xsd:enumeration value=\"romanUcParenBoth\"/>\n      <xsd:enumeration value=\"romanLcParenR\"/>\n      <xsd:enumeration value=\"romanUcParenR\"/>\n      <xsd:enumeration value=\"romanLcPeriod\"/>\n      <xsd:enumeration value=\"romanUcPeriod\"/>\n      <xsd:enumeration value=\"circleNumDbPlain\"/>\n      <xsd:enumeration value=\"circleNumWdBlackPlain\"/>\n      <xsd:enumeration value=\"circleNumWdWhitePlain\"/>\n      <xsd:enumeration value=\"arabicDbPeriod\"/>\n      <xsd:enumeration value=\"arabicDbPlain\"/>\n      <xsd:enumeration value=\"ea1ChsPeriod\"/>\n      <xsd:enumeration value=\"ea1ChsPlain\"/>\n      <xsd:enumeration value=\"ea1ChtPeriod\"/>\n      <xsd:enumeration value=\"ea1ChtPlain\"/>\n      <xsd:enumeration value=\"ea1JpnChsDbPeriod\"/>\n      <xsd:enumeration value=\"ea1JpnKorPlain\"/>\n      <xsd:enumeration value=\"ea1JpnKorPeriod\"/>\n      <xsd:enumeration value=\"arabic1Minus\"/>\n      <xsd:enumeration value=\"arabic2Minus\"/>\n      <xsd:enumeration value=\"hebrew2Minus\"/>\n      <xsd:enumeration value=\"thaiAlphaPeriod\"/>\n      <xsd:enumeration value=\"thaiAlphaParenR\"/>\n      <xsd:enumeration value=\"thaiAlphaParenBoth\"/>\n      <xsd:enumeration value=\"thaiNumPeriod\"/>\n      <xsd:enumeration value=\"thaiNumParenR\"/>\n      <xsd:enumeration value=\"thaiNumParenBoth\"/>\n      <xsd:enumeration value=\"hindiAlphaPeriod\"/>\n      <xsd:enumeration value=\"hindiNumPeriod\"/>\n      <xsd:enumeration value=\"hindiNumParenR\"/>\n      <xsd:enumeration value=\"hindiAlpha1Period\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletColorFollowText\"/>\n  <xsd:group name=\"EG_TextBulletColor\">\n    <xsd:choice>\n      <xsd:element name=\"buClrTx\" type=\"CT_TextBulletColorFollowText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"buClr\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextBulletSize\">\n    <xsd:union memberTypes=\"ST_TextBulletSizePercent ST_TextBulletSizeDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*((2[5-9])|([3-9][0-9])|([1-3][0-9][0-9])|400)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizeDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"25000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletSizeFollowText\"/>\n  <xsd:complexType name=\"CT_TextBulletSizePercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextBulletSizePercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBulletSizePoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextFontSize\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextBulletSize\">\n    <xsd:choice>\n      <xsd:element name=\"buSzTx\" type=\"CT_TextBulletSizeFollowText\"/>\n      <xsd:element name=\"buSzPct\" type=\"CT_TextBulletSizePercent\"/>\n      <xsd:element name=\"buSzPts\" type=\"CT_TextBulletSizePoint\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBulletTypefaceFollowText\"/>\n  <xsd:group name=\"EG_TextBulletTypeface\">\n    <xsd:choice>\n      <xsd:element name=\"buFontTx\" type=\"CT_TextBulletTypefaceFollowText\"/>\n      <xsd:element name=\"buFont\" type=\"CT_TextFont\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextAutonumberBullet\">\n    <xsd:attribute name=\"type\" type=\"ST_TextAutonumberScheme\" use=\"required\"/>\n    <xsd:attribute name=\"startAt\" type=\"ST_TextBulletStartAtNum\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextCharBullet\">\n    <xsd:attribute name=\"char\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBlipBullet\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextNoBullet\"/>\n  <xsd:group name=\"EG_TextBullet\">\n    <xsd:choice>\n      <xsd:element name=\"buNone\" type=\"CT_TextNoBullet\"/>\n      <xsd:element name=\"buAutoNum\" type=\"CT_TextAutonumberBullet\"/>\n      <xsd:element name=\"buChar\" type=\"CT_TextCharBullet\"/>\n      <xsd:element name=\"buBlip\" type=\"CT_TextBlipBullet\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextPoint\">\n    <xsd:union memberTypes=\"ST_TextPointUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextPointUnqualified\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-400000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextNonNegativePoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontSize\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"100\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTypeface\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PitchFamily\">\n   <xsd:restriction base=\"xsd:byte\">\n     <xsd:enumeration value=\"00\"/>\n     <xsd:enumeration value=\"01\"/>\n     <xsd:enumeration value=\"02\"/>\n     <xsd:enumeration value=\"16\"/>\n     <xsd:enumeration value=\"17\"/>\n     <xsd:enumeration value=\"18\"/>\n     <xsd:enumeration value=\"32\"/>\n     <xsd:enumeration value=\"33\"/>\n     <xsd:enumeration value=\"34\"/>\n     <xsd:enumeration value=\"48\"/>\n     <xsd:enumeration value=\"49\"/>\n     <xsd:enumeration value=\"50\"/>\n     <xsd:enumeration value=\"64\"/>\n     <xsd:enumeration value=\"65\"/>\n     <xsd:enumeration value=\"66\"/>\n     <xsd:enumeration value=\"80\"/>\n     <xsd:enumeration value=\"81\"/>\n     <xsd:enumeration value=\"82\"/>\n   </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_TextFont\">\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n    <xsd:attribute name=\"panose\" type=\"s:ST_Panose\" use=\"optional\"/>\n    <xsd:attribute name=\"pitchFamily\" type=\"ST_PitchFamily\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"charset\" type=\"xsd:byte\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextUnderlineType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDashHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dotDotDashHeavy\"/>\n      <xsd:enumeration value=\"wavy\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDbl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextUnderlineLineFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillGroupWrapper\">\n    <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextUnderlineLine\">\n    <xsd:choice>\n      <xsd:element name=\"uLnTx\" type=\"CT_TextUnderlineLineFollowText\"/>\n      <xsd:element name=\"uLn\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextUnderlineFill\">\n    <xsd:choice>\n      <xsd:element name=\"uFillTx\" type=\"CT_TextUnderlineFillFollowText\"/>\n      <xsd:element name=\"uFill\" type=\"CT_TextUnderlineFillGroupWrapper\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextStrikeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"noStrike\"/>\n      <xsd:enumeration value=\"sngStrike\"/>\n      <xsd:enumeration value=\"dblStrike\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextCapsType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"small\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextCharacterProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineLine\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sym\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkMouseOver\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rtl\" type=\"CT_Boolean\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"kumimoji\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"altLang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_TextFontSize\" use=\"optional\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"u\" type=\"ST_TextUnderlineType\" use=\"optional\"/>\n    <xsd:attribute name=\"strike\" type=\"ST_TextStrikeType\" use=\"optional\"/>\n    <xsd:attribute name=\"kern\" type=\"ST_TextNonNegativePoint\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_TextCapsType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"spc\" type=\"ST_TextPoint\" use=\"optional\"/>\n    <xsd:attribute name=\"normalizeH\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"baseline\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"noProof\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"dirty\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"err\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"smtClean\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"smtId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bmk\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextSpacingPoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"158400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextSpacingPercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"13200000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextSpacingPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacingPoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPoint\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextMargin\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndent\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"-51206400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTabAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"dec\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextTabStop\">\n    <xsd:attribute name=\"pos\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextTabAlignType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextTabStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TextTabStop\" minOccurs=\"0\" maxOccurs=\"32\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLineBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacing\">\n    <xsd:choice>\n      <xsd:element name=\"spcPct\" type=\"CT_TextSpacingPercent\"/>\n      <xsd:element name=\"spcPts\" type=\"CT_TextSpacingPoint\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"justLow\"/>\n      <xsd:enumeration value=\"dist\"/>\n      <xsd:enumeration value=\"thaiDist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndentLevelType\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"8\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextParagraphProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnSpc\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcBef\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcAft\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletColor\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletTypeface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBullet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tabLst\" type=\"CT_TextTabStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"defRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"lvl\" type=\"ST_TextIndentLevelType\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"ST_TextIndent\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"defTabSz\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"eaLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fontAlgn\" type=\"ST_TextFontAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"latinLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingPunct\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextRun\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_RegularTextRun\"/>\n      <xsd:element name=\"br\" type=\"CT_TextLineBreak\"/>\n      <xsd:element name=\"fld\" type=\"CT_TextField\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RegularTextRun\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"shared-relationshipReference.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>\n  <xsd:element name=\"from\" type=\"CT_Marker\"/>\n  <xsd:element name=\"to\" type=\"CT_Marker\"/>\n  <xsd:complexType name=\"CT_AnchorClientData\">\n    <xsd:attribute name=\"fLocksWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPrintsWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ColID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RowID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"ST_ColID\"/>\n      <xsd:element name=\"colOff\" type=\"a:ST_Coordinate\"/>\n      <xsd:element name=\"row\" type=\"ST_RowID\"/>\n      <xsd:element name=\"rowOff\" type=\"a:ST_Coordinate\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"twoCell\"/>\n      <xsd:enumeration value=\"oneCell\"/>\n      <xsd:enumeration value=\"absolute\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TwoCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"editAs\" type=\"ST_EditAs\" use=\"optional\" default=\"twoCell\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OneCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsoluteAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"twoCellAnchor\" type=\"CT_TwoCellAnchor\"/>\n      <xsd:element name=\"oneCellAnchor\" type=\"CT_OneCellAnchor\"/>\n      <xsd:element name=\"absoluteAnchor\" type=\"CT_AbsoluteAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wsDr\" type=\"CT_Drawing\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:dpct=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"wml.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:complexType name=\"CT_EffectExtent\">\n    <xsd:attribute name=\"l\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapDistance\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Inline\">\n    <xsd:sequence>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapText\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bothSides\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WrapPath\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lineTo\" type=\"a:CT_Point2D\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"edited\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapNone\"/>\n  <xsd:complexType name=\"CT_WrapSquare\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTight\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapThrough\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTopBottom\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_WrapType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"wrapNone\" type=\"CT_WrapNone\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapSquare\" type=\"CT_WrapSquare\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTight\" type=\"CT_WrapTight\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapThrough\" type=\"CT_WrapThrough\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTopAndBottom\" type=\"CT_WrapTopBottom\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PositionOffset\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlignH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"leftMargin\"/>\n      <xsd:enumeration value=\"rightMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosH\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignH\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromH\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlignV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"topMargin\"/>\n      <xsd:enumeration value=\"bottomMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosV\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignV\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromV\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Anchor\">\n    <xsd:sequence>\n      <xsd:element name=\"simplePos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"positionH\" type=\"CT_PosH\"/>\n      <xsd:element name=\"positionV\" type=\"CT_PosV\"/>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_WrapType\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"simplePos\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"relativeHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"behindDoc\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"layoutInCell\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"allowOverlap\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"w:EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextboxInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinkedTextboxInformation\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"seq\" type=\"xsd:unsignedShort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingShape\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"cNvCnPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"txbx\" type=\"CT_TextboxInfo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"linkedTxbx\" type=\"CT_LinkedTextboxInformation\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"bodyPr\" type=\"a:CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"normalEastAsianFlow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvFrPr\" type=\"a:CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPartNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvContentPartPr\" type=\"a:CT_NonVisualContentPartProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPart\">\n    <xsd:sequence>\n      <xsd:element name=\"nvContentPartPr\" type=\"CT_WordprocessingContentPartNonVisual\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingGroup\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_WordprocessingGroup\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingCanvas\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n        <xsd:element ref=\"wgp\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wpc\" type=\"CT_WordprocessingCanvas\"/>\n  <xsd:element name=\"wgp\" type=\"CT_WordprocessingGroup\"/>\n  <xsd:element name=\"wsp\" type=\"CT_WordprocessingShape\"/>\n  <xsd:element name=\"inline\" type=\"CT_Inline\"/>\n  <xsd:element name=\"anchor\" type=\"CT_Anchor\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_TransitionSideDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"d\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionCornerDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"lu\"/>\n      <xsd:enumeration value=\"ru\"/>\n      <xsd:enumeration value=\"ld\"/>\n      <xsd:enumeration value=\"rd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionInOutDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SideDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionSideDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CornerDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionCornerDirectionType\" use=\"optional\" default=\"lu\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionEightDirectionType\">\n    <xsd:union memberTypes=\"ST_TransitionSideDirectionType ST_TransitionCornerDirectionType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EightDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionEightDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OrientationTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InOutTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptionalBlackTransition\">\n    <xsd:attribute name=\"thruBlk\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SplitTransition\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WheelTransition\">\n    <xsd:attribute name=\"spokes\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"4\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionStartSoundAction\">\n    <xsd:sequence>\n      <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"snd\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionSoundAction\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"stSnd\" type=\"CT_TransitionStartSoundAction\"/>\n      <xsd:element name=\"endSnd\" type=\"CT_Empty\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionSpeed\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slow\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"fast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideTransition\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"blinds\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"checker\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"circle\" type=\"CT_Empty\"/>\n        <xsd:element name=\"dissolve\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comb\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"cover\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"cut\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"diamond\" type=\"CT_Empty\"/>\n        <xsd:element name=\"fade\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"newsflash\" type=\"CT_Empty\"/>\n        <xsd:element name=\"plus\" type=\"CT_Empty\"/>\n        <xsd:element name=\"pull\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"push\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"random\" type=\"CT_Empty\"/>\n        <xsd:element name=\"randomBar\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"split\" type=\"CT_SplitTransition\"/>\n        <xsd:element name=\"strips\" type=\"CT_CornerDirectionTransition\"/>\n        <xsd:element name=\"wedge\" type=\"CT_Empty\"/>\n        <xsd:element name=\"wheel\" type=\"CT_WheelTransition\"/>\n        <xsd:element name=\"wipe\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"zoom\" type=\"CT_InOutTransition\"/>\n      </xsd:choice>\n      <xsd:element name=\"sndAc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TransitionSoundAction\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"spd\" type=\"ST_TransitionSpeed\" use=\"optional\" default=\"fast\"/>\n    <xsd:attribute name=\"advClick\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"advTm\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeIndefinite\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"indefinite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTime\">\n    <xsd:union memberTypes=\"xsd:unsignedInt ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeID\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateIntervalTime\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLIterateIntervalPercentage\">\n    <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_IterateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"el\"/>\n      <xsd:enumeration value=\"wd\"/>\n      <xsd:enumeration value=\"lt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateData\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"tmAbs\" type=\"CT_TLIterateIntervalTime\"/>\n      <xsd:element name=\"tmPct\" type=\"CT_TLIterateIntervalPercentage\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_IterateType\" use=\"optional\" default=\"el\"/>\n    <xsd:attribute name=\"backwards\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSubShapeId\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTextTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"charRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"pRg\" type=\"CT_IndexRange\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLChartSubelementType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"gridLegend\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleChartTargetElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TLChartSubelementType\" use=\"required\"/>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLShapeTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"CT_Empty\"/>\n      <xsd:element name=\"subSp\" type=\"CT_TLSubShapeId\"/>\n      <xsd:element name=\"oleChartEl\" type=\"CT_TLOleChartTargetElement\"/>\n      <xsd:element name=\"txEl\" type=\"CT_TLTextTargetElement\"/>\n      <xsd:element name=\"graphicEl\" type=\"a:CT_AnimationElementChoice\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeTargetElement\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"sldTgt\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sndTgt\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"spTgt\" type=\"CT_TLShapeTargetElement\"/>\n      <xsd:element name=\"inkTgt\" type=\"CT_TLSubShapeId\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTriggerTimeNodeID\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTimeNodeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerRuntimeNode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"first\"/>\n      <xsd:enumeration value=\"last\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTriggerRuntimeNode\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTriggerRuntimeNode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerEvent\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"onBegin\"/>\n      <xsd:enumeration value=\"onEnd\"/>\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"onClick\"/>\n      <xsd:enumeration value=\"onDblClick\"/>\n      <xsd:enumeration value=\"onMouseOver\"/>\n      <xsd:enumeration value=\"onMouseOut\"/>\n      <xsd:enumeration value=\"onNext\"/>\n      <xsd:enumeration value=\"onPrev\"/>\n      <xsd:enumeration value=\"onStopAudio\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeCondition\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\"/>\n      <xsd:element name=\"tn\" type=\"CT_TLTriggerTimeNodeID\"/>\n      <xsd:element name=\"rtn\" type=\"CT_TLTriggerRuntimeNode\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"evt\" use=\"optional\" type=\"ST_TLTriggerEvent\"/>\n    <xsd:attribute name=\"delay\" type=\"ST_TLTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeConditionList\">\n    <xsd:sequence>\n      <xsd:element name=\"cond\" type=\"CT_TLTimeCondition\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TimeNodeList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"par\" type=\"CT_TLTimeNodeParallel\"/>\n      <xsd:element name=\"seq\" type=\"CT_TLTimeNodeSequence\"/>\n      <xsd:element name=\"excl\" type=\"CT_TLTimeNodeExclusive\"/>\n      <xsd:element name=\"anim\" type=\"CT_TLAnimateBehavior\"/>\n      <xsd:element name=\"animClr\" type=\"CT_TLAnimateColorBehavior\"/>\n      <xsd:element name=\"animEffect\" type=\"CT_TLAnimateEffectBehavior\"/>\n      <xsd:element name=\"animMotion\" type=\"CT_TLAnimateMotionBehavior\"/>\n      <xsd:element name=\"animRot\" type=\"CT_TLAnimateRotationBehavior\"/>\n      <xsd:element name=\"animScale\" type=\"CT_TLAnimateScaleBehavior\"/>\n      <xsd:element name=\"cmd\" type=\"CT_TLCommandBehavior\"/>\n      <xsd:element name=\"set\" type=\"CT_TLSetBehavior\"/>\n      <xsd:element name=\"audio\" type=\"CT_TLMediaNodeAudio\"/>\n      <xsd:element name=\"video\" type=\"CT_TLMediaNodeVideo\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeNodePresetClassType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"entr\"/>\n      <xsd:enumeration value=\"exit\"/>\n      <xsd:enumeration value=\"emph\"/>\n      <xsd:enumeration value=\"path\"/>\n      <xsd:enumeration value=\"verb\"/>\n      <xsd:enumeration value=\"mediacall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeRestartType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"whenNotActive\"/>\n      <xsd:enumeration value=\"never\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeFillType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"remove\"/>\n      <xsd:enumeration value=\"freeze\"/>\n      <xsd:enumeration value=\"hold\"/>\n      <xsd:enumeration value=\"transition\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeSyncType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"canSlip\"/>\n      <xsd:enumeration value=\"locked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeMasterRelation\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sameClick\"/>\n      <xsd:enumeration value=\"lastClick\"/>\n      <xsd:enumeration value=\"nextClick\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clickEffect\"/>\n      <xsd:enumeration value=\"withEffect\"/>\n      <xsd:enumeration value=\"afterEffect\"/>\n      <xsd:enumeration value=\"mainSeq\"/>\n      <xsd:enumeration value=\"interactiveSeq\"/>\n      <xsd:enumeration value=\"clickPar\"/>\n      <xsd:enumeration value=\"withGroup\"/>\n      <xsd:enumeration value=\"afterGroup\"/>\n      <xsd:enumeration value=\"tmRoot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonTimeNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"stCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endSync\" type=\"CT_TLTimeCondition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iterate\" type=\"CT_TLIterateData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"childTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"subTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_TLTimeNodeID\" use=\"optional\"/>\n    <xsd:attribute name=\"presetID\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presetClass\" type=\"ST_TLTimeNodePresetClassType\" use=\"optional\"/>\n    <xsd:attribute name=\"presetSubtype\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"dur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"repeatCount\" type=\"ST_TLTime\" use=\"optional\" default=\"1000\"/>\n    <xsd:attribute name=\"repeatDur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"spd\" type=\"a:ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"accel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"decel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"autoRev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_TLTimeNodeRestartType\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_TLTimeNodeFillType\" use=\"optional\"/>\n    <xsd:attribute name=\"syncBehavior\" type=\"ST_TLTimeNodeSyncType\" use=\"optional\"/>\n    <xsd:attribute name=\"tmFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"evtFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"masterRel\" type=\"ST_TLTimeNodeMasterRelation\" use=\"optional\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"afterEffect\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nodeType\" type=\"ST_TLTimeNodeType\" use=\"optional\"/>\n    <xsd:attribute name=\"nodePh\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeParallel\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLNextActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"seek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLPreviousActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"skipTimed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeNodeSequence\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prevCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nextCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"concurrent\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"prevAc\" type=\"ST_TLPreviousActionType\" use=\"optional\"/>\n    <xsd:attribute name=\"nextAc\" type=\"ST_TLNextActionType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeExclusive\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLBehaviorAttributeNameList\">\n    <xsd:sequence>\n      <xsd:element name=\"attrName\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLBehaviorAdditiveType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"repl\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorAccumulateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorTransformType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pt\"/>\n      <xsd:enumeration value=\"img\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorOverrideType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"childStyle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonBehaviorData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attrNameLst\" type=\"CT_TLBehaviorAttributeNameList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"additive\" type=\"ST_TLBehaviorAdditiveType\" use=\"optional\"/>\n    <xsd:attribute name=\"accumulate\" type=\"ST_TLBehaviorAccumulateType\" use=\"optional\"/>\n    <xsd:attribute name=\"xfrmType\" type=\"ST_TLBehaviorTransformType\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rctx\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"override\" type=\"ST_TLBehaviorOverrideType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantBooleanVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantIntegerVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantFloatVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:float\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantStringVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"boolVal\" type=\"CT_TLAnimVariantBooleanVal\"/>\n      <xsd:element name=\"intVal\" type=\"CT_TLAnimVariantIntegerVal\"/>\n      <xsd:element name=\"fltVal\" type=\"CT_TLAnimVariantFloatVal\"/>\n      <xsd:element name=\"strVal\" type=\"CT_TLAnimVariantStringVal\"/>\n      <xsd:element name=\"clrVal\" type=\"a:CT_Color\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeAnimateValueTime\">\n    <xsd:union memberTypes=\"a:ST_PositiveFixedPercentage ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tm\" type=\"ST_TLTimeAnimateValueTime\" use=\"optional\" default=\"indefinite\"/>\n    <xsd:attribute name=\"fmla\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValueList\">\n    <xsd:sequence>\n      <xsd:element name=\"tav\" type=\"CT_TLTimeAnimateValue\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorCalcMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"discrete\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"fmla\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorValueType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tavLst\" type=\"CT_TLTimeAnimateValueList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"calcmode\" type=\"ST_TLAnimateBehaviorCalcMode\" use=\"optional\"/>\n    <xsd:attribute name=\"valueType\" type=\"ST_TLAnimateBehaviorValueType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByRgbColorTransform\">\n    <xsd:attribute name=\"r\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByHslColorTransform\">\n    <xsd:attribute name=\"h\" type=\"a:ST_Angle\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"l\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByAnimateColorTransform\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"rgb\" type=\"CT_TLByRgbColorTransform\"/>\n      <xsd:element name=\"hsl\" type=\"CT_TLByHslColorTransform\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateColorSpace\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rgb\"/>\n      <xsd:enumeration value=\"hsl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateColorDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateColorBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLByAnimateColorTransform\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"clrSpc\" type=\"ST_TLAnimateColorSpace\" use=\"optional\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TLAnimateColorDirection\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateEffectTransition\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateEffectBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"progress\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"transition\" type=\"ST_TLAnimateEffectTransition\" default=\"in\" use=\"optional\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"prLst\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionBehaviorOrigin\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parent\"/>\n      <xsd:enumeration value=\"layout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionPathEditMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relative\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLPoint\">\n    <xsd:attribute name=\"x\" type=\"a:ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"a:ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateMotionBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rCtr\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"origin\" type=\"ST_TLAnimateMotionBehaviorOrigin\" use=\"optional\"/>\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"pathEditMode\" type=\"ST_TLAnimateMotionPathEditMode\" use=\"optional\"/>\n    <xsd:attribute name=\"rAng\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"ptsTypes\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateRotationBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"a:ST_Angle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateScaleBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zoomContents\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLCommandType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"evt\"/>\n      <xsd:enumeration value=\"call\"/>\n      <xsd:enumeration value=\"verb\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommandBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute type=\"ST_TLCommandType\" name=\"type\" use=\"optional\"/>\n    <xsd:attribute name=\"cmd\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSetBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLCommonMediaNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"vol\" type=\"a:ST_PositiveFixedPercentage\" default=\"50%\" use=\"optional\"/>\n    <xsd:attribute name=\"mute\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numSld\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showWhenStopped\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeAudio\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeVideo\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullScrn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_TLBuild\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uiExpand\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_TLTemplate\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTemplateList\">\n    <xsd:sequence>\n      <xsd:element name=\"tmpl\" type=\"CT_TLTemplate\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLParaBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"whole\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"tmplLst\" type=\"CT_TLTemplateList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"build\" type=\"ST_TLParaBuildType\" use=\"optional\" default=\"whole\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoUpdateAnimBg\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advAuto\" type=\"ST_TLTime\" use=\"optional\" default=\"indefinite\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLDiagramBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"depthByNode\"/>\n      <xsd:enumeration value=\"depthByBranch\"/>\n      <xsd:enumeration value=\"breadthByNode\"/>\n      <xsd:enumeration value=\"breadthByLvl\"/>\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"cwIn\"/>\n      <xsd:enumeration value=\"cwOut\"/>\n      <xsd:enumeration value=\"ccw\"/>\n      <xsd:enumeration value=\"ccwIn\"/>\n      <xsd:enumeration value=\"ccwOut\"/>\n      <xsd:enumeration value=\"inByRing\"/>\n      <xsd:enumeration value=\"outByRing\"/>\n      <xsd:enumeration value=\"up\"/>\n      <xsd:enumeration value=\"down\"/>\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildDiagram\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLDiagramBuildType\" use=\"optional\" default=\"whole\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLOleChartBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleBuildChart\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLOleChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLGraphicalObjectBuild\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bldAsOne\" type=\"CT_Empty\"/>\n      <xsd:element name=\"bldSub\" type=\"a:CT_AnimationGraphicalObjectBuildProperties\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BuildList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bldP\" type=\"CT_TLBuildParagraph\"/>\n      <xsd:element name=\"bldDgm\" type=\"CT_TLBuildDiagram\"/>\n      <xsd:element name=\"bldOleChart\" type=\"CT_TLOleBuildChart\"/>\n      <xsd:element name=\"bldGraphic\" type=\"CT_TLGraphicalObjectBuild\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideTiming\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bldLst\" type=\"CT_BuildList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:simpleType name=\"ST_Name\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IndexRange\">\n    <xsd:attribute name=\"st\" type=\"ST_Index\" use=\"required\"/>\n    <xsd:attribute name=\"end\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipListEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_SlideRelationshipListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowId\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SlideListChoice\">\n    <xsd:choice>\n      <xsd:element name=\"sldAll\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sldRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShowId\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CustomerData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagsData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomerDataList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"custData\" type=\"CT_CustomerData\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tags\" type=\"CT_TagsData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionListModify\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mod\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthor\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"initials\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"lastIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"clrIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthorList\">\n    <xsd:sequence>\n      <xsd:element name=\"cmAuthor\" type=\"CT_CommentAuthor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmAuthorLst\" type=\"CT_CommentAuthorList\"/>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"text\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"idx\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"cm\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmLst\" type=\"CT_CommentList\"/>\n  <xsd:attributeGroup name=\"AG_Ole\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"showAsIcon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"imgW\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"imgH\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:simpleType name=\"ST_OleObjectFollowColorScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"textAndBackground\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleObjectEmbed\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"followColorScheme\" type=\"ST_OleObjectFollowColorScheme\" use=\"optional\"\n      default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjectLink\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"updateAutomatic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"embed\" type=\"CT_OleObjectEmbed\"/>\n        <xsd:element name=\"link\" type=\"CT_OleObjectLink\"/>\n      </xsd:choice>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"oleObj\" type=\"CT_OleObject\"/>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlList\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"256\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideId\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldId\" type=\"CT_SlideIdListEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideMasterId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideMasterId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterId\" type=\"CT_SlideMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"notesMasterId\" type=\"CT_NotesMasterIdListEntry\" minOccurs=\"0\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"handoutMasterId\" type=\"CT_HandoutMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontDataId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"a:CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"regular\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bold\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"italic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"boldItalic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontList\">\n    <xsd:sequence>\n      <xsd:element name=\"embeddedFont\" type=\"CT_EmbeddedFontListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShow\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLst\" type=\"CT_SlideRelationshipList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowList\">\n    <xsd:sequence>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhotoAlbumLayout\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fitToSlide\"/>\n      <xsd:enumeration value=\"1pic\"/>\n      <xsd:enumeration value=\"2pic\"/>\n      <xsd:enumeration value=\"4pic\"/>\n      <xsd:enumeration value=\"1picTitle\"/>\n      <xsd:enumeration value=\"2picTitle\"/>\n      <xsd:enumeration value=\"4picTitle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhotoAlbumFrameShape\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"frameStyle1\"/>\n      <xsd:enumeration value=\"frameStyle2\"/>\n      <xsd:enumeration value=\"frameStyle3\"/>\n      <xsd:enumeration value=\"frameStyle4\"/>\n      <xsd:enumeration value=\"frameStyle5\"/>\n      <xsd:enumeration value=\"frameStyle6\"/>\n      <xsd:enumeration value=\"frameStyle7\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhotoAlbum\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bw\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showCaptions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"layout\" type=\"ST_PhotoAlbumLayout\" use=\"optional\" default=\"fitToSlide\"/>\n    <xsd:attribute name=\"frame\" type=\"ST_PhotoAlbumFrameShape\" use=\"optional\" default=\"frameStyle1\"\n    />\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideSizeCoordinate\">\n    <xsd:restriction base=\"a:ST_PositiveCoordinate32\">\n      <xsd:minInclusive value=\"914400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SlideSizeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"screen4x3\"/>\n      <xsd:enumeration value=\"letter\"/>\n      <xsd:enumeration value=\"A4\"/>\n      <xsd:enumeration value=\"35mm\"/>\n      <xsd:enumeration value=\"overhead\"/>\n      <xsd:enumeration value=\"banner\"/>\n      <xsd:enumeration value=\"custom\"/>\n      <xsd:enumeration value=\"ledger\"/>\n      <xsd:enumeration value=\"A3\"/>\n      <xsd:enumeration value=\"B4ISO\"/>\n      <xsd:enumeration value=\"B5ISO\"/>\n      <xsd:enumeration value=\"B4JIS\"/>\n      <xsd:enumeration value=\"B5JIS\"/>\n      <xsd:enumeration value=\"hagakiCard\"/>\n      <xsd:enumeration value=\"screen16x9\"/>\n      <xsd:enumeration value=\"screen16x10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideSize\">\n    <xsd:attribute name=\"cx\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideSizeType\" use=\"optional\" default=\"custom\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"invalStChars\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"invalEndChars\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BookmarkIdSeed\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ModifyVerifier\">\n    <xsd:attribute name=\"algorithmName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinValue\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"saltData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"hashData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Presentation\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterIdLst\" type=\"CT_SlideMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesMasterIdLst\" type=\"CT_NotesMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"handoutMasterIdLst\" type=\"CT_HandoutMasterIdList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sldIdLst\" type=\"CT_SlideIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldSz\" type=\"CT_SlideSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesSz\" type=\"a:CT_PositiveSize2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embeddedFontLst\" type=\"CT_EmbeddedFontList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custShowLst\" type=\"CT_CustomShowList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"photoAlbum\" type=\"CT_PhotoAlbum\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTextStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"modifyVerifier\" type=\"CT_ModifyVerifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverZoom\" type=\"a:ST_Percentage\" use=\"optional\" default=\"50%\"/>\n    <xsd:attribute name=\"firstSlideNum\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showSpecialPlsOnTitleSld\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removePersonalInfoOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"strictFirstAndLastChars\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"embedTrueTypeFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveSubsetFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"bookmarkIdSeed\" type=\"ST_BookmarkIdSeed\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:element name=\"presentation\" type=\"CT_Presentation\"/>\n  <xsd:complexType name=\"CT_HtmlPublishProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showSpeakerNotes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebColorType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"browser\"/>\n      <xsd:enumeration value=\"presentationText\"/>\n      <xsd:enumeration value=\"presentationAccent\"/>\n      <xsd:enumeration value=\"whiteTextOnBlack\"/>\n      <xsd:enumeration value=\"blackTextOnWhite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebScreenSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1400\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebEncoding\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"resizeGraphics\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"relyOnVml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"organizeInFolders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useLongFilenames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"imgSz\" type=\"ST_WebScreenSize\" use=\"optional\" default=\"800x600\"/>\n    <xsd:attribute name=\"encoding\" type=\"ST_WebEncoding\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"clr\" type=\"ST_WebColorType\" use=\"optional\" default=\"whiteTextOnBlack\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintWhat\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slides\"/>\n      <xsd:enumeration value=\"handouts1\"/>\n      <xsd:enumeration value=\"handouts2\"/>\n      <xsd:enumeration value=\"handouts3\"/>\n      <xsd:enumeration value=\"handouts4\"/>\n      <xsd:enumeration value=\"handouts6\"/>\n      <xsd:enumeration value=\"handouts9\"/>\n      <xsd:enumeration value=\"notes\"/>\n      <xsd:enumeration value=\"outline\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrintColorMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bw\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PrintProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prnWhat\" type=\"ST_PrintWhat\" use=\"optional\" default=\"slides\"/>\n    <xsd:attribute name=\"clrMode\" type=\"ST_PrintColorMode\" use=\"optional\" default=\"clr\"/>\n    <xsd:attribute name=\"hiddenSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scaleToFitPaper\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"frameSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoBrowse\">\n    <xsd:attribute name=\"showScrollbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoKiosk\">\n    <xsd:attribute name=\"restart\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"300000\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShowType\">\n    <xsd:choice>\n      <xsd:element name=\"present\" type=\"CT_Empty\"/>\n      <xsd:element name=\"browse\" type=\"CT_ShowInfoBrowse\"/>\n      <xsd:element name=\"kiosk\" type=\"CT_ShowInfoKiosk\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ShowProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:group ref=\"EG_ShowType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"penClr\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useTimings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"htmlPubPr\" type=\"CT_HtmlPublishProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPr\" type=\"CT_WebProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prnPr\" type=\"CT_PrintProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPr\" type=\"CT_ShowProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMru\" type=\"a:CT_ColorMRU\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"presentationPr\" type=\"CT_PresentationProperties\"/>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sldNum\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"hdr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"ftr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PlaceholderType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"body\"/>\n      <xsd:enumeration value=\"ctrTitle\"/>\n      <xsd:enumeration value=\"subTitle\"/>\n      <xsd:enumeration value=\"dt\"/>\n      <xsd:enumeration value=\"sldNum\"/>\n      <xsd:enumeration value=\"ftr\"/>\n      <xsd:enumeration value=\"hdr\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"clipArt\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"media\"/>\n      <xsd:enumeration value=\"sldImg\"/>\n      <xsd:enumeration value=\"pic\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PlaceholderSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"half\"/>\n      <xsd:enumeration value=\"quarter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_PlaceholderType\" use=\"optional\" default=\"obj\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_PlaceholderSize\" use=\"optional\" default=\"full\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hasCustomPrompt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ApplicationNonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"ph\" type=\"CT_Placeholder\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_Media\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isPhoto\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useBgFill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TopLevelSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMap\" type=\"a:CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_ChildSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMappingOverride\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_ChildSlide\">\n    <xsd:attribute name=\"showMasterSp\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showMasterPhAnim\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_BackgroundProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shadeToTitle\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Background\">\n    <xsd:choice>\n      <xsd:element name=\"bgPr\" type=\"CT_BackgroundProperties\"/>\n      <xsd:element name=\"bgRef\" type=\"a:CT_StyleMatrixReference\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Background\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\" default=\"white\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideData\">\n    <xsd:sequence>\n      <xsd:element name=\"bg\" type=\"CT_Background\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spTree\" type=\"CT_GroupShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_ControlList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Slide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sld\" type=\"CT_Slide\"/>\n  <xsd:simpleType name=\"ST_SlideLayoutType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"twoColTx\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"txAndChart\"/>\n      <xsd:enumeration value=\"chartAndTx\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"txAndClipArt\"/>\n      <xsd:enumeration value=\"clipArtAndTx\"/>\n      <xsd:enumeration value=\"titleOnly\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"txAndObj\"/>\n      <xsd:enumeration value=\"objAndTx\"/>\n      <xsd:enumeration value=\"objOnly\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"txAndMedia\"/>\n      <xsd:enumeration value=\"mediaAndTx\"/>\n      <xsd:enumeration value=\"objOverTx\"/>\n      <xsd:enumeration value=\"txOverObj\"/>\n      <xsd:enumeration value=\"txAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndTx\"/>\n      <xsd:enumeration value=\"twoObjOverTx\"/>\n      <xsd:enumeration value=\"fourObj\"/>\n      <xsd:enumeration value=\"vertTx\"/>\n      <xsd:enumeration value=\"clipArtAndVertTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTxOverChart\"/>\n      <xsd:enumeration value=\"twoObj\"/>\n      <xsd:enumeration value=\"objAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndObj\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"secHead\"/>\n      <xsd:enumeration value=\"twoTxTwoObj\"/>\n      <xsd:enumeration value=\"objTx\"/>\n      <xsd:enumeration value=\"picTx\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayout\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"matchingName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideLayoutType\" use=\"optional\" default=\"cust\"/>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldLayout\" type=\"CT_SlideLayout\"/>\n  <xsd:complexType name=\"CT_SlideMasterTextStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"titleStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"otherStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideLayoutId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayoutIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideLayoutId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideLayoutIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLayoutId\" type=\"CT_SlideLayoutIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMaster\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLayoutIdLst\" type=\"CT_SlideLayoutIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txStyles\" type=\"CT_SlideMasterTextStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldMaster\" type=\"CT_SlideMaster\"/>\n  <xsd:complexType name=\"CT_HandoutMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"handoutMaster\" type=\"CT_HandoutMaster\"/>\n  <xsd:complexType name=\"CT_NotesMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"notesMaster\" type=\"CT_NotesMaster\"/>\n  <xsd:complexType name=\"CT_NotesSlide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n  </xsd:complexType>\n  <xsd:element name=\"notes\" type=\"CT_NotesSlide\"/>\n  <xsd:complexType name=\"CT_SlideSyncProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverSldId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"serverSldModifiedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"clientInsertedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldSyncPr\" type=\"CT_SlideSyncProperties\"/>\n  <xsd:complexType name=\"CT_StringTag\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagList\">\n    <xsd:sequence>\n      <xsd:element name=\"tag\" type=\"CT_StringTag\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tagLst\" type=\"CT_TagList\"/>\n  <xsd:simpleType name=\"ST_SplitterBarState\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"minimized\"/>\n      <xsd:enumeration value=\"restored\"/>\n      <xsd:enumeration value=\"maximized\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ViewType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sldView\"/>\n      <xsd:enumeration value=\"sldMasterView\"/>\n      <xsd:enumeration value=\"notesView\"/>\n      <xsd:enumeration value=\"handoutView\"/>\n      <xsd:enumeration value=\"notesMasterView\"/>\n      <xsd:enumeration value=\"outlineView\"/>\n      <xsd:enumeration value=\"sldSorterView\"/>\n      <xsd:enumeration value=\"sldThumbnailView\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NormalViewPortion\">\n    <xsd:attribute name=\"sz\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"autoAdjust\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NormalViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"restoredLeft\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"restoredTop\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showOutlineIcons\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapVertSplitter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vertBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"horzBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"preferSingleView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"scale\" type=\"a:CT_Scale2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"origin\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"varScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesTextViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"collapse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_OutlineViewSlideEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLst\" type=\"CT_OutlineViewSlideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideSorterViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guide\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"vert\"/>\n    <xsd:attribute name=\"pos\" type=\"a:ST_Coordinate32\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GuideList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"guide\" type=\"CT_Guide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"guideLst\" type=\"CT_GuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"snapToGrid\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapToObjects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGuides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ViewProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"normalViewPr\" type=\"CT_NormalViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"slideViewPr\" type=\"CT_SlideViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlineViewPr\" type=\"CT_OutlineViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesTextViewPr\" type=\"CT_NotesTextViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sorterViewPr\" type=\"CT_SlideSorterViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"notesViewPr\" type=\"CT_NotesViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpacing\" type=\"a:CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastView\" type=\"ST_ViewType\" use=\"optional\" default=\"sldView\"/>\n    <xsd:attribute name=\"showComments\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"viewPr\" type=\"CT_ViewProperties\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_AdditionalCharacteristics\">\n    <xsd:sequence>\n      <xsd:element name=\"characteristic\" type=\"CT_Characteristic\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Characteristic\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"relation\" type=\"ST_Relation\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"vocabulary\" type=\"xsd:anyURI\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Relation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ge\"/>\n      <xsd:enumeration value=\"le\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"eq\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"additionalCharacteristics\" type=\"CT_AdditionalCharacteristics\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"s:ST_String\">\n      <xsd:enumeration value=\"ArticleInAPeriodical\"/>\n      <xsd:enumeration value=\"Book\"/>\n      <xsd:enumeration value=\"BookSection\"/>\n      <xsd:enumeration value=\"JournalArticle\"/>\n      <xsd:enumeration value=\"ConferenceProceedings\"/>\n      <xsd:enumeration value=\"Report\"/>\n      <xsd:enumeration value=\"SoundRecording\"/>\n      <xsd:enumeration value=\"Performance\"/>\n      <xsd:enumeration value=\"Art\"/>\n      <xsd:enumeration value=\"DocumentFromInternetSite\"/>\n      <xsd:enumeration value=\"InternetSite\"/>\n      <xsd:enumeration value=\"Film\"/>\n      <xsd:enumeration value=\"Interview\"/>\n      <xsd:enumeration value=\"Patent\"/>\n      <xsd:enumeration value=\"ElectronicSource\"/>\n      <xsd:enumeration value=\"Case\"/>\n      <xsd:enumeration value=\"Misc\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NameListType\">\n    <xsd:sequence>\n      <xsd:element name=\"Person\" type=\"CT_PersonType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PersonType\">\n    <xsd:sequence>\n      <xsd:element name=\"Last\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"First\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Middle\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameType\">\n    <xsd:sequence>\n      <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameOrCorporateType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"Corporate\" minOccurs=\"1\" maxOccurs=\"1\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AuthorType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"Artist\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Author\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"BookAuthor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Compiler\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Composer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Conductor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Counsel\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Director\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Editor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewee\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Inventor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Performer\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"ProducerName\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Translator\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Writer\" type=\"CT_NameType\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SourceType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"AbbreviatedCaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"AlbumTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Author\" type=\"CT_AuthorType\"/>\n        <xsd:element name=\"BookTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Broadcaster\" type=\"s:ST_String\"/>\n        <xsd:element name=\"BroadcastTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ChapterNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"City\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Comments\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ConferenceName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CountryRegion\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Court\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Day\" type=\"s:ST_String\"/>\n        <xsd:element name=\"DayAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Department\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Distributor\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Edition\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Guid\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Institution\" type=\"s:ST_String\"/>\n        <xsd:element name=\"InternetSiteTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Issue\" type=\"s:ST_String\"/>\n        <xsd:element name=\"JournalName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"LCID\" type=\"s:ST_Lang\"/>\n        <xsd:element name=\"Medium\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Month\" type=\"s:ST_String\"/>\n        <xsd:element name=\"MonthAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"NumberVolumes\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Pages\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PatentNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PeriodicalTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ProductionCompany\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PublicationTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Publisher\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RecordingNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RefOrder\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Reporter\" type=\"s:ST_String\"/>\n        <xsd:element name=\"SourceType\" type=\"ST_SourceType\"/>\n        <xsd:element name=\"ShortTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StandardNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StateProvince\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Station\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Tag\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Theater\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ThesisType\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Title\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Type\" type=\"s:ST_String\"/>\n        <xsd:element name=\"URL\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Version\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Volume\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Year\" type=\"s:ST_String\"/>\n        <xsd:element name=\"YearAccessed\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"Sources\" type=\"CT_Sources\"/>\n  <xsd:complexType name=\"CT_Sources\">\n    <xsd:sequence>\n      <xsd:element name=\"Source\" type=\"CT_SourceType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectedStyle\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"StyleName\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"URI\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\">\n  <xsd:simpleType name=\"ST_Lang\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColorRGB\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"3\" fixed=\"true\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Panose\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalendarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gregorian\"/>\n      <xsd:enumeration value=\"gregorianUs\"/>\n      <xsd:enumeration value=\"gregorianMeFrench\"/>\n      <xsd:enumeration value=\"gregorianArabic\"/>\n      <xsd:enumeration value=\"hijri\"/>\n      <xsd:enumeration value=\"hebrew\"/>\n      <xsd:enumeration value=\"taiwan\"/>\n      <xsd:enumeration value=\"japan\"/>\n      <xsd:enumeration value=\"thai\"/>\n      <xsd:enumeration value=\"korea\"/>\n      <xsd:enumeration value=\"saka\"/>\n      <xsd:enumeration value=\"gregorianXlitEnglish\"/>\n      <xsd:enumeration value=\"gregorianXlitFrench\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hash\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CryptProv\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rsaAES\"/>\n      <xsd:enumeration value=\"rsaFull\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"typeAny\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Guid\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff\">\n    <xsd:union memberTypes=\"xsd:boolean ST_OnOff1\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff1\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_String\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XmlName\">\n    <xsd:restriction base=\"xsd:NCName\">\n      <xsd:minLength value=\"1\"/>\n      <xsd:maxLength value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalse\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalseBlank\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n      <xsd:enumeration value=\"\"/>\n      <xsd:enumeration value=\"True\"/>\n      <xsd:enumeration value=\"False\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedDecimalNumber\">\n    <xsd:restriction base=\"xsd:decimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TwipsMeasure\">\n    <xsd:union memberTypes=\"ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignRun\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"superscript\"/>\n      <xsd:enumeration value=\"subscript\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Xstring\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_YAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inline\"/>\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConformanceClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"strict\"/>\n      <xsd:enumeration value=\"transitional\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UniversalMeasure\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveUniversalMeasure\">\n    <xsd:restriction base=\"ST_UniversalMeasure\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"-?((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_DatastoreSchemaRef\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreSchemaRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRef\" type=\"CT_DatastoreSchemaRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreItem\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRefs\" type=\"CT_DatastoreSchemaRefs\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"itemID\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"datastoreItem\" type=\"CT_DatastoreItem\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_Schema\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" default=\"\"/>\n    <xsd:attribute name=\"manifestLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLanguage\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SchemaLibrary\">\n    <xsd:sequence>\n      <xsd:element name=\"schema\" type=\"CT_Schema\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"schemaLibrary\" type=\"CT_SchemaLibrary\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:sequence>\n      <xsd:element name=\"property\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Property\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Property\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n      <xsd:element ref=\"vt:array\"/>\n      <xsd:element ref=\"vt:blob\"/>\n      <xsd:element ref=\"vt:oblob\"/>\n      <xsd:element ref=\"vt:empty\"/>\n      <xsd:element ref=\"vt:null\"/>\n      <xsd:element ref=\"vt:i1\"/>\n      <xsd:element ref=\"vt:i2\"/>\n      <xsd:element ref=\"vt:i4\"/>\n      <xsd:element ref=\"vt:i8\"/>\n      <xsd:element ref=\"vt:int\"/>\n      <xsd:element ref=\"vt:ui1\"/>\n      <xsd:element ref=\"vt:ui2\"/>\n      <xsd:element ref=\"vt:ui4\"/>\n      <xsd:element ref=\"vt:ui8\"/>\n      <xsd:element ref=\"vt:uint\"/>\n      <xsd:element ref=\"vt:r4\"/>\n      <xsd:element ref=\"vt:r8\"/>\n      <xsd:element ref=\"vt:decimal\"/>\n      <xsd:element ref=\"vt:lpstr\"/>\n      <xsd:element ref=\"vt:lpwstr\"/>\n      <xsd:element ref=\"vt:bstr\"/>\n      <xsd:element ref=\"vt:date\"/>\n      <xsd:element ref=\"vt:filetime\"/>\n      <xsd:element ref=\"vt:bool\"/>\n      <xsd:element ref=\"vt:cy\"/>\n      <xsd:element ref=\"vt:error\"/>\n      <xsd:element ref=\"vt:stream\"/>\n      <xsd:element ref=\"vt:ostream\"/>\n      <xsd:element ref=\"vt:storage\"/>\n      <xsd:element ref=\"vt:ostorage\"/>\n      <xsd:element ref=\"vt:vstream\"/>\n      <xsd:element ref=\"vt:clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fmtid\" use=\"required\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"pid\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"linkTarget\" use=\"optional\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  elementFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:all>\n      <xsd:element name=\"Template\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Manager\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Company\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Pages\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Words\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Characters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"PresentationFormat\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Lines\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Paragraphs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Slides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Notes\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"TotalTime\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"HiddenSlides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"MMClips\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"ScaleCrop\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HeadingPairs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"TitlesOfParts\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorLpstr\"/>\n      <xsd:element name=\"LinksUpToDate\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"CharactersWithSpaces\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"SharedDoc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HyperlinkBase\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"HLinks\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"HyperlinksChanged\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"DigSig\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DigSigBlob\"/>\n      <xsd:element name=\"Application\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"AppVersion\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"DocSecurity\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorVariant\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorLpstr\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DigSigBlob\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:blob\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_VectorBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"i8\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"ui8\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"lpstr\"/>\n      <xsd:enumeration value=\"lpwstr\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"filetime\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n      <xsd:enumeration value=\"clsid\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrayBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"int\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"uint\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Cy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*[0-9]*\\.[0-9]{4}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Error\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*0x[0-9A-Za-z]{8}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Null\"/>\n  <xsd:complexType name=\"CT_Vector\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"baseType\" type=\"ST_VectorBaseType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Array\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"cy\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"lBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"uBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"baseType\" type=\"ST_ArrayBaseType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Variant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"vector\"/>\n      <xsd:element ref=\"array\"/>\n      <xsd:element ref=\"blob\"/>\n      <xsd:element ref=\"oblob\"/>\n      <xsd:element ref=\"empty\"/>\n      <xsd:element ref=\"null\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"stream\"/>\n      <xsd:element ref=\"ostream\"/>\n      <xsd:element ref=\"storage\"/>\n      <xsd:element ref=\"ostorage\"/>\n      <xsd:element ref=\"vstream\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vstream\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:base64Binary\">\n        <xsd:attribute name=\"version\" type=\"s:ST_Guid\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:element name=\"variant\" type=\"CT_Variant\"/>\n  <xsd:element name=\"vector\" type=\"CT_Vector\"/>\n  <xsd:element name=\"array\" type=\"CT_Array\"/>\n  <xsd:element name=\"blob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"oblob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"empty\" type=\"CT_Empty\"/>\n  <xsd:element name=\"null\" type=\"CT_Null\"/>\n  <xsd:element name=\"i1\" type=\"xsd:byte\"/>\n  <xsd:element name=\"i2\" type=\"xsd:short\"/>\n  <xsd:element name=\"i4\" type=\"xsd:int\"/>\n  <xsd:element name=\"i8\" type=\"xsd:long\"/>\n  <xsd:element name=\"int\" type=\"xsd:int\"/>\n  <xsd:element name=\"ui1\" type=\"xsd:unsignedByte\"/>\n  <xsd:element name=\"ui2\" type=\"xsd:unsignedShort\"/>\n  <xsd:element name=\"ui4\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"ui8\" type=\"xsd:unsignedLong\"/>\n  <xsd:element name=\"uint\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"r4\" type=\"xsd:float\"/>\n  <xsd:element name=\"r8\" type=\"xsd:double\"/>\n  <xsd:element name=\"decimal\" type=\"xsd:decimal\"/>\n  <xsd:element name=\"lpstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"lpwstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"bstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"date\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"filetime\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"bool\" type=\"xsd:boolean\"/>\n  <xsd:element name=\"cy\" type=\"ST_Cy\"/>\n  <xsd:element name=\"error\" type=\"ST_Error\"/>\n  <xsd:element name=\"stream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"storage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostorage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"vstream\" type=\"CT_Vstream\"/>\n  <xsd:element name=\"clsid\" type=\"s:ST_Guid\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n  <xsd:simpleType name=\"ST_Integer255\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer255\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer255\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Integer2\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"-2\"/>\n      <xsd:maxInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer2\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer2\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SpacingRule\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SpacingRule\">\n    <xsd:attribute name=\"val\" type=\"ST_SpacingRule\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnSignedInteger\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnSignedInteger\">\n    <xsd:attribute name=\"val\" type=\"ST_UnSignedInteger\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Char\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Char\">\n    <xsd:attribute name=\"val\" type=\"ST_Char\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_XAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_YAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_YAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"centered\"/>\n      <xsd:enumeration value=\"match\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shp\">\n    <xsd:attribute name=\"val\" type=\"ST_Shp\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"skw\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"noBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FType\">\n    <xsd:attribute name=\"val\" type=\"ST_FType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LimLoc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"undOvr\"/>\n      <xsd:enumeration value=\"subSup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LimLoc\">\n    <xsd:attribute name=\"val\" type=\"ST_LimLoc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TopBot\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TopBot\">\n    <xsd:attribute name=\"val\" type=\"ST_TopBot\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Script\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"fraktur\"/>\n      <xsd:enumeration value=\"double-struck\"/>\n      <xsd:enumeration value=\"sans-serif\"/>\n      <xsd:enumeration value=\"monospace\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Script\">\n    <xsd:attribute name=\"val\" type=\"ST_Script\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"i\"/>\n      <xsd:enumeration value=\"bi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualBreak\">\n    <xsd:attribute name=\"alnAt\" type=\"ST_Integer255\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ScriptStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"scr\" minOccurs=\"0\" type=\"CT_Script\"/>\n      <xsd:element name=\"sty\" minOccurs=\"0\" type=\"CT_Style\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPR\">\n    <xsd:sequence>\n      <xsd:element name=\"lit\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n      <xsd:choice>\n        <xsd:element name=\"nor\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n        <xsd:sequence>\n          <xsd:group ref=\"EG_ScriptStyle\"/>\n        </xsd:sequence>\n      </xsd:choice>\n      <xsd:element name=\"brk\" minOccurs=\"0\" type=\"CT_ManualBreak\"/>\n      <xsd:element name=\"aln\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPR\" minOccurs=\"0\"/>\n      <xsd:group ref=\"w:EG_RPr\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:group ref=\"w:EG_RunInnerContent\"/>\n        <xsd:element name=\"t\" type=\"CT_Text\" minOccurs=\"0\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CtrlPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"w:EG_RPrMath\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AccPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Acc\">\n    <xsd:sequence>\n      <xsd:element name=\"accPr\" type=\"CT_AccPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarPr\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar\">\n    <xsd:sequence>\n      <xsd:element name=\"barPr\" type=\"CT_BarPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"opEmu\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBreak\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"diff\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"brk\" type=\"CT_ManualBreak\" minOccurs=\"0\"/>\n      <xsd:element name=\"aln\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Box\">\n    <xsd:sequence>\n      <xsd:element name=\"boxPr\" type=\"CT_BoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"hideTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideBot\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideLeft\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideRight\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeH\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeV\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeBLTR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeTLBR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBox\">\n    <xsd:sequence>\n      <xsd:element name=\"borderBoxPr\" type=\"CT_BorderBoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPr\">\n    <xsd:sequence>\n      <xsd:element name=\"begChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"sepChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"endChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shp\" type=\"CT_Shp\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_D\">\n    <xsd:sequence>\n      <xsd:element name=\"dPr\" type=\"CT_DPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"objDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArr\">\n    <xsd:sequence>\n      <xsd:element name=\"eqArrPr\" type=\"CT_EqArrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FPr\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FType\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:sequence>\n      <xsd:element name=\"fPr\" type=\"CT_FPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"num\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"den\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FuncPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Func\">\n    <xsd:sequence>\n      <xsd:element name=\"funcPr\" type=\"CT_FuncPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"fName\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"vertJc\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChr\">\n    <xsd:sequence>\n      <xsd:element name=\"groupChrPr\" type=\"CT_GroupChrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLowPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLow\">\n    <xsd:sequence>\n      <xsd:element name=\"limLowPr\" type=\"CT_LimLowPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUppPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUpp\">\n    <xsd:sequence>\n      <xsd:element name=\"limUppPr\" type=\"CT_LimUppPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCPr\">\n    <xsd:sequence>\n      <xsd:element name=\"count\" type=\"CT_Integer255\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcJc\" type=\"CT_XAlign\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MC\">\n    <xsd:sequence>\n      <xsd:element name=\"mcPr\" type=\"CT_MCPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCS\">\n    <xsd:sequence>\n      <xsd:element name=\"mc\" type=\"CT_MC\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"plcHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcs\" type=\"CT_MCS\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MR\">\n    <xsd:sequence>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_M\">\n    <xsd:sequence>\n      <xsd:element name=\"mPr\" type=\"CT_MPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"mr\" type=\"CT_MR\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NaryPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"limLoc\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"supHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Nary\">\n    <xsd:sequence>\n      <xsd:element name=\"naryPr\" type=\"CT_NaryPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhantPr\">\n    <xsd:sequence>\n      <xsd:element name=\"show\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroWid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroAsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroDesc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"transp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Phant\">\n    <xsd:sequence>\n      <xsd:element name=\"phantPr\" type=\"CT_PhantPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadPr\">\n    <xsd:sequence>\n      <xsd:element name=\"degHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rad\">\n    <xsd:sequence>\n      <xsd:element name=\"radPr\" type=\"CT_RadPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"deg\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPrePr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPre\">\n    <xsd:sequence>\n      <xsd:element name=\"sPrePr\" type=\"CT_SPrePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSub\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubPr\" type=\"CT_SSubPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"alnScr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubSupPr\" type=\"CT_SSubSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSupPr\" type=\"CT_SSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OMathMathElements\">\n    <xsd:choice>\n      <xsd:element name=\"acc\" type=\"CT_Acc\"/>\n      <xsd:element name=\"bar\" type=\"CT_Bar\"/>\n      <xsd:element name=\"box\" type=\"CT_Box\"/>\n      <xsd:element name=\"borderBox\" type=\"CT_BorderBox\"/>\n      <xsd:element name=\"d\" type=\"CT_D\"/>\n      <xsd:element name=\"eqArr\" type=\"CT_EqArr\"/>\n      <xsd:element name=\"f\" type=\"CT_F\"/>\n      <xsd:element name=\"func\" type=\"CT_Func\"/>\n      <xsd:element name=\"groupChr\" type=\"CT_GroupChr\"/>\n      <xsd:element name=\"limLow\" type=\"CT_LimLow\"/>\n      <xsd:element name=\"limUpp\" type=\"CT_LimUpp\"/>\n      <xsd:element name=\"m\" type=\"CT_M\"/>\n      <xsd:element name=\"nary\" type=\"CT_Nary\"/>\n      <xsd:element name=\"phant\" type=\"CT_Phant\"/>\n      <xsd:element name=\"rad\" type=\"CT_Rad\"/>\n      <xsd:element name=\"sPre\" type=\"CT_SPre\"/>\n      <xsd:element name=\"sSub\" type=\"CT_SSub\"/>\n      <xsd:element name=\"sSubSup\" type=\"CT_SSubSup\"/>\n      <xsd:element name=\"sSup\" type=\"CT_SSup\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_OMathElements\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_OMathMathElements\"/>\n      <xsd:group ref=\"w:EG_PContentMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OMathArgPr\">\n    <xsd:sequence>\n      <xsd:element name=\"argSz\" type=\"CT_Integer2\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathArg\">\n    <xsd:sequence>\n      <xsd:element name=\"argPr\" type=\"CT_OMathArgPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"centerGroup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OMathJc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathParaPr\">\n    <xsd:sequence>\n      <xsd:element name=\"jc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBin\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"before\"/>\n      <xsd:enumeration value=\"after\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBin\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBin\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBinSub\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"--\"/>\n      <xsd:enumeration value=\"-+\"/>\n      <xsd:enumeration value=\"+-\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBinSub\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBinSub\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathPr\">\n    <xsd:sequence>\n      <xsd:element name=\"mathFont\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBin\" type=\"CT_BreakBin\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBinSub\" type=\"CT_BreakBinSub\" minOccurs=\"0\"/>\n      <xsd:element name=\"smallFrac\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dispDef\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"rMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"defJc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"preSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"postSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"interSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"intraSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"wrapIndent\" type=\"CT_TwipsMeasure\"/>\n        <xsd:element name=\"wrapRight\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"intLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"naryLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"mathPr\" type=\"CT_MathPr\"/>\n  <xsd:complexType name=\"CT_OMathPara\">\n    <xsd:sequence>\n      <xsd:element name=\"oMathParaPr\" type=\"CT_OMathParaPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OMath\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMath\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"oMathPara\" type=\"CT_OMathPara\"/>\n  <xsd:element name=\"oMath\" type=\"CT_OMath\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  blockDefault=\"#all\">\n  <xsd:simpleType name=\"ST_RelationshipId\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:attribute name=\"id\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"embed\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"link\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"dm\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"lo\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"qs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"cs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"blip\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"pict\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"href\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topRight\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomRight\" type=\"ST_RelationshipId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import \n    namespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n    schemaLocation=\"dml-spreadsheetDrawing.xsd\"/>\n  <xsd:complexType name=\"CT_AutoFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"filterColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FilterColumn\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FilterColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"filters\" type=\"CT_Filters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top10\" type=\"CT_Top10\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customFilters\" type=\"CT_CustomFilters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dynamicFilter\" type=\"CT_DynamicFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colorFilter\" type=\"CT_ColorFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconFilter\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_IconFilter\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"colId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"hiddenButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showButton\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" type=\"CT_Filter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dateGroupItem\" type=\"CT_DateGroupItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n    <xsd:attribute name=\"blank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calendarType\" type=\"s:ST_CalendarType\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filter\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"customFilter\" type=\"CT_CustomFilter\" minOccurs=\"1\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"and\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilter\">\n    <xsd:attribute name=\"operator\" type=\"ST_FilterOperator\" default=\"equal\" use=\"optional\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Top10\">\n    <xsd:attribute name=\"top\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"filterVal\" type=\"xsd:double\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorFilter\">\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"cellColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconFilter\">\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"required\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FilterOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DynamicFilter\">\n    <xsd:attribute name=\"type\" type=\"ST_DynamicFilterType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"valIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxVal\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DynamicFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n      <xsd:enumeration value=\"belowAverage\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_IconSetType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"3Arrows\"/>\n      <xsd:enumeration value=\"3ArrowsGray\"/>\n      <xsd:enumeration value=\"3Flags\"/>\n      <xsd:enumeration value=\"3TrafficLights1\"/>\n      <xsd:enumeration value=\"3TrafficLights2\"/>\n      <xsd:enumeration value=\"3Signs\"/>\n      <xsd:enumeration value=\"3Symbols\"/>\n      <xsd:enumeration value=\"3Symbols2\"/>\n      <xsd:enumeration value=\"4Arrows\"/>\n      <xsd:enumeration value=\"4ArrowsGray\"/>\n      <xsd:enumeration value=\"4RedToBlack\"/>\n      <xsd:enumeration value=\"4Rating\"/>\n      <xsd:enumeration value=\"4TrafficLights\"/>\n      <xsd:enumeration value=\"5Arrows\"/>\n      <xsd:enumeration value=\"5ArrowsGray\"/>\n      <xsd:enumeration value=\"5Rating\"/>\n      <xsd:enumeration value=\"5Quarters\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SortState\">\n    <xsd:sequence>\n      <xsd:element name=\"sortCondition\" minOccurs=\"0\" maxOccurs=\"64\" type=\"CT_SortCondition\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"columnSort\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"caseSensitive\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortMethod\" type=\"ST_SortMethod\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SortCondition\">\n    <xsd:attribute name=\"descending\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortBy\" type=\"ST_SortBy\" use=\"optional\" default=\"value\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"customList\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3Arrows\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cellColor\"/>\n      <xsd:enumeration value=\"fontColor\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SortMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stroke\"/>\n      <xsd:enumeration value=\"pinYin\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DateGroupItem\">\n    <xsd:attribute name=\"year\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"month\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"day\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"hour\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"minute\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"second\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"dateTimeGrouping\" type=\"ST_DateTimeGrouping\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTimeGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"year\"/>\n      <xsd:enumeration value=\"month\"/>\n      <xsd:enumeration value=\"day\"/>\n      <xsd:enumeration value=\"hour\"/>\n      <xsd:enumeration value=\"minute\"/>\n      <xsd:enumeration value=\"second\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellRef\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ref\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefA\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Sqref\">\n    <xsd:list itemType=\"ST_Ref\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Formula\">\n    <xsd:restriction base=\"s:ST_Xstring\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedIntHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedShortHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XStringElement\">\n    <xsd:attribute name=\"v\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectAnchor\">\n    <xsd:sequence>\n      <xsd:element ref=\"xdr:from\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"xdr:to\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"moveWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sizeWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"calcChain\" type=\"CT_CalcChain\"/>\n  <xsd:complexType name=\"CT_CalcChain\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_CalcCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcCell\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"l\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"a\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"authors\" type=\"CT_Authors\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentList\" type=\"CT_CommentList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Authors\">\n    <xsd:sequence>\n      <xsd:element name=\"author\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"text\" type=\"CT_Rst\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentPr\" type=\"CT_CommentPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"textHAlign\" type=\"ST_TextHAlign\" use=\"optional\" default=\"left\"/>\n    <xsd:attribute name=\"textVAlign\" type=\"ST_TextVAlign\" use=\"optional\" default=\"top\"/>\n    <xsd:attribute name=\"lockText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"justLastX\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextHAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"MapInfo\" type=\"CT_MapInfo\"/>\n  <xsd:complexType name=\"CT_MapInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"Schema\" type=\"CT_Schema\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Map\" type=\"CT_Map\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectionNamespaces\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Schema\" mixed=\"true\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaRef\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"Namespace\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"SchemaLanguage\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Map\">\n    <xsd:sequence>\n      <xsd:element name=\"DataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"Name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"RootElement\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"ShowImportExportValidationErrors\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"AutoFit\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"Append\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveSortAFLayout\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveFormat\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"DataBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBinding\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"ConnectionID\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DataBindingLoadMode\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"connections\" type=\"CT_Connections\"/>\n  <xsd:complexType name=\"CT_Connections\">\n    <xsd:sequence>\n      <xsd:element name=\"connection\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Connection\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:sequence>\n      <xsd:element name=\"dbPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DbPr\"/>\n      <xsd:element name=\"olapPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_OlapPr\"/>\n      <xsd:element name=\"webPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_WebPr\"/>\n      <xsd:element name=\"textPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextPr\"/>\n      <xsd:element name=\"parameters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Parameters\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"odcFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"keepAlive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"interval\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"reconnectionMethod\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"refreshedVersion\" use=\"required\" type=\"xsd:unsignedByte\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" use=\"optional\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"savePassword\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"new\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"deleted\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"onlyUseConnectionFile\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"background\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"credentials\" use=\"optional\" type=\"ST_CredMethod\" default=\"integrated\"/>\n    <xsd:attribute name=\"singleSignOnId\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CredMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"integrated\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"stored\"/>\n      <xsd:enumeration value=\"prompt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DbPr\">\n    <xsd:attribute name=\"connection\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"command\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"serverCommand\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"commandType\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OlapPr\">\n    <xsd:attribute name=\"local\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"localConnection\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"localRefresh\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sendLocale\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowDrillCount\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"serverFill\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverNumberFormat\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFont\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFontColor\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tables\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Tables\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"xml\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sourceData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parsePre\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl97\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"textDates\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl2000\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"url\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"post\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"htmlTables\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"htmlFormat\" use=\"optional\" type=\"ST_HtmlFmt\" default=\"none\"/>\n    <xsd:attribute name=\"editPage\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HtmlFmt\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rtf\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Parameters\">\n    <xsd:sequence>\n      <xsd:element name=\"parameter\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Parameter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sqlType\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"parameterType\" use=\"optional\" type=\"ST_ParameterType\" default=\"prompt\"/>\n    <xsd:attribute name=\"refreshOnChange\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"boolean\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"double\" use=\"optional\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"integer\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"string\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cell\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ParameterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"prompt\"/>\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Tables\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_TableMissing\"/>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableMissing\"/>\n  <xsd:complexType name=\"CT_TextPr\">\n    <xsd:sequence>\n      <xsd:element name=\"textFields\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextFields\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fileType\" use=\"optional\" type=\"ST_FileType\" default=\"win\"/>\n    <xsd:attribute name=\"codePage\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1252\"/>\n    <xsd:attribute name=\"characterSet\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\" default=\"\"/>\n    <xsd:attribute name=\"delimited\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"decimal\" use=\"optional\" type=\"s:ST_Xstring\" default=\".\"/>\n    <xsd:attribute name=\"thousands\" use=\"optional\" type=\"s:ST_Xstring\" default=\",\"/>\n    <xsd:attribute name=\"tab\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"space\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"comma\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"semicolon\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"qualifier\" use=\"optional\" type=\"ST_Qualifier\" default=\"doubleQuote\"/>\n    <xsd:attribute name=\"delimiter\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FileType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"mac\"/>\n      <xsd:enumeration value=\"win\"/>\n      <xsd:enumeration value=\"dos\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"other\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Qualifier\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doubleQuote\"/>\n      <xsd:enumeration value=\"singleQuote\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextFields\">\n    <xsd:sequence>\n      <xsd:element name=\"textField\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_TextField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"ST_ExternalConnectionType\" default=\"general\"/>\n    <xsd:attribute name=\"position\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ExternalConnectionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"MDY\"/>\n      <xsd:enumeration value=\"DMY\"/>\n      <xsd:enumeration value=\"YMD\"/>\n      <xsd:enumeration value=\"MYD\"/>\n      <xsd:enumeration value=\"DYM\"/>\n      <xsd:enumeration value=\"YDM\"/>\n      <xsd:enumeration value=\"skip\"/>\n      <xsd:enumeration value=\"EMD\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"pivotCacheDefinition\" type=\"CT_PivotCacheDefinition\"/>\n  <xsd:element name=\"pivotCacheRecords\" type=\"CT_PivotCacheRecords\"/>\n  <xsd:element name=\"pivotTableDefinition\" type=\"CT_pivotTableDefinition\"/>\n  <xsd:complexType name=\"CT_PivotCacheDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheSource\" type=\"CT_CacheSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheFields\" type=\"CT_CacheFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheHierarchies\" minOccurs=\"0\" type=\"CT_CacheHierarchies\"/>\n      <xsd:element name=\"kpis\" minOccurs=\"0\" type=\"CT_PCDKPIs\"/>\n      <xsd:element name=\"tupleCache\" minOccurs=\"0\" type=\"CT_TupleCache\"/>\n      <xsd:element name=\"calculatedItems\" minOccurs=\"0\" type=\"CT_CalculatedItems\"/>\n      <xsd:element name=\"calculatedMembers\" type=\"CT_CalculatedMembers\" minOccurs=\"0\"/>\n      <xsd:element name=\"dimensions\" type=\"CT_Dimensions\" minOccurs=\"0\"/>\n      <xsd:element name=\"measureGroups\" type=\"CT_MeasureGroups\" minOccurs=\"0\"/>\n      <xsd:element name=\"maps\" type=\"CT_MeasureDimensionMaps\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalid\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"optimizeMemory\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshedBy\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDate\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDateIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"backgroundQuery\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingItemsLimit\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"refreshedVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"recordCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"upgradeOnRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tupleCache\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportSubquery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportAdvancedDrill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheFields\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheField\" type=\"CT_CacheField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheField\">\n    <xsd:sequence>\n      <xsd:element name=\"sharedItems\" type=\"CT_SharedItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fieldGroup\" minOccurs=\"0\" type=\"CT_FieldGroup\"/>\n      <xsd:element name=\"mpMap\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"propertyName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueList\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqlType\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"databaseField\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"mappingCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"memberPropertyField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheSource\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"worksheetSource\" type=\"CT_WorksheetSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"consolidation\" type=\"CT_Consolidation\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_SourceType\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" default=\"0\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"external\"/>\n      <xsd:enumeration value=\"consolidation\"/>\n      <xsd:enumeration value=\"scenario\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorksheetSource\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Consolidation\">\n    <xsd:sequence>\n      <xsd:element name=\"pages\" type=\"CT_Pages\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rangeSets\" type=\"CT_RangeSets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"autoPage\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pages\">\n    <xsd:sequence>\n      <xsd:element name=\"page\" type=\"CT_PCDSCPage\" minOccurs=\"1\" maxOccurs=\"4\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSCPage\">\n    <xsd:sequence>\n      <xsd:element name=\"pageItem\" type=\"CT_PageItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSets\">\n    <xsd:sequence>\n      <xsd:element name=\"rangeSet\" type=\"CT_RangeSet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSet\">\n    <xsd:attribute name=\"i1\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i2\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i3\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i4\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedItems\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"s\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"containsSemiMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsNonDate\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsDate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsString\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsInteger\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"minDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"longText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Missing\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Number\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Error\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateTime\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"rangePr\" minOccurs=\"0\" type=\"CT_RangePr\"/>\n      <xsd:element name=\"discretePr\" minOccurs=\"0\" type=\"CT_DiscretePr\"/>\n      <xsd:element name=\"groupItems\" minOccurs=\"0\" type=\"CT_GroupItems\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"par\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"base\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangePr\">\n    <xsd:attribute name=\"autoStart\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"autoEnd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"groupBy\" type=\"ST_GroupBy\" default=\"range\"/>\n    <xsd:attribute name=\"startNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"endNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"startDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"endDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"groupInterval\" type=\"xsd:double\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GroupBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"seconds\"/>\n      <xsd:enumeration value=\"minutes\"/>\n      <xsd:enumeration value=\"hours\"/>\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"quarters\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DiscretePr\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupItems\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCacheRecords\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Record\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Record\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPIs\">\n    <xsd:sequence>\n      <xsd:element name=\"kpi\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PCDKPI\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPI\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"value\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"goal\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"status\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"trend\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"weight\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"time\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheHierarchy\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CacheHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldsUsage\" minOccurs=\"0\" type=\"CT_FieldsUsage\"/>\n      <xsd:element name=\"groupLevels\" minOccurs=\"0\" type=\"CT_GroupLevels\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parentSet\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"attribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"keyAttribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultMemberUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"dimensionUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measures\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"oneField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"memberValueDatatype\" use=\"optional\" type=\"xsd:unsignedShort\"/>\n    <xsd:attribute name=\"unbalanced\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"unbalancedGroup\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldsUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldUsage\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FieldUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldUsage\">\n    <xsd:attribute name=\"x\" use=\"required\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevels\">\n    <xsd:sequence>\n      <xsd:element name=\"groupLevel\" maxOccurs=\"unbounded\" type=\"CT_GroupLevel\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevel\">\n    <xsd:sequence>\n      <xsd:element name=\"groups\" minOccurs=\"0\" type=\"CT_Groups\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"user\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customRollUp\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Groups\">\n    <xsd:sequence>\n      <xsd:element name=\"group\" maxOccurs=\"unbounded\" type=\"CT_LevelGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMembers\" type=\"CT_GroupMembers\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueParent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMember\" maxOccurs=\"unbounded\" type=\"CT_GroupMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMember\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"group\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TupleCache\">\n    <xsd:sequence>\n      <xsd:element name=\"entries\" minOccurs=\"0\" type=\"CT_PCDSDTCEntries\"/>\n      <xsd:element name=\"sets\" minOccurs=\"0\" type=\"CT_Sets\"/>\n      <xsd:element name=\"queryCache\" minOccurs=\"0\" type=\"CT_QueryCache\"/>\n      <xsd:element name=\"serverFormats\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ServerFormats\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormat\">\n    <xsd:attribute name=\"culture\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"format\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"serverFormat\" type=\"CT_ServerFormat\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSDTCEntries\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuples\">\n    <xsd:sequence>\n      <xsd:element name=\"tpl\" type=\"CT_Tuple\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuple\">\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"item\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sets\">\n    <xsd:sequence>\n      <xsd:element name=\"set\" maxOccurs=\"unbounded\" type=\"CT_Set\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Set\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"sortByTuple\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"maxRank\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"setDefinition\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_SortType\" default=\"none\"/>\n    <xsd:attribute name=\"queryFailed\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n      <xsd:enumeration value=\"ascendingAlpha\"/>\n      <xsd:enumeration value=\"descendingAlpha\"/>\n      <xsd:enumeration value=\"ascendingNatural\"/>\n      <xsd:enumeration value=\"descendingNatural\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_QueryCache\">\n    <xsd:sequence>\n      <xsd:element name=\"query\" maxOccurs=\"unbounded\" type=\"CT_Query\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Query\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItems\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedItem\" maxOccurs=\"unbounded\" type=\"CT_CalculatedItem\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItem\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedMember\" maxOccurs=\"unbounded\" type=\"CT_CalculatedMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMember\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"memberName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"solveOrder\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_pivotTableDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"location\" type=\"CT_Location\"/>\n      <xsd:element name=\"pivotFields\" type=\"CT_PivotFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowFields\" type=\"CT_RowFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowItems\" type=\"CT_rowItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"colFields\" type=\"CT_ColFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"colItems\" type=\"CT_colItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageFields\" type=\"CT_PageFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataFields\" type=\"CT_DataFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"formats\" type=\"CT_Formats\" minOccurs=\"0\"/>\n      <xsd:element name=\"conditionalFormats\" type=\"CT_ConditionalFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"chartFormats\" type=\"CT_ChartFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotHierarchies\" type=\"CT_PivotHierarchies\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotTableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotTableStyle\"/>\n      <xsd:element name=\"filters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotFilters\"/>\n      <xsd:element name=\"rowHierarchiesUsage\" type=\"CT_RowHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"colHierarchiesUsage\" type=\"CT_ColHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cacheId\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dataOnRows\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dataPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"dataCaption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"grandTotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"errorCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showError\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showMissing\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"pageStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"pivotTableStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"vacatedStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"tag\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"updatedVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"asteriskTotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showItems\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"editData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"disableFieldList\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showCalcMbrs\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"visualTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showMultipleLabel\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataDropDown\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"printDrill\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showMemberPropertyTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableWizard\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableFieldProperties\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"useAutoFormatting\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"pageWrap\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"pageOverThenDown\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalHiddenItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"colGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fieldPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mergeItem\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showDropZones\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"showEmptyRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showEmptyCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showHeaders\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outlineData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"compactData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"gridDropZones\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"immersive\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleFieldFilters\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"chartFormat\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"rowHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"colHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fieldListSortAscending\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mdxSubqueries\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customListSort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Location\">\n    <xsd:attribute name=\"ref\" use=\"required\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"firstHeaderRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataCol\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"rowPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"colPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotField\" maxOccurs=\"unbounded\" type=\"CT_PivotField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotField\">\n    <xsd:sequence>\n      <xsd:element name=\"items\" minOccurs=\"0\" type=\"CT_Items\"/>\n      <xsd:element name=\"autoSortScope\" minOccurs=\"0\" type=\"CT_AutoSortScope\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"axis\" use=\"optional\" type=\"ST_Axis\"/>\n    <xsd:attribute name=\"dataField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showDropDowns\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hiddenLevel\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueMemberProperty\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"allDrilled\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showAll\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"insertBlankRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"insertPageBreak\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"autoShow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"topAutoShow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hideNewItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"measureFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPageCount\" type=\"xsd:unsignedInt\" default=\"10\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_FieldSortType\" default=\"manual\"/>\n    <xsd:attribute name=\"dataSourceSort\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nonAutoSortDefault\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rankBy\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showPropCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultAttributeDrillState\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoSortScope\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Items\">\n    <xsd:sequence>\n      <xsd:element name=\"item\" maxOccurs=\"unbounded\" type=\"CT_Item\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Item\">\n    <xsd:attribute name=\"n\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"h\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"m\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"e\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pageField\" maxOccurs=\"unbounded\" type=\"CT_PageField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"item\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cap\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataFields\">\n    <xsd:sequence>\n      <xsd:element name=\"dataField\" maxOccurs=\"unbounded\" type=\"CT_DataField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataField\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"subtotal\" type=\"ST_DataConsolidateFunction\" default=\"sum\"/>\n    <xsd:attribute name=\"showDataAs\" type=\"ST_ShowDataAs\" default=\"normal\"/>\n    <xsd:attribute name=\"baseField\" type=\"xsd:int\" default=\"-1\"/>\n    <xsd:attribute name=\"baseItem\" type=\"xsd:unsignedInt\" default=\"1048832\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_rowItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_colItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_I\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_X\">\n    <xsd:attribute name=\"v\" type=\"xsd:int\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Field\">\n    <xsd:attribute name=\"x\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formats\">\n    <xsd:sequence>\n      <xsd:element name=\"format\" maxOccurs=\"unbounded\" type=\"CT_Format\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Format\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"action\" type=\"ST_FormatAction\" default=\"formatting\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"conditionalFormat\" maxOccurs=\"unbounded\" type=\"CT_ConditionalFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotAreas\" type=\"CT_PivotAreas\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"scope\" type=\"ST_Scope\" default=\"selection\"/>\n    <xsd:attribute name=\"type\" type=\"ST_Type\" default=\"none\"/>\n    <xsd:attribute name=\"priority\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreas\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Scope\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"selection\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"field\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Type\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"column\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChartFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"chartFormat\" maxOccurs=\"unbounded\" type=\"CT_ChartFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"chart\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"format\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"series\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotHierarchy\" maxOccurs=\"unbounded\" type=\"CT_PivotHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"mps\" minOccurs=\"0\" type=\"CT_MemberProperties\"/>\n      <xsd:element name=\"members\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Members\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showInFieldList\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"rowHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"colHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierarchyUsage\">\n    <xsd:attribute name=\"hierarchyUsage\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"mp\" maxOccurs=\"unbounded\" type=\"CT_MemberProperty\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nameLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pPos\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"field\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Members\">\n    <xsd:sequence>\n      <xsd:element name=\"member\" maxOccurs=\"unbounded\" type=\"CT_Member\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"level\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Member\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dimensions\">\n    <xsd:sequence>\n      <xsd:element name=\"dimension\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotDimension\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotDimension\">\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroups\">\n    <xsd:sequence>\n      <xsd:element name=\"measureGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMaps\">\n    <xsd:sequence>\n      <xsd:element name=\"map\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureDimensionMap\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroup\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMap\">\n    <xsd:attribute name=\"measureGroup\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dimension\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotTableStyle\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"showRowHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotFilter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_AutoFilter\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"mpFld\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" use=\"required\" type=\"ST_PivotFilterType\"/>\n    <xsd:attribute name=\"evalOrder\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureHier\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureFld\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue1\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue2\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShowDataAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"difference\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"percentDiff\"/>\n      <xsd:enumeration value=\"runTotal\"/>\n      <xsd:enumeration value=\"percentOfRow\"/>\n      <xsd:enumeration value=\"percentOfCol\"/>\n      <xsd:enumeration value=\"percentOfTotal\"/>\n      <xsd:enumeration value=\"index\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ItemType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"countA\"/>\n      <xsd:enumeration value=\"avg\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevP\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varP\"/>\n      <xsd:enumeration value=\"grand\"/>\n      <xsd:enumeration value=\"blank\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormatAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"formatting\"/>\n      <xsd:enumeration value=\"drill\"/>\n      <xsd:enumeration value=\"formula\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FieldSortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PivotFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"unknown\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"captionEqual\"/>\n      <xsd:enumeration value=\"captionNotEqual\"/>\n      <xsd:enumeration value=\"captionBeginsWith\"/>\n      <xsd:enumeration value=\"captionNotBeginsWith\"/>\n      <xsd:enumeration value=\"captionEndsWith\"/>\n      <xsd:enumeration value=\"captionNotEndsWith\"/>\n      <xsd:enumeration value=\"captionContains\"/>\n      <xsd:enumeration value=\"captionNotContains\"/>\n      <xsd:enumeration value=\"captionGreaterThan\"/>\n      <xsd:enumeration value=\"captionGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"captionLessThan\"/>\n      <xsd:enumeration value=\"captionLessThanOrEqual\"/>\n      <xsd:enumeration value=\"captionBetween\"/>\n      <xsd:enumeration value=\"captionNotBetween\"/>\n      <xsd:enumeration value=\"valueEqual\"/>\n      <xsd:enumeration value=\"valueNotEqual\"/>\n      <xsd:enumeration value=\"valueGreaterThan\"/>\n      <xsd:enumeration value=\"valueGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"valueLessThan\"/>\n      <xsd:enumeration value=\"valueLessThanOrEqual\"/>\n      <xsd:enumeration value=\"valueBetween\"/>\n      <xsd:enumeration value=\"valueNotBetween\"/>\n      <xsd:enumeration value=\"dateEqual\"/>\n      <xsd:enumeration value=\"dateNotEqual\"/>\n      <xsd:enumeration value=\"dateOlderThan\"/>\n      <xsd:enumeration value=\"dateOlderThanOrEqual\"/>\n      <xsd:enumeration value=\"dateNewerThan\"/>\n      <xsd:enumeration value=\"dateNewerThanOrEqual\"/>\n      <xsd:enumeration value=\"dateBetween\"/>\n      <xsd:enumeration value=\"dateNotBetween\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"references\" minOccurs=\"0\" type=\"CT_PivotAreaReferences\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PivotAreaType\" default=\"normal\"/>\n    <xsd:attribute name=\"dataOnly\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"labelOnly\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"cacheIndex\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"offset\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"collapsedLevelsAreSubtotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PivotAreaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"origin\"/>\n      <xsd:enumeration value=\"button\"/>\n      <xsd:enumeration value=\"topEnd\"/>\n      <xsd:enumeration value=\"topRight\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotAreaReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"reference\" maxOccurs=\"unbounded\" type=\"CT_PivotAreaReference\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreaReference\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"selected\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"byPosition\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"relative\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Index\">\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Axis\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"axisRow\"/>\n      <xsd:enumeration value=\"axisCol\"/>\n      <xsd:enumeration value=\"axisPage\"/>\n      <xsd:enumeration value=\"axisValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"queryTable\" type=\"CT_QueryTable\"/>\n  <xsd:complexType name=\"CT_QueryTable\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableRefresh\" type=\"CT_QueryTableRefresh\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"headers\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"backgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"firstBackgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"growShrinkType\" type=\"ST_GrowShrinkType\" use=\"optional\"\n      default=\"insertDelete\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removeDataOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"adjustColumnWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"intermediate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableRefresh\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableFields\" type=\"CT_QueryTableFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"queryTableDeletedFields\" type=\"CT_QueryTableDeletedFields\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserveSortFilterLayout\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fieldIdWrapped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headersInLastRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"minimumVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"nextId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"unboundColumnsLeft\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"unboundColumnsRight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableDeletedFields\">\n    <xsd:sequence>\n      <xsd:element name=\"deletedField\" type=\"CT_DeletedField\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DeletedField\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableFields\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableField\" type=\"CT_QueryTableField\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataBound\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clipped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tableColumnId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GrowShrinkType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertDelete\"/>\n      <xsd:enumeration value=\"insertClear\"/>\n      <xsd:enumeration value=\"overwriteClear\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"sst\" type=\"CT_Sst\"/>\n  <xsd:complexType name=\"CT_Sst\">\n    <xsd:sequence>\n      <xsd:element name=\"si\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"uniqueCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhoneticType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"halfwidthKatakana\"/>\n      <xsd:enumeration value=\"fullwidthKatakana\"/>\n      <xsd:enumeration value=\"Hiragana\"/>\n      <xsd:enumeration value=\"noConversion\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhoneticAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhoneticRun\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RElt\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPrElt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrElt\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rFont\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rst\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"r\" type=\"CT_RElt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPh\" type=\"CT_PhoneticRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"phoneticPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PhoneticPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhoneticPr\">\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PhoneticType\" use=\"optional\" default=\"fullwidthKatakana\"/>\n    <xsd:attribute name=\"alignment\" type=\"ST_PhoneticAlignment\" use=\"optional\" default=\"left\"/>\n  </xsd:complexType>\n  <xsd:element name=\"headers\" type=\"CT_RevisionHeaders\"/>\n  <xsd:element name=\"revisions\" type=\"CT_Revisions\"/>\n  <xsd:complexType name=\"CT_RevisionHeaders\">\n    <xsd:sequence>\n      <xsd:element name=\"header\" type=\"CT_RevisionHeader\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"lastGuid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shared\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"diskRevisions\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"trackRevisions\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"exclusive\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"revisionId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"version\" type=\"xsd:int\" default=\"1\"/>\n    <xsd:attribute name=\"keepChangeHistory\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"protected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveHistory\" type=\"xsd:unsignedInt\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Revisions\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rrc\" type=\"CT_RevisionRowColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rm\" type=\"CT_RevisionMove\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcv\" type=\"CT_RevisionCustomView\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rsnm\" type=\"CT_RevisionSheetRename\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ris\" type=\"CT_RevisionInsertSheet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"raf\" type=\"CT_RevisionAutoFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rdn\" type=\"CT_RevisionDefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcmt\" type=\"CT_RevisionComment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rqt\" type=\"CT_RevisionQueryTableField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcft\" type=\"CT_RevisionConflict\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_RevData\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ua\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ra\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_RevisionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetIdMap\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_SheetIdMap\"/>\n      <xsd:element name=\"reviewedList\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ReviewedRevisions\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"maxSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"minRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"maxRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetIdMap\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetId\" type=\"CT_SheetId\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetId\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReviewedRevisions\">\n    <xsd:sequence>\n      <xsd:element name=\"reviewed\" type=\"CT_Reviewed\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Reviewed\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UndoInfo\">\n    <xsd:attribute name=\"index\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"exp\" type=\"ST_FormulaExpression\" use=\"required\"/>\n    <xsd:attribute name=\"ref3D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"array\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cs\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dr\" type=\"ST_RefA\" use=\"required\"/>\n    <xsd:attribute name=\"dn\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionRowColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_rwColActionType\" use=\"required\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionMove\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"source\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"destination\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"sourceSheetId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCustomView\">\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionSheetRename\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"oldName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"newName\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionInsertSheet\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetPosition\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCellChange\">\n    <xsd:sequence>\n      <xsd:element name=\"oc\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nc\" type=\"CT_Cell\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"odxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ndxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"odxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldQuotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"oldPh\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"endOfListFormulaUpdate\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionAutoFormatting\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionComment\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"cell\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" default=\"add\"/>\n    <xsd:attribute name=\"alwaysShow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"author\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"oldLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"newLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionDefinedName\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oldFormula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"customView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldFunction\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldFunctionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"shortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldShortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldHidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldCustomMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldDescription\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldHelp\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldStatusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldComment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionConflict\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionQueryTableField\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"fieldId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_rwColActionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertRow\"/>\n      <xsd:enumeration value=\"deleteRow\"/>\n      <xsd:enumeration value=\"insertCol\"/>\n      <xsd:enumeration value=\"deleteCol\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RevisionAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"add\"/>\n      <xsd:enumeration value=\"delete\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormulaExpression\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ref\"/>\n      <xsd:enumeration value=\"refError\"/>\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"areaError\"/>\n      <xsd:enumeration value=\"computedArea\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"users\" type=\"CT_Users\"/>\n  <xsd:complexType name=\"CT_Users\">\n    <xsd:sequence>\n      <xsd:element name=\"userInfo\" minOccurs=\"0\" maxOccurs=\"256\" type=\"CT_SharedUser\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedUser\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"worksheet\" type=\"CT_Worksheet\"/>\n  <xsd:element name=\"chartsheet\" type=\"CT_Chartsheet\"/>\n  <xsd:element name=\"dialogsheet\" type=\"CT_Dialogsheet\"/>\n  <xsd:complexType name=\"CT_Macrosheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dialogsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" minOccurs=\"0\" type=\"CT_SheetPr\"/>\n      <xsd:element name=\"sheetViews\" minOccurs=\"0\" type=\"CT_SheetViews\"/>\n      <xsd:element name=\"sheetFormatPr\" minOccurs=\"0\" type=\"CT_SheetFormatPr\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" minOccurs=\"0\" type=\"CT_CustomSheetViews\"/>\n      <xsd:element name=\"printOptions\" minOccurs=\"0\" type=\"CT_PrintOptions\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" minOccurs=\"0\" type=\"CT_PageSetup\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" minOccurs=\"0\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"legacyDrawing\" minOccurs=\"0\" type=\"CT_LegacyDrawing\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Worksheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetCalcPr\" type=\"CT_SheetCalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protectedRanges\" type=\"CT_ProtectedRanges\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scenarios\" type=\"CT_Scenarios\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mergeCells\" type=\"CT_MergeCells\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dataValidations\" type=\"CT_DataValidations\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hyperlinks\" type=\"CT_Hyperlinks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellWatches\" type=\"CT_CellWatches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ignoredErrors\" type=\"CT_IgnoredErrors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableParts\" type=\"CT_TableParts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetCalcPr\">\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetFormatPr\">\n    <xsd:attribute name=\"baseColWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"8\"/>\n    <xsd:attribute name=\"defaultColWidth\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultRowHeight\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zeroHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevelRow\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"outlineLevelCol\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cols\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"CT_Col\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Col\">\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bestFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"phonetic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellSpan\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellSpans\">\n    <xsd:list itemType=\"ST_CellSpan\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spans\" type=\"ST_CellSpans\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"customFormat\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ht\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cell\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_CellFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"is\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"cm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"inlineStr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellFormulaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"array\"/>\n      <xsd:enumeration value=\"dataTable\"/>\n      <xsd:enumeration value=\"shared\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlinePr\" type=\"CT_OutlinePr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetUpPr\" type=\"CT_PageSetUpPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"syncHorizontal\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncVertical\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"transitionEvaluation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"transitionEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filterMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableFormatConditionsCalculation\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetDimension\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_SheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"pivotSelection\" type=\"CT_PivotSelection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"windowProtection\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowColHeaders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showZeros\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rightToLeft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultGridColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showWhiteSpace\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" use=\"optional\" default=\"normal\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"64\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"zoomScaleNormal\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScaleSheetLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScalePageLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pane\">\n    <xsd:attribute name=\"xSplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ySplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activePane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"state\" type=\"ST_PaneState\" use=\"optional\" default=\"split\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSelection\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"showHeader\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"label\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"extendable\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"dimension\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"click\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Selection\">\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"activeCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activeCellId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\" default=\"A1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bottomRight\"/>\n      <xsd:enumeration value=\"topRight\"/>\n      <xsd:enumeration value=\"bottomLeft\"/>\n      <xsd:enumeration value=\"topLeft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"brk\" type=\"CT_Break\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"manualBreakCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Break\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"man\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetViewType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"pageBreakPreview\"/>\n      <xsd:enumeration value=\"pageLayout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OutlinePr\">\n    <xsd:attribute name=\"applyStyles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"summaryBelow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"summaryRight\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetUpPr\">\n    <xsd:attribute name=\"autoPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataConsolidate\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRefs\" type=\"CT_DataRefs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"function\" type=\"ST_DataConsolidateFunction\" use=\"optional\" default=\"sum\"/>\n    <xsd:attribute name=\"startLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"leftLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"topLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"link\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataConsolidateFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevp\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varp\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DataRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRef\" type=\"CT_DataRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataRef\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCells\">\n    <xsd:sequence>\n      <xsd:element name=\"mergeCell\" type=\"CT_MergeCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCell\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTags\" type=\"CT_CellSmartTags\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTag\" type=\"CT_CellSmartTag\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTag\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTagPr\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CellSmartTagPr\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlBased\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTagPr\">\n    <xsd:attribute name=\"key\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LegacyDrawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DrawingHF\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"lho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"che\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"chf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomSheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" default=\"64\"/>\n    <xsd:attribute name=\"showPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"outlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"zeroValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"printArea\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAutoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"filterUnique\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" default=\"normal\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidations\">\n    <xsd:sequence>\n      <xsd:element name=\"dataValidation\" type=\"CT_DataValidation\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"disablePrompts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidation\">\n    <xsd:sequence>\n      <xsd:element name=\"formula1\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formula2\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_DataValidationType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"errorStyle\" type=\"ST_DataValidationErrorStyle\" use=\"optional\"\n      default=\"stop\"/>\n    <xsd:attribute name=\"imeMode\" type=\"ST_DataValidationImeMode\" use=\"optional\" default=\"noControl\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_DataValidationOperator\" use=\"optional\" default=\"between\"/>\n    <xsd:attribute name=\"allowBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showDropDown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInputMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showErrorMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errorTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"error\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"promptTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"prompt\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataValidationType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"list\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"time\"/>\n      <xsd:enumeration value=\"textLength\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationErrorStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stop\"/>\n      <xsd:enumeration value=\"warning\"/>\n      <xsd:enumeration value=\"information\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationImeMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"disabled\"/>\n      <xsd:enumeration value=\"hiragana\"/>\n      <xsd:enumeration value=\"fullKatakana\"/>\n      <xsd:enumeration value=\"halfKatakana\"/>\n      <xsd:enumeration value=\"fullAlpha\"/>\n      <xsd:enumeration value=\"halfAlpha\"/>\n      <xsd:enumeration value=\"fullHangul\"/>\n      <xsd:enumeration value=\"halfHangul\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"expression\"/>\n      <xsd:enumeration value=\"cellIs\"/>\n      <xsd:enumeration value=\"colorScale\"/>\n      <xsd:enumeration value=\"dataBar\"/>\n      <xsd:enumeration value=\"iconSet\"/>\n      <xsd:enumeration value=\"top10\"/>\n      <xsd:enumeration value=\"uniqueValues\"/>\n      <xsd:enumeration value=\"duplicateValues\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContainsText\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n      <xsd:enumeration value=\"containsBlanks\"/>\n      <xsd:enumeration value=\"notContainsBlanks\"/>\n      <xsd:enumeration value=\"containsErrors\"/>\n      <xsd:enumeration value=\"notContainsErrors\"/>\n      <xsd:enumeration value=\"timePeriod\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TimePeriod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"last7Days\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConditionalFormattingOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContains\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfvoType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"formula\"/>\n      <xsd:enumeration value=\"percentile\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ConditionalFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"cfRule\" type=\"CT_CfRule\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CfRule\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"3\"/>\n      <xsd:element name=\"colorScale\" type=\"CT_ColorScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataBar\" type=\"CT_DataBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconSet\" type=\"CT_IconSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfType\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"priority\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"stopIfTrue\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"aboveAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_ConditionalFormattingOperator\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"timePeriod\" type=\"ST_TimePeriod\" use=\"optional\"/>\n    <xsd:attribute name=\"rank\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"stdDev\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"equalAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlinks\">\n    <xsd:sequence>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"location\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"t\" type=\"ST_CellFormulaType\" use=\"optional\" default=\"normal\"/>\n        <xsd:attribute name=\"aca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n        <xsd:attribute name=\"dt2D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"dtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del1\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del2\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"r1\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"r2\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"ca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"bx\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorScale\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBar\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"minLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"10\"/>\n    <xsd:attribute name=\"maxLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"90\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconSet\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3TrafficLights1\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"reverse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cfvo\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfvoType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"gte\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintOptions\">\n    <xsd:attribute name=\"horizontalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"verticalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headings\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLinesSet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToHeight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"pageOrder\" type=\"ST_PageOrder\" use=\"optional\" default=\"downThenOver\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellComments\" type=\"ST_CellComments\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errors\" type=\"ST_PrintError\" use=\"optional\" default=\"displayed\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"downThenOver\"/>\n      <xsd:enumeration value=\"overThenDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellComments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"asDisplayed\"/>\n      <xsd:enumeration value=\"atEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"scaleWithDoc\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintError\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"displayed\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"NA\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Scenarios\">\n    <xsd:sequence>\n      <xsd:element name=\"scenario\" type=\"CT_Scenario\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"current\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scenarios\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formatCells\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertHyperlinks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectLockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"pivotTables\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectUnlockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRanges\">\n    <xsd:sequence>\n      <xsd:element name=\"protectedRange\" type=\"CT_ProtectedRange\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRange\">\n    <xsd:sequence>\n      <xsd:element name=\"securityDescriptor\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"securityDescriptor\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scenario\">\n    <xsd:sequence>\n      <xsd:element name=\"inputCells\" type=\"CT_InputCells\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"user\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InputCells\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"undone\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatches\">\n    <xsd:sequence>\n      <xsd:element name=\"cellWatch\" type=\"CT_CellWatch\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatch\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chartsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_ChartsheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_ChartsheetViews\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_ChartsheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomChartsheetViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_ChartsheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" default=\"100\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"content\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CsPageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomChartsheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"customPr\" type=\"CT_CustomProperty\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"oleObject\" type=\"CT_OleObject\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:element name=\"objectPr\" type=\"CT_ObjectPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dvAspect\" type=\"ST_DvAspect\" use=\"optional\" default=\"DVASPECT_CONTENT\"/>\n    <xsd:attribute name=\"link\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oleUpdate\" type=\"ST_OleUpdate\" use=\"optional\"/>\n    <xsd:attribute name=\"autoLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dde\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DvAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"DVASPECT_CONTENT\"/>\n      <xsd:enumeration value=\"DVASPECT_ICON\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OleUpdate\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"OLEUPDATE_ALWAYS\"/>\n      <xsd:enumeration value=\"OLEUPDATE_ONCALL\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebPublishItems\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishItem\" type=\"CT_WebPublishItem\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishItem\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceType\" type=\"ST_WebSourceType\" use=\"required\"/>\n    <xsd:attribute name=\"sourceRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Controls\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"controlPr\" type=\"CT_ControlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"recalcAlways\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"linkedCell\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"listFillRange\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"cf\" type=\"s:ST_Xstring\" use=\"optional\" default=\"pict\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sheet\"/>\n      <xsd:enumeration value=\"printArea\"/>\n      <xsd:enumeration value=\"autoFilter\"/>\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"pivotTable\"/>\n      <xsd:enumeration value=\"query\"/>\n      <xsd:enumeration value=\"label\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IgnoredErrors\">\n    <xsd:sequence>\n      <xsd:element name=\"ignoredError\" type=\"CT_IgnoredError\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IgnoredError\">\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"evalError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"twoDigitTextYear\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numberStoredAsText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formulaRange\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"unlockedFormula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"emptyCellReference\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"listDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calculatedColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PaneState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"split\"/>\n      <xsd:enumeration value=\"frozen\"/>\n      <xsd:enumeration value=\"frozenSplit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableParts\">\n    <xsd:sequence>\n      <xsd:element name=\"tablePart\" type=\"CT_TablePart\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePart\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"metadata\" type=\"CT_Metadata\"/>\n  <xsd:complexType name=\"CT_Metadata\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataTypes\" type=\"CT_MetadataTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"metadataStrings\" type=\"CT_MetadataStrings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mdxMetadata\" type=\"CT_MdxMetadata\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"futureMetadata\" type=\"CT_FutureMetadata\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"cellMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"valueMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataType\" type=\"CT_MetadataType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataType\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"minSupportedVersion\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ghostRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ghostCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"edit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"delete\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"copy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteValues\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteBorders\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteColWidths\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteNumberFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"merge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitFirst\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"rowColShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearAll\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"clearFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearContents\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"assign\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"coerce\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"adjust\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellMeta\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlocks\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_MetadataBlock\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"rc\" type=\"CT_MetadataRecord\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataRecord\">\n    <xsd:attribute name=\"t\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_FutureMetadataBlock\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"mdx\" type=\"CT_Mdx\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Mdx\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"t\" type=\"CT_MdxTuple\"/>\n      <xsd:element name=\"ms\" type=\"CT_MdxSet\"/>\n      <xsd:element name=\"p\" type=\"CT_MdxMemeberProp\"/>\n      <xsd:element name=\"k\" type=\"CT_MdxKPI\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"f\" type=\"ST_MdxFunctionType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxFunctionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"m\"/>\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"c\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"k\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxTuple\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ct\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"fi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxSet\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ns\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"o\" type=\"ST_MdxSetOrder\" use=\"optional\" default=\"u\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxSetOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"a\"/>\n      <xsd:enumeration value=\"d\"/>\n      <xsd:enumeration value=\"aa\"/>\n      <xsd:enumeration value=\"ad\"/>\n      <xsd:enumeration value=\"na\"/>\n      <xsd:enumeration value=\"nd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxMemeberProp\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxKPI\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"p\" type=\"ST_MdxKPIProperty\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxKPIProperty\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"g\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"m\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MetadataStringIndex\">\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataStrings\">\n    <xsd:sequence>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"singleXmlCells\" type=\"CT_SingleXmlCells\"/>\n  <xsd:complexType name=\"CT_SingleXmlCells\">\n    <xsd:sequence>\n      <xsd:element name=\"singleXmlCell\" type=\"CT_SingleXmlCell\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SingleXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlCellPr\" type=\"CT_XmlCellPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlCellPr\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlPr\" type=\"CT_XmlPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleSheet\" type=\"CT_Stylesheet\"/>\n  <xsd:complexType name=\"CT_Stylesheet\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmts\" type=\"CT_NumFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fonts\" type=\"CT_Fonts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fills\" type=\"CT_Fills\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"borders\" type=\"CT_Borders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyleXfs\" type=\"CT_CellStyleXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellXfs\" type=\"CT_CellXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyles\" type=\"CT_CellStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dxfs\" type=\"CT_Dxfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyles\" type=\"CT_TableStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colors\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellAlignment\">\n    <xsd:attribute name=\"horizontal\" type=\"ST_HorizontalAlignment\" use=\"optional\"/>\n    <xsd:attribute name=\"vertical\" type=\"ST_VerticalAlignment\" default=\"bottom\" use=\"optional\"/>\n    <xsd:attribute name=\"textRotation\" type=\"ST_TextRotation\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapText\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"relativeIndent\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"justifyLastLine\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"shrinkToFit\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"readingOrder\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextRotation\">\n    <xsd:union>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:maxInclusive value=\"180\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:enumeration value=\"255\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:union>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"thin\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hair\"/>\n      <xsd:enumeration value=\"mediumDashed\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"mediumDashDot\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"mediumDashDotDot\"/>\n      <xsd:enumeration value=\"slantDashDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Borders\">\n    <xsd:sequence>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"top\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"diagonal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertical\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"horizontal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"diagonalUp\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"diagonalDown\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderPr\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"style\" type=\"ST_BorderStyle\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellProtection\">\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fills\">\n    <xsd:sequence>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"patternFill\" type=\"CT_PatternFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradientFill\" type=\"CT_GradientFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PatternFill\">\n    <xsd:sequence>\n      <xsd:element name=\"fgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"patternType\" type=\"ST_PatternType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"auto\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indexed\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"theme\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tint\" type=\"xsd:double\" use=\"optional\" default=\"0.0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PatternType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"mediumGray\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"darkHorizontal\"/>\n      <xsd:enumeration value=\"darkVertical\"/>\n      <xsd:enumeration value=\"darkDown\"/>\n      <xsd:enumeration value=\"darkUp\"/>\n      <xsd:enumeration value=\"darkGrid\"/>\n      <xsd:enumeration value=\"darkTrellis\"/>\n      <xsd:enumeration value=\"lightHorizontal\"/>\n      <xsd:enumeration value=\"lightVertical\"/>\n      <xsd:enumeration value=\"lightDown\"/>\n      <xsd:enumeration value=\"lightUp\"/>\n      <xsd:enumeration value=\"lightGrid\"/>\n      <xsd:enumeration value=\"lightTrellis\"/>\n      <xsd:enumeration value=\"gray125\"/>\n      <xsd:enumeration value=\"gray0625\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientFill\">\n    <xsd:sequence>\n      <xsd:element name=\"stop\" type=\"CT_GradientStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_GradientType\" use=\"optional\" default=\"linear\"/>\n    <xsd:attribute name=\"degree\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"position\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GradientType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"path\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"fill\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"centerContinuous\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyleXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Xf\">\n    <xsd:sequence>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"optional\"/>\n    <xsd:attribute name=\"fillId\" type=\"ST_FillId\" use=\"optional\"/>\n    <xsd:attribute name=\"borderId\" type=\"ST_BorderId\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pivotButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"applyNumberFormat\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFont\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFill\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyBorder\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyAlignment\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyProtection\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"cellStyle\" type=\"CT_CellStyle\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"required\"/>\n    <xsd:attribute name=\"builtinId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iLevel\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"customBuiltin\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxfs\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxf\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumFmtId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellStyleXfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DxfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:element name=\"indexedColors\" type=\"CT_IndexedColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mruColors\" type=\"CT_MRUColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IndexedColors\">\n    <xsd:sequence>\n      <xsd:element name=\"rgbColor\" type=\"CT_RgbColor\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MRUColors\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RgbColor\">\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultTableStyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultPivotStyle\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyleElement\" type=\"CT_TableStyleElement\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"table\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TableStyleType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableStyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"headerRow\"/>\n      <xsd:enumeration value=\"totalRow\"/>\n      <xsd:enumeration value=\"firstColumn\"/>\n      <xsd:enumeration value=\"lastColumn\"/>\n      <xsd:enumeration value=\"firstRowStripe\"/>\n      <xsd:enumeration value=\"secondRowStripe\"/>\n      <xsd:enumeration value=\"firstColumnStripe\"/>\n      <xsd:enumeration value=\"secondColumnStripe\"/>\n      <xsd:enumeration value=\"firstHeaderCell\"/>\n      <xsd:enumeration value=\"lastHeaderCell\"/>\n      <xsd:enumeration value=\"firstTotalCell\"/>\n      <xsd:enumeration value=\"lastTotalCell\"/>\n      <xsd:enumeration value=\"firstSubtotalColumn\"/>\n      <xsd:enumeration value=\"secondSubtotalColumn\"/>\n      <xsd:enumeration value=\"thirdSubtotalColumn\"/>\n      <xsd:enumeration value=\"firstSubtotalRow\"/>\n      <xsd:enumeration value=\"secondSubtotalRow\"/>\n      <xsd:enumeration value=\"thirdSubtotalRow\"/>\n      <xsd:enumeration value=\"blankRow\"/>\n      <xsd:enumeration value=\"firstColumnSubheading\"/>\n      <xsd:enumeration value=\"secondColumnSubheading\"/>\n      <xsd:enumeration value=\"thirdColumnSubheading\"/>\n      <xsd:enumeration value=\"firstRowSubheading\"/>\n      <xsd:enumeration value=\"secondRowSubheading\"/>\n      <xsd:enumeration value=\"thirdRowSubheading\"/>\n      <xsd:enumeration value=\"pageFieldLabels\"/>\n      <xsd:enumeration value=\"pageFieldValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BooleanProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSize\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IntProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignFontProperty\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:attribute name=\"val\" type=\"ST_FontScheme\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontScheme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnderlineProperty\">\n    <xsd:attribute name=\"val\" type=\"ST_UnderlineValues\" use=\"optional\" default=\"single\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnderlineValues\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"singleAccounting\"/>\n      <xsd:enumeration value=\"doubleAccounting\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"14\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_AutoFormat\">\n    <xsd:attribute name=\"autoFormatId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"applyNumberFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyBorderFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyFontFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyPatternFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyAlignmentFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyWidthHeightFormats\" type=\"xsd:boolean\"/>\n  </xsd:attributeGroup>\n  <xsd:element name=\"externalLink\" type=\"CT_ExternalLink\"/>\n  <xsd:complexType name=\"CT_ExternalLink\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"externalBook\" type=\"CT_ExternalBook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ddeLink\" type=\"CT_DdeLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"oleLink\" type=\"CT_OleLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalBook\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetNames\" type=\"CT_ExternalSheetNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_ExternalDefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetDataSet\" type=\"CT_ExternalSheetDataSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetNames\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetName\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_ExternalSheetName\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_ExternalDefinedName\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedName\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"refersTo\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetDataSet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetData\" type=\"CT_ExternalSheetData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_ExternalRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"refreshError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalRow\">\n    <xsd:sequence>\n      <xsd:element name=\"cell\" type=\"CT_ExternalCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalCell\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeLink\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItems\" type=\"CT_DdeItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ddeService\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"ddeTopic\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItems\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItem\" type=\"CT_DdeItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItem\">\n    <xsd:sequence>\n      <xsd:element name=\"values\" type=\"CT_DdeValues\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" default=\"0\"/>\n    <xsd:attribute name=\"ole\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValues\">\n    <xsd:sequence>\n      <xsd:element name=\"value\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_DdeValue\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rows\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cols\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_DdeValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DdeValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"str\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleLink\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItems\" type=\"CT_OleItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItems\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItem\" type=\"CT_OleItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"icon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"table\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableColumns\" type=\"CT_TableColumns\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyleInfo\" type=\"CT_TableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"displayName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"tableType\" type=\"ST_TableType\" use=\"optional\" default=\"worksheet\"/>\n    <xsd:attribute name=\"headerRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"insertRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"insertRowShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"totalsRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"totalsRowShown\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"tableBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"xml\"/>\n      <xsd:enumeration value=\"queryTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleInfo\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showFirstColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showColumnStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumns\">\n    <xsd:sequence>\n      <xsd:element name=\"tableColumn\" type=\"CT_TableColumn\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumn\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedColumnFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"totalsRowFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xmlColumnPr\" type=\"CT_XmlColumnPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"totalsRowFunction\" type=\"ST_TotalsRowFunction\" use=\"optional\"\n      default=\"none\"/>\n    <xsd:attribute name=\"totalsRowLabel\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"queryTableFieldId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"array\" type=\"xsd:boolean\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TotalsRowFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XmlColumnPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"denormalized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_XmlDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:element name=\"volTypes\" type=\"CT_VolTypes\"/>\n  <xsd:complexType name=\"CT_VolTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"volType\" type=\"CT_VolType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolType\">\n    <xsd:sequence>\n      <xsd:element name=\"main\" type=\"CT_VolMain\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_VolDepType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolMain\">\n    <xsd:sequence>\n      <xsd:element name=\"tp\" type=\"CT_VolTopic\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"first\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopic\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stp\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tr\" type=\"CT_VolTopicRef\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_VolValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopicRef\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VolDepType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"realTimeData\"/>\n      <xsd:enumeration value=\"olapFunctions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VolValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"workbook\" type=\"CT_Workbook\"/>\n  <xsd:complexType name=\"CT_Workbook\">\n    <xsd:sequence>\n      <xsd:element name=\"fileVersion\" type=\"CT_FileVersion\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileSharing\" type=\"CT_FileSharing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookPr\" type=\"CT_WorkbookPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookProtection\" type=\"CT_WorkbookProtection\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"bookViews\" type=\"CT_BookViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheets\" type=\"CT_Sheets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"functionGroups\" type=\"CT_FunctionGroups\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalReferences\" type=\"CT_ExternalReferences\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_DefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"calcPr\" type=\"CT_CalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleSize\" type=\"CT_OleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customWorkbookViews\" type=\"CT_CustomWorkbookViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotCaches\" type=\"CT_PivotCaches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagTypes\" type=\"CT_SmartTagTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishing\" type=\"CT_WebPublishing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileRecoveryPr\" type=\"CT_FileRecoveryPr\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"webPublishObjects\" type=\"CT_WebPublishObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileVersion\">\n    <xsd:attribute name=\"appName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lastEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lowestEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rupBuild\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"codeName\" type=\"s:ST_Guid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"workbookView\" type=\"CT_BookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"visibility\" type=\"ST_Visibility\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"firstSheet\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"activeTab\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"autoFilterDateGrouping\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Visibility\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CustomWorkbookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customWorkbookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomWorkbookView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomWorkbookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"autoUpdate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"mergeInterval\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"changesSavedWin\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"onlySync\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"personalView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"includePrintSettings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"includeHiddenRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"maximized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"activeSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"showFormulaBar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showStatusbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showComments\" type=\"ST_Comments\" use=\"optional\" default=\"commIndicator\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Comments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"commNone\"/>\n      <xsd:enumeration value=\"commIndicator\"/>\n      <xsd:enumeration value=\"commIndAndComment\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Objects\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"placeholders\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Sheets\">\n    <xsd:sequence>\n      <xsd:element name=\"sheet\" type=\"CT_Sheet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sheet\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorkbookPr\">\n    <xsd:attribute name=\"date1904\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"showBorderUnselectedTables\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n    <xsd:attribute name=\"filterPrivacy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"promptedSolutions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInkAnnotation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"backupFile\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveExternalLinkValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"updateLinks\" type=\"ST_UpdateLinks\" use=\"optional\" default=\"userSet\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hidePivotFieldList\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPivotChartFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"allowRefreshQuery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"publishItems\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"checkCompatibility\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshAllConnections\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultThemeVersion\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UpdateLinks\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"userSet\"/>\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:attribute name=\"embed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"show\" type=\"ST_SmartTagShow\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SmartTagShow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"noIndicator\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceUri\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileRecoveryPr\">\n    <xsd:attribute name=\"autoRecover\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"crashSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dataExtractLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"repairLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcPr\">\n    <xsd:attribute name=\"calcId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"calcMode\" type=\"ST_CalcMode\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refMode\" type=\"ST_RefMode\" use=\"optional\" default=\"A1\"/>\n    <xsd:attribute name=\"iterate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"iterateCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"iterateDelta\" type=\"xsd:double\" use=\"optional\" default=\"0.001\"/>\n    <xsd:attribute name=\"fullPrecision\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcCompleted\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentCalc\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentManualCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"forceFullCalc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CalcMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"autoNoTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"A1\"/>\n      <xsd:enumeration value=\"R1C1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_DefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefinedName\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n        <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"vbProcedure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"xlm\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"shortcutKey\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"publishToServer\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"workbookParameter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"externalReference\" type=\"CT_ExternalReference\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReference\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetBackgroundPicture\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCaches\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotCache\" type=\"CT_PivotCache\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCache\">\n    <xsd:attribute name=\"cacheId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileSharing\">\n    <xsd:attribute name=\"readOnlyRecommended\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"reservationPassword\" type=\"ST_UnsignedShortHex\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleSize\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WorkbookProtection\">\n    <xsd:attribute name=\"workbookPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lockStructure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockWindows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockRevision\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"revisionsAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishing\">\n    <xsd:attribute name=\"css\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"thicket\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"longFileNames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"vml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"targetScreenSize\" type=\"ST_TargetScreenSize\" use=\"optional\"\n      default=\"800x600\"/>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"96\"/>\n    <xsd:attribute name=\"codePage\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FunctionGroups\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"functionGroup\" type=\"CT_FunctionGroup\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"builtInGroupCount\" type=\"xsd:unsignedInt\" default=\"16\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FunctionGroup\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishObject\" type=\"CT_WebPublishObject\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObject\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:schemas-microsoft-com:vml\"\n  xmlns:pvml=\"urn:schemas-microsoft-com:office:powerpoint\"\n  xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:w10=\"urn:schemas-microsoft-com:office:word\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:vml\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:office\"\n    schemaLocation=\"vml-officeDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:word\"\n    schemaLocation=\"vml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:excel\"\n    schemaLocation=\"vml-spreadsheetDrawing.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:powerpoint\"\n    schemaLocation=\"vml-presentationDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attributeGroup name=\"AG_Id\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Style\">\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Type\">\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Adj\">\n    <xsd:attribute name=\"adj\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Path\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Fill\">\n    <xsd:attribute name=\"filled\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Chromakey\">\n    <xsd:attribute name=\"chromakey\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Ext\">\n    <xsd:attribute name=\"ext\" form=\"qualified\" type=\"ST_Ext\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_CoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"href\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"class\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"alt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordsize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"print\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"stroked\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeweight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeCoreAttributes\">\n    <xsd:attribute ref=\"o:spid\"/>\n    <xsd:attribute ref=\"o:oned\"/>\n    <xsd:attribute ref=\"o:regroupid\"/>\n    <xsd:attribute ref=\"o:doubleclicknotify\"/>\n    <xsd:attribute ref=\"o:button\"/>\n    <xsd:attribute ref=\"o:userhidden\"/>\n    <xsd:attribute ref=\"o:bullet\"/>\n    <xsd:attribute ref=\"o:hr\"/>\n    <xsd:attribute ref=\"o:hrstd\"/>\n    <xsd:attribute ref=\"o:hrnoshade\"/>\n    <xsd:attribute ref=\"o:hrpct\"/>\n    <xsd:attribute ref=\"o:hralign\"/>\n    <xsd:attribute ref=\"o:allowincell\"/>\n    <xsd:attribute ref=\"o:allowoverlap\"/>\n    <xsd:attribute ref=\"o:userdrawn\"/>\n    <xsd:attribute ref=\"o:bordertopcolor\"/>\n    <xsd:attribute ref=\"o:borderleftcolor\"/>\n    <xsd:attribute ref=\"o:borderbottomcolor\"/>\n    <xsd:attribute ref=\"o:borderrightcolor\"/>\n    <xsd:attribute ref=\"o:dgmlayout\"/>\n    <xsd:attribute ref=\"o:dgmnodekind\"/>\n    <xsd:attribute ref=\"o:dgmlayoutmru\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeShapeAttributes\">\n    <xsd:attribute ref=\"o:spt\"/>\n    <xsd:attribute ref=\"o:connectortype\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"o:oleicon\"/>\n    <xsd:attribute ref=\"o:ole\"/>\n    <xsd:attribute ref=\"o:preferrelative\"/>\n    <xsd:attribute ref=\"o:cliptowrap\"/>\n    <xsd:attribute ref=\"o:clip\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllCoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_CoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeCoreAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_ShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeShapeAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ImageAttributes\">\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropleft\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"croptop\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropright\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropbottom\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gain\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"blacklevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gamma\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"grayscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"bilevel\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_StrokeAttributes\">\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n  </xsd:attributeGroup>\n  <xsd:group name=\"EG_ShapeElements\">\n    <xsd:choice>\n      <xsd:element ref=\"path\"/>\n      <xsd:element ref=\"formulas\"/>\n      <xsd:element ref=\"handles\"/>\n      <xsd:element ref=\"fill\"/>\n      <xsd:element ref=\"stroke\"/>\n      <xsd:element ref=\"shadow\"/>\n      <xsd:element ref=\"textbox\"/>\n      <xsd:element ref=\"textpath\"/>\n      <xsd:element ref=\"imagedata\"/>\n      <xsd:element ref=\"o:skew\"/>\n      <xsd:element ref=\"o:extrusion\"/>\n      <xsd:element ref=\"o:callout\"/>\n      <xsd:element ref=\"o:lock\"/>\n      <xsd:element ref=\"o:clippath\"/>\n      <xsd:element ref=\"o:signatureline\"/>\n      <xsd:element ref=\"w10:wrap\"/>\n      <xsd:element ref=\"w10:anchorlock\"/>\n      <xsd:element ref=\"w10:bordertop\"/>\n      <xsd:element ref=\"w10:borderbottom\"/>\n      <xsd:element ref=\"w10:borderleft\"/>\n      <xsd:element ref=\"w10:borderright\"/>\n      <xsd:element ref=\"x:ClientData\" minOccurs=\"0\"/>\n      <xsd:element ref=\"pvml:textdata\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"shape\" type=\"CT_Shape\"/>\n  <xsd:element name=\"shapetype\" type=\"CT_Shapetype\"/>\n  <xsd:element name=\"group\" type=\"CT_Group\"/>\n  <xsd:element name=\"background\" type=\"CT_Background\"/>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n      <xsd:element ref=\"pvml:iscomment\"/>\n      <xsd:element ref=\"o:equationxml\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Type\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:gfxdata\"/>\n    <xsd:attribute name=\"equationxml\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shapetype\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"o:complex\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:master\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Group\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"group\"/>\n      <xsd:element ref=\"shape\"/>\n      <xsd:element ref=\"shapetype\"/>\n      <xsd:element ref=\"arc\"/>\n      <xsd:element ref=\"curve\"/>\n      <xsd:element ref=\"image\"/>\n      <xsd:element ref=\"line\"/>\n      <xsd:element ref=\"oval\"/>\n      <xsd:element ref=\"polyline\"/>\n      <xsd:element ref=\"rect\"/>\n      <xsd:element ref=\"roundrect\"/>\n      <xsd:element ref=\"o:diagram\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"editas\" type=\"ST_EditAs\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:tableproperties\"/>\n    <xsd:attribute ref=\"o:tablelimits\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:element ref=\"fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:targetscreensize\"/>\n  </xsd:complexType>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:element name=\"formulas\" type=\"CT_Formulas\"/>\n  <xsd:element name=\"handles\" type=\"CT_Handles\"/>\n  <xsd:element name=\"imagedata\" type=\"CT_ImageData\"/>\n  <xsd:element name=\"path\" type=\"CT_Path\"/>\n  <xsd:element name=\"textbox\" type=\"CT_Textbox\"/>\n  <xsd:element name=\"shadow\" type=\"CT_Shadow\"/>\n  <xsd:element name=\"stroke\" type=\"CT_Stroke\"/>\n  <xsd:element name=\"textpath\" type=\"CT_TextPath\"/>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"position\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"aspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"alignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"focus\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focussize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focusposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"method\" type=\"ST_FillMethod\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:opacity2\"/>\n    <xsd:attribute name=\"recolor\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotate\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formulas\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_F\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:attribute name=\"eqn\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Handles\">\n    <xsd:sequence>\n      <xsd:element name=\"h\" type=\"CT_H\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_H\">\n    <xsd:attribute name=\"position\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"polar\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"map\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"invx\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"invy\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"switch\" type=\"s:ST_TrueFalseBlank\"/>\n    <xsd:attribute name=\"xrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"yrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"radiusrange\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ImageData\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attribute name=\"embosscolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"recolortarget\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:oleid\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:movie\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n    <xsd:attribute ref=\"r:id\"/>\n    <xsd:attribute ref=\"r:pict\"/>\n    <xsd:attribute ref=\"r:href\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"limo\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textboxrect\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fillok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shadowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"arrowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"gradientshapeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textpathok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpenok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:connecttype\"/>\n    <xsd:attribute ref=\"o:connectlocs\"/>\n    <xsd:attribute ref=\"o:connectangles\"/>\n    <xsd:attribute ref=\"o:extrusionok\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shadow\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ShadowType\" use=\"optional\"/>\n    <xsd:attribute name=\"obscured\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"offset2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Stroke\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:left\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:top\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:right\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:bottom\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:column\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_StrokeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Textbox\">\n    <xsd:choice>\n      <xsd:element ref=\"w:txbxContent\" minOccurs=\"0\"/>\n      <xsd:any namespace=\"##local\" processContents=\"skip\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"inset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:singleclick\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextPath\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitpath\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"trim\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"xscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"string\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"arc\" type=\"CT_Arc\"/>\n  <xsd:element name=\"curve\" type=\"CT_Curve\"/>\n  <xsd:element name=\"image\" type=\"CT_Image\"/>\n  <xsd:element name=\"line\" type=\"CT_Line\"/>\n  <xsd:element name=\"oval\" type=\"CT_Oval\"/>\n  <xsd:element name=\"polyline\" type=\"CT_PolyLine\"/>\n  <xsd:element name=\"rect\" type=\"CT_Rect\"/>\n  <xsd:element name=\"roundrect\" type=\"CT_RoundRect\"/>\n  <xsd:complexType name=\"CT_Arc\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"startAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"endAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Curve\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control1\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Image\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Oval\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolyLine\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"points\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RoundRect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"arcsize\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Ext\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"view\"/>\n      <xsd:enumeration value=\"edit\"/>\n      <xsd:enumeration value=\"backwardCompatible\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"frame\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"sigma\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"linear sigma\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ShadowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"emboss\"/>\n      <xsd:enumeration value=\"perspective\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeLineStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thinThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeJoinStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"miter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeEndCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"round\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowLength\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"short\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"long\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"narrow\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"wide\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"block\"/>\n      <xsd:enumeration value=\"classic\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"open\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ImageAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ignore\"/>\n      <xsd:enumeration value=\"atMost\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"canvas\"/>\n      <xsd:enumeration value=\"orgchart\"/>\n      <xsd:enumeration value=\"radial\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"stacked\"/>\n      <xsd:enumeration value=\"venn\"/>\n      <xsd:enumeration value=\"bullseye\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:office\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:vml\" schemaLocation=\"vml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attribute name=\"bwmode\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwpure\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwnormal\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"targetscreensize\" type=\"ST_ScreenSize\"/>\n  <xsd:attribute name=\"insetmode\" type=\"ST_InsetMode\" default=\"custom\"/>\n  <xsd:attribute name=\"spt\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"oned\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"regroupid\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"doubleclicknotify\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"connectortype\" type=\"ST_ConnectorType\" default=\"straight\"/>\n  <xsd:attribute name=\"button\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userhidden\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"forcedash\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleicon\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"ole\" type=\"s:ST_TrueFalseBlank\"/>\n  <xsd:attribute name=\"preferrelative\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"cliptowrap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"clip\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bullet\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hr\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrstd\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrnoshade\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrpct\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"hralign\" type=\"ST_HrAlign\" default=\"left\"/>\n  <xsd:attribute name=\"allowincell\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"allowoverlap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userdrawn\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bordertopcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderleftcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderbottomcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderrightcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connecttype\" type=\"ST_ConnectType\"/>\n  <xsd:attribute name=\"connectlocs\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connectangles\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"master\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"extrusionok\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"href\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"althref\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"title\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"singleclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleid\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"detectmouseclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"movie\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"spid\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"opacity2\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"relid\" type=\"r:ST_RelationshipId\"/>\n  <xsd:attribute name=\"dgmlayout\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"dgmnodekind\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"dgmlayoutmru\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"gfxdata\" type=\"xsd:base64Binary\"/>\n  <xsd:attribute name=\"tableproperties\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"tablelimits\" type=\"xsd:string\"/>\n  <xsd:element name=\"shapedefaults\" type=\"CT_ShapeDefaults\"/>\n  <xsd:element name=\"shapelayout\" type=\"CT_ShapeLayout\"/>\n  <xsd:element name=\"signatureline\" type=\"CT_SignatureLine\"/>\n  <xsd:element name=\"ink\" type=\"CT_Ink\"/>\n  <xsd:element name=\"diagram\" type=\"CT_Diagram\"/>\n  <xsd:element name=\"equationxml\" type=\"CT_EquationXml\"/>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:all minOccurs=\"0\">\n      <xsd:element ref=\"v:fill\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:stroke\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:textbox\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:shadow\" minOccurs=\"0\"/>\n      <xsd:element ref=\"skew\" minOccurs=\"0\"/>\n      <xsd:element ref=\"extrusion\" minOccurs=\"0\"/>\n      <xsd:element ref=\"callout\" minOccurs=\"0\"/>\n      <xsd:element ref=\"lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"colormru\" minOccurs=\"0\" type=\"CT_ColorMru\"/>\n      <xsd:element name=\"colormenu\" minOccurs=\"0\" type=\"CT_ColorMenu\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"spidmax\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"stroke\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"allowincell\" form=\"qualified\" type=\"s:ST_TrueFalse\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ink\">\n    <xsd:sequence/>\n    <xsd:attribute name=\"i\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"annotation\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"contentType\" type=\"ST_ContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SignatureLine\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"issignatureline\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"provid\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"signinginstructionsset\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"allowcomments\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"showsigndate\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"suggestedsigner\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigner2\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigneremail\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"signinginstructions\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"addlxml\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"sigprovurl\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLayout\">\n    <xsd:all>\n      <xsd:element name=\"idmap\" type=\"CT_IdMap\" minOccurs=\"0\"/>\n      <xsd:element name=\"regrouptable\" type=\"CT_RegroupTable\" minOccurs=\"0\"/>\n      <xsd:element name=\"rules\" type=\"CT_Rules\" minOccurs=\"0\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IdMap\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RegroupTable\">\n    <xsd:sequence>\n      <xsd:element name=\"entry\" type=\"CT_Entry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Entry\">\n    <xsd:attribute name=\"new\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" type=\"CT_R\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"proxy\" type=\"CT_Proxy\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_RType\" use=\"optional\"/>\n    <xsd:attribute name=\"how\" type=\"ST_How\" use=\"optional\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Proxy\">\n    <xsd:attribute name=\"start\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"end\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"connectloc\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Diagram\">\n    <xsd:sequence>\n      <xsd:element name=\"relationtable\" type=\"CT_RelationTable\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"dgmstyle\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"autoformat\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"reverse\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autolayout\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscalex\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscaley\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmfontsize\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"constrainbounds\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmbasetextscale\" type=\"xsd:integer\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EquationXml\">\n    <xsd:sequence>\n      <xsd:any namespace=\"##any\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"contentType\" type=\"ST_AlternateMathContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlternateMathContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RelationTable\">\n    <xsd:sequence>\n      <xsd:element name=\"rel\" type=\"CT_Relation\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Relation\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"idsrc\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"iddest\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"idcntr\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMru\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMenu\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"shadowcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"extrusioncolor\" type=\"s:ST_ColorType\"/>\n  </xsd:complexType>\n  <xsd:element name=\"skew\" type=\"CT_Skew\"/>\n  <xsd:element name=\"extrusion\" type=\"CT_Extrusion\"/>\n  <xsd:element name=\"callout\" type=\"CT_Callout\"/>\n  <xsd:element name=\"lock\" type=\"CT_Lock\"/>\n  <xsd:element name=\"OLEObject\" type=\"CT_OLEObject\"/>\n  <xsd:element name=\"complex\" type=\"CT_Complex\"/>\n  <xsd:element name=\"left\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"top\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"right\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"bottom\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"column\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"clippath\" type=\"CT_ClipPath\"/>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:complexType name=\"CT_Skew\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extrusion\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ExtrusionType\" default=\"parallel\" use=\"optional\"/>\n    <xsd:attribute name=\"render\" type=\"ST_ExtrusionRender\" default=\"solid\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpointorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpoint\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"plane\" type=\"ST_ExtrusionPlane\" default=\"XY\" use=\"optional\"/>\n    <xsd:attribute name=\"skewangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"skewamt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"foredepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"backdepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientation\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientationangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"lockrotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autorotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationcenter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationangle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"colormode\" type=\"ST_ColorMode\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"shininess\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"specularity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"diffusity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"metal\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"facet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightface\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"brightness\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh2\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Callout\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gap\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"dropauto\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"drop\" type=\"ST_CalloutDrop\" use=\"optional\"/>\n    <xsd:attribute name=\"distance\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lengthspecified\" type=\"s:ST_TrueFalse\" default=\"f\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"accentbar\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textborder\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusx\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusy\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"position\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"selection\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"grouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"ungrouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotation\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"cropping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"verticies\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"adjusthandles\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"aspectratio\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shapetype\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OLEObject\">\n    <xsd:sequence>\n      <xsd:element name=\"LinkType\" type=\"ST_OLELinkType\" minOccurs=\"0\"/>\n      <xsd:element name=\"LockedField\" type=\"s:ST_TrueFalseBlank\" minOccurs=\"0\"/>\n      <xsd:element name=\"FieldCodes\" type=\"xsd:string\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"Type\" type=\"ST_OLEType\" use=\"optional\"/>\n    <xsd:attribute name=\"ProgID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"ShapeID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DrawAspect\" type=\"ST_OLEDrawAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"ObjectID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"UpdateMode\" type=\"ST_OLEUpdateMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Complex\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrokeChild\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"v:ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"v:ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"v:ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"v:ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"v:ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"href\"/>\n    <xsd:attribute ref=\"althref\"/>\n    <xsd:attribute ref=\"title\"/>\n    <xsd:attribute ref=\"forcedash\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipPath\">\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"required\" form=\"qualified\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"callout\"/>\n      <xsd:enumeration value=\"connector\"/>\n      <xsd:enumeration value=\"align\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_How\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"middle\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BWMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"color\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"grayScale\"/>\n      <xsd:enumeration value=\"lightGrayscale\"/>\n      <xsd:enumeration value=\"inverseGray\"/>\n      <xsd:enumeration value=\"grayOutline\"/>\n      <xsd:enumeration value=\"highContrast\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hide\"/>\n      <xsd:enumeration value=\"undrawn\"/>\n      <xsd:enumeration value=\"blackTextAndLines\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544,376\"/>\n      <xsd:enumeration value=\"640,480\"/>\n      <xsd:enumeration value=\"720,512\"/>\n      <xsd:enumeration value=\"800,600\"/>\n      <xsd:enumeration value=\"1024,768\"/>\n      <xsd:enumeration value=\"1152,862\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InsetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramLayout\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:enumeration value=\"0\"/>\n      <xsd:enumeration value=\"1\"/>\n      <xsd:enumeration value=\"2\"/>\n      <xsd:enumeration value=\"3\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"perspective\"/>\n      <xsd:enumeration value=\"parallel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionRender\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"wireFrame\"/>\n      <xsd:enumeration value=\"boundingCube\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionPlane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"XY\"/>\n      <xsd:enumeration value=\"ZX\"/>\n      <xsd:enumeration value=\"YZ\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"30\"/>\n      <xsd:enumeration value=\"45\"/>\n      <xsd:enumeration value=\"60\"/>\n      <xsd:enumeration value=\"90\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutDrop\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutPlacement\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"user\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"straight\"/>\n      <xsd:enumeration value=\"elbow\"/>\n      <xsd:enumeration value=\"curved\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HrAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"segments\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLELinkType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Embed\"/>\n      <xsd:enumeration value=\"Link\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Content\"/>\n      <xsd:enumeration value=\"Icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Always\"/>\n      <xsd:enumeration value=\"OnCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gradientCenter\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"gradientUnscaled\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"background\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:powerpoint\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:powerpoint\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"iscomment\" type=\"CT_Empty\"/>\n  <xsd:element name=\"textdata\" type=\"CT_Rel\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:excel\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"ClientData\" type=\"CT_ClientData\"/>\n  <xsd:complexType name=\"CT_ClientData\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"MoveWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SizeWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Anchor\" type=\"xsd:string\"/>\n      <xsd:element name=\"Locked\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DefaultSize\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"PrintObject\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Disabled\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoFill\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoPict\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaMacro\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextHAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextVAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"LockText\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"JustLastX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SecretEdit\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Default\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Help\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Cancel\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dismiss\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Accel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Accel2\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Row\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Column\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Visible\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RowHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ColHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VTEdit\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MultiLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VScroll\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ValidIds\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaRange\" type=\"xsd:string\"/>\n      <xsd:element name=\"WidthMin\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Sel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"NoThreeD2\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SelType\" type=\"xsd:string\"/>\n      <xsd:element name=\"MultiSel\" type=\"xsd:string\"/>\n      <xsd:element name=\"LCT\" type=\"xsd:string\"/>\n      <xsd:element name=\"ListItem\" type=\"xsd:string\"/>\n      <xsd:element name=\"DropStyle\" type=\"xsd:string\"/>\n      <xsd:element name=\"Colored\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DropLines\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Checked\" type=\"xsd:integer\"/>\n      <xsd:element name=\"FmlaLink\" type=\"xsd:string\"/>\n      <xsd:element name=\"FmlaPict\" type=\"xsd:string\"/>\n      <xsd:element name=\"NoThreeD\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FirstButton\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaGroup\" type=\"xsd:string\"/>\n      <xsd:element name=\"Val\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Min\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Max\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Inc\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Page\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Horiz\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dx\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MapOCX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"CF\" type=\"ST_CF\"/>\n      <xsd:element name=\"Camera\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RecalcAlways\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoScale\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DDE\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"UIObj\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ScriptText\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptExtended\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptLanguage\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"ScriptLocation\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"FmlaTxbx\" type=\"xsd:string\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"ObjectType\" type=\"ST_ObjectType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CF\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ObjectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Button\"/>\n      <xsd:enumeration value=\"Checkbox\"/>\n      <xsd:enumeration value=\"Dialog\"/>\n      <xsd:enumeration value=\"Drop\"/>\n      <xsd:enumeration value=\"Edit\"/>\n      <xsd:enumeration value=\"GBox\"/>\n      <xsd:enumeration value=\"Label\"/>\n      <xsd:enumeration value=\"LineA\"/>\n      <xsd:enumeration value=\"List\"/>\n      <xsd:enumeration value=\"Movie\"/>\n      <xsd:enumeration value=\"Note\"/>\n      <xsd:enumeration value=\"Pict\"/>\n      <xsd:enumeration value=\"Radio\"/>\n      <xsd:enumeration value=\"RectA\"/>\n      <xsd:enumeration value=\"Scroll\"/>\n      <xsd:enumeration value=\"Spin\"/>\n      <xsd:enumeration value=\"Shape\"/>\n      <xsd:enumeration value=\"Group\"/>\n      <xsd:enumeration value=\"Rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:word\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:word\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"bordertop\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderleft\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderright\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderbottom\" type=\"CT_Border\"/>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"type\" type=\"ST_BorderType\" use=\"optional\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:positiveInteger\" use=\"optional\"/>\n    <xsd:attribute name=\"shadow\" type=\"ST_BorderShadow\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"wrap\" type=\"CT_Wrap\"/>\n  <xsd:complexType name=\"CT_Wrap\">\n    <xsd:attribute name=\"type\" type=\"ST_WrapType\" use=\"optional\"/>\n    <xsd:attribute name=\"side\" type=\"ST_WrapSide\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorx\" type=\"ST_HorizontalAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"anchory\" type=\"ST_VerticalAnchor\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"anchorlock\" type=\"CT_AnchorLock\"/>\n  <xsd:complexType name=\"CT_AnchorLock\"/>\n  <xsd:simpleType name=\"ST_BorderType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hairline\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmall\"/>\n      <xsd:enumeration value=\"thickThinSmall\"/>\n      <xsd:enumeration value=\"thickBetweenThinSmall\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n      <xsd:enumeration value=\"thinThickLarge\"/>\n      <xsd:enumeration value=\"thickThinLarge\"/>\n      <xsd:enumeration value=\"thickBetweenThinLarge\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashedSmall\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"HTMLOutset\"/>\n      <xsd:enumeration value=\"HTMLInset\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderShadow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"topAndBottom\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapSide\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"char\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"line\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:sl=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" schemaLocation=\"../mce/mc.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n    schemaLocation=\"dml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n    schemaLocation=\"shared-math.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n    schemaLocation=\"shared-customXmlSchemaProperties.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LongHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LongHexNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_LongHexNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShortHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UcharHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Charset\">\n    <xsd:attribute name=\"val\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"s:ST_String\" use=\"optional\" default=\"ISO-8859-1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DecimalNumberOrPercent\">\n    <xsd:union memberTypes=\"ST_UnqualifiedPercentage s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnqualifiedPercentage\">\n    <xsd:restriction base=\"xsd:decimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DecimalNumber\">\n    <xsd:restriction base=\"xsd:integer\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedDecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DecimalNumberOrPrecent\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedTwipsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedTwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PixelsMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PixelsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HpsMeasure\">\n    <xsd:union memberTypes=\"s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_HpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedHpsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedHpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedHpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTime\">\n    <xsd:restriction base=\"xsd:dateTime\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_MacroName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"33\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MacroName\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MacroName\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EighthPointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextScale\">\n    <xsd:union memberTypes=\"ST_TextScalePercent ST_TextScaleDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(600|([0-5]?[0-9]?[0-9]))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScaleDecimal\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"600\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextScale\">\n    <xsd:attribute name=\"val\" type=\"ST_TextScale\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HighlightColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkYellow\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Highlight\">\n    <xsd:attribute name=\"val\" type=\"ST_HighlightColor\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HexColorAuto\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColor\">\n    <xsd:union memberTypes=\"ST_HexColorAuto s:ST_HexColorRGB\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"val\" type=\"ST_HexColor\" use=\"required\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lang\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guid\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Guid\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Underline\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashedHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dashDotDotHeavy\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDouble\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Underline\">\n    <xsd:attribute name=\"val\" type=\"ST_Underline\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextEffect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blinkBackground\"/>\n      <xsd:enumeration value=\"lights\"/>\n      <xsd:enumeration value=\"antsBlack\"/>\n      <xsd:enumeration value=\"antsRed\"/>\n      <xsd:enumeration value=\"shimmer\"/>\n      <xsd:enumeration value=\"sparkle\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextEffect\">\n    <xsd:attribute name=\"val\" type=\"ST_TextEffect\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Border\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmallGap\"/>\n      <xsd:enumeration value=\"thickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickMediumGap\"/>\n      <xsd:enumeration value=\"thickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickLargeGap\"/>\n      <xsd:enumeration value=\"thickThinLargeGap\"/>\n      <xsd:enumeration value=\"thinThickThinLargeGap\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashSmallGap\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"outset\"/>\n      <xsd:enumeration value=\"inset\"/>\n      <xsd:enumeration value=\"apples\"/>\n      <xsd:enumeration value=\"archedScallops\"/>\n      <xsd:enumeration value=\"babyPacifier\"/>\n      <xsd:enumeration value=\"babyRattle\"/>\n      <xsd:enumeration value=\"balloons3Colors\"/>\n      <xsd:enumeration value=\"balloonsHotAir\"/>\n      <xsd:enumeration value=\"basicBlackDashes\"/>\n      <xsd:enumeration value=\"basicBlackDots\"/>\n      <xsd:enumeration value=\"basicBlackSquares\"/>\n      <xsd:enumeration value=\"basicThinLines\"/>\n      <xsd:enumeration value=\"basicWhiteDashes\"/>\n      <xsd:enumeration value=\"basicWhiteDots\"/>\n      <xsd:enumeration value=\"basicWhiteSquares\"/>\n      <xsd:enumeration value=\"basicWideInline\"/>\n      <xsd:enumeration value=\"basicWideMidline\"/>\n      <xsd:enumeration value=\"basicWideOutline\"/>\n      <xsd:enumeration value=\"bats\"/>\n      <xsd:enumeration value=\"birds\"/>\n      <xsd:enumeration value=\"birdsFlight\"/>\n      <xsd:enumeration value=\"cabins\"/>\n      <xsd:enumeration value=\"cakeSlice\"/>\n      <xsd:enumeration value=\"candyCorn\"/>\n      <xsd:enumeration value=\"celticKnotwork\"/>\n      <xsd:enumeration value=\"certificateBanner\"/>\n      <xsd:enumeration value=\"chainLink\"/>\n      <xsd:enumeration value=\"champagneBottle\"/>\n      <xsd:enumeration value=\"checkedBarBlack\"/>\n      <xsd:enumeration value=\"checkedBarColor\"/>\n      <xsd:enumeration value=\"checkered\"/>\n      <xsd:enumeration value=\"christmasTree\"/>\n      <xsd:enumeration value=\"circlesLines\"/>\n      <xsd:enumeration value=\"circlesRectangles\"/>\n      <xsd:enumeration value=\"classicalWave\"/>\n      <xsd:enumeration value=\"clocks\"/>\n      <xsd:enumeration value=\"compass\"/>\n      <xsd:enumeration value=\"confetti\"/>\n      <xsd:enumeration value=\"confettiGrays\"/>\n      <xsd:enumeration value=\"confettiOutline\"/>\n      <xsd:enumeration value=\"confettiStreamers\"/>\n      <xsd:enumeration value=\"confettiWhite\"/>\n      <xsd:enumeration value=\"cornerTriangles\"/>\n      <xsd:enumeration value=\"couponCutoutDashes\"/>\n      <xsd:enumeration value=\"couponCutoutDots\"/>\n      <xsd:enumeration value=\"crazyMaze\"/>\n      <xsd:enumeration value=\"creaturesButterfly\"/>\n      <xsd:enumeration value=\"creaturesFish\"/>\n      <xsd:enumeration value=\"creaturesInsects\"/>\n      <xsd:enumeration value=\"creaturesLadyBug\"/>\n      <xsd:enumeration value=\"crossStitch\"/>\n      <xsd:enumeration value=\"cup\"/>\n      <xsd:enumeration value=\"decoArch\"/>\n      <xsd:enumeration value=\"decoArchColor\"/>\n      <xsd:enumeration value=\"decoBlocks\"/>\n      <xsd:enumeration value=\"diamondsGray\"/>\n      <xsd:enumeration value=\"doubleD\"/>\n      <xsd:enumeration value=\"doubleDiamonds\"/>\n      <xsd:enumeration value=\"earth1\"/>\n      <xsd:enumeration value=\"earth2\"/>\n      <xsd:enumeration value=\"earth3\"/>\n      <xsd:enumeration value=\"eclipsingSquares1\"/>\n      <xsd:enumeration value=\"eclipsingSquares2\"/>\n      <xsd:enumeration value=\"eggsBlack\"/>\n      <xsd:enumeration value=\"fans\"/>\n      <xsd:enumeration value=\"film\"/>\n      <xsd:enumeration value=\"firecrackers\"/>\n      <xsd:enumeration value=\"flowersBlockPrint\"/>\n      <xsd:enumeration value=\"flowersDaisies\"/>\n      <xsd:enumeration value=\"flowersModern1\"/>\n      <xsd:enumeration value=\"flowersModern2\"/>\n      <xsd:enumeration value=\"flowersPansy\"/>\n      <xsd:enumeration value=\"flowersRedRose\"/>\n      <xsd:enumeration value=\"flowersRoses\"/>\n      <xsd:enumeration value=\"flowersTeacup\"/>\n      <xsd:enumeration value=\"flowersTiny\"/>\n      <xsd:enumeration value=\"gems\"/>\n      <xsd:enumeration value=\"gingerbreadMan\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"handmade1\"/>\n      <xsd:enumeration value=\"handmade2\"/>\n      <xsd:enumeration value=\"heartBalloon\"/>\n      <xsd:enumeration value=\"heartGray\"/>\n      <xsd:enumeration value=\"hearts\"/>\n      <xsd:enumeration value=\"heebieJeebies\"/>\n      <xsd:enumeration value=\"holly\"/>\n      <xsd:enumeration value=\"houseFunky\"/>\n      <xsd:enumeration value=\"hypnotic\"/>\n      <xsd:enumeration value=\"iceCreamCones\"/>\n      <xsd:enumeration value=\"lightBulb\"/>\n      <xsd:enumeration value=\"lightning1\"/>\n      <xsd:enumeration value=\"lightning2\"/>\n      <xsd:enumeration value=\"mapPins\"/>\n      <xsd:enumeration value=\"mapleLeaf\"/>\n      <xsd:enumeration value=\"mapleMuffins\"/>\n      <xsd:enumeration value=\"marquee\"/>\n      <xsd:enumeration value=\"marqueeToothed\"/>\n      <xsd:enumeration value=\"moons\"/>\n      <xsd:enumeration value=\"mosaic\"/>\n      <xsd:enumeration value=\"musicNotes\"/>\n      <xsd:enumeration value=\"northwest\"/>\n      <xsd:enumeration value=\"ovals\"/>\n      <xsd:enumeration value=\"packages\"/>\n      <xsd:enumeration value=\"palmsBlack\"/>\n      <xsd:enumeration value=\"palmsColor\"/>\n      <xsd:enumeration value=\"paperClips\"/>\n      <xsd:enumeration value=\"papyrus\"/>\n      <xsd:enumeration value=\"partyFavor\"/>\n      <xsd:enumeration value=\"partyGlass\"/>\n      <xsd:enumeration value=\"pencils\"/>\n      <xsd:enumeration value=\"people\"/>\n      <xsd:enumeration value=\"peopleWaving\"/>\n      <xsd:enumeration value=\"peopleHats\"/>\n      <xsd:enumeration value=\"poinsettias\"/>\n      <xsd:enumeration value=\"postageStamp\"/>\n      <xsd:enumeration value=\"pumpkin1\"/>\n      <xsd:enumeration value=\"pushPinNote2\"/>\n      <xsd:enumeration value=\"pushPinNote1\"/>\n      <xsd:enumeration value=\"pyramids\"/>\n      <xsd:enumeration value=\"pyramidsAbove\"/>\n      <xsd:enumeration value=\"quadrants\"/>\n      <xsd:enumeration value=\"rings\"/>\n      <xsd:enumeration value=\"safari\"/>\n      <xsd:enumeration value=\"sawtooth\"/>\n      <xsd:enumeration value=\"sawtoothGray\"/>\n      <xsd:enumeration value=\"scaredCat\"/>\n      <xsd:enumeration value=\"seattle\"/>\n      <xsd:enumeration value=\"shadowedSquares\"/>\n      <xsd:enumeration value=\"sharksTeeth\"/>\n      <xsd:enumeration value=\"shorebirdTracks\"/>\n      <xsd:enumeration value=\"skyrocket\"/>\n      <xsd:enumeration value=\"snowflakeFancy\"/>\n      <xsd:enumeration value=\"snowflakes\"/>\n      <xsd:enumeration value=\"sombrero\"/>\n      <xsd:enumeration value=\"southwest\"/>\n      <xsd:enumeration value=\"stars\"/>\n      <xsd:enumeration value=\"starsTop\"/>\n      <xsd:enumeration value=\"stars3d\"/>\n      <xsd:enumeration value=\"starsBlack\"/>\n      <xsd:enumeration value=\"starsShadowed\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"swirligig\"/>\n      <xsd:enumeration value=\"tornPaper\"/>\n      <xsd:enumeration value=\"tornPaperBlack\"/>\n      <xsd:enumeration value=\"trees\"/>\n      <xsd:enumeration value=\"triangleParty\"/>\n      <xsd:enumeration value=\"triangles\"/>\n      <xsd:enumeration value=\"triangle1\"/>\n      <xsd:enumeration value=\"triangle2\"/>\n      <xsd:enumeration value=\"triangleCircle1\"/>\n      <xsd:enumeration value=\"triangleCircle2\"/>\n      <xsd:enumeration value=\"shapes1\"/>\n      <xsd:enumeration value=\"shapes2\"/>\n      <xsd:enumeration value=\"twistedLines1\"/>\n      <xsd:enumeration value=\"twistedLines2\"/>\n      <xsd:enumeration value=\"vine\"/>\n      <xsd:enumeration value=\"waveline\"/>\n      <xsd:enumeration value=\"weavingAngles\"/>\n      <xsd:enumeration value=\"weavingBraid\"/>\n      <xsd:enumeration value=\"weavingRibbon\"/>\n      <xsd:enumeration value=\"weavingStrips\"/>\n      <xsd:enumeration value=\"whiteFlowers\"/>\n      <xsd:enumeration value=\"woodwork\"/>\n      <xsd:enumeration value=\"xIllusions\"/>\n      <xsd:enumeration value=\"zanyTriangles\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n      <xsd:enumeration value=\"zigZagStitch\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"val\" type=\"ST_Border\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_EighthPointMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"ST_PointMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"shadow\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"frame\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shd\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"horzStripe\"/>\n      <xsd:enumeration value=\"vertStripe\"/>\n      <xsd:enumeration value=\"reverseDiagStripe\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"horzCross\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"thinHorzStripe\"/>\n      <xsd:enumeration value=\"thinVertStripe\"/>\n      <xsd:enumeration value=\"thinReverseDiagStripe\"/>\n      <xsd:enumeration value=\"thinDiagStripe\"/>\n      <xsd:enumeration value=\"thinHorzCross\"/>\n      <xsd:enumeration value=\"thinDiagCross\"/>\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct12\"/>\n      <xsd:enumeration value=\"pct15\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct35\"/>\n      <xsd:enumeration value=\"pct37\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct45\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct55\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct62\"/>\n      <xsd:enumeration value=\"pct65\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct85\"/>\n      <xsd:enumeration value=\"pct87\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"pct95\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shd\">\n    <xsd:attribute name=\"val\" type=\"ST_Shd\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFill\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignRun\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FitText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Em\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"comma\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"underDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Em\">\n    <xsd:attribute name=\"val\" type=\"ST_Em\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Language\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"bidi\" type=\"s:ST_Lang\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CombineBrackets\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"curly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EastAsianLayout\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"combine\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"combineBrackets\" type=\"ST_CombineBrackets\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"vertCompress\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HeightRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Wrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"notBeside\"/>\n      <xsd:enumeration value=\"around\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DropCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"drop\"/>\n      <xsd:enumeration value=\"margin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FramePr\">\n    <xsd:attribute name=\"dropCap\" type=\"ST_DropCap\" use=\"optional\"/>\n    <xsd:attribute name=\"lines\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"vSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_Wrap\" use=\"optional\"/>\n    <xsd:attribute name=\"hAnchor\" type=\"ST_HAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"vAnchor\" type=\"ST_VAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"x\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"xAlign\" type=\"s:ST_XAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"y\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"yAlign\" type=\"s:ST_YAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorLock\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TabJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TabTlc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TabStop\">\n    <xsd:attribute name=\"val\" type=\"ST_TabJc\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_TabTlc\" use=\"optional\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LineSpacingRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Spacing\">\n    <xsd:attribute name=\"before\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"after\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"line\" type=\"ST_SignedTwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"lineRule\" type=\"ST_LineSpacingRule\" use=\"optional\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ind\">\n    <xsd:attribute name=\"start\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"startChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"end\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"endChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"left\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"leftChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"right\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"rightChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"hanging\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLine\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLineChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"mediumKashida\"/>\n      <xsd:enumeration value=\"distribute\"/>\n      <xsd:enumeration value=\"numTab\"/>\n      <xsd:enumeration value=\"highKashida\"/>\n      <xsd:enumeration value=\"lowKashida\"/>\n      <xsd:enumeration value=\"thaiDistribute\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_JcTable\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"start\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Jc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_JcTable\">\n    <xsd:attribute name=\"val\" type=\"ST_JcTable\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_View\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"outline\"/>\n      <xsd:enumeration value=\"masterPages\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"web\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_View\">\n    <xsd:attribute name=\"val\" type=\"ST_View\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Zoom\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fullPage\"/>\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"textFit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Zoom\">\n    <xsd:attribute name=\"val\" type=\"ST_Zoom\" use=\"optional\"/>\n    <xsd:attribute name=\"percent\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WritingStyle\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"vendorID\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"dllVersion\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"nlCheck\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"checkStyle\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"appName\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Proof\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clean\"/>\n      <xsd:enumeration value=\"dirty\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Proof\">\n    <xsd:attribute name=\"spelling\" type=\"ST_Proof\" use=\"optional\"/>\n    <xsd:attribute name=\"grammar\" type=\"ST_Proof\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocType\">\n    <xsd:attribute name=\"val\" type=\"ST_DocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocProtect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"readOnly\"/>\n      <xsd:enumeration value=\"comments\"/>\n      <xsd:enumeration value=\"trackedChanges\"/>\n      <xsd:enumeration value=\"forms\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Password\">\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_TransitionalPassword\">\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptSpinCount\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hash\" type=\"xsd:base64Binary\"/>\n    <xsd:attribute name=\"salt\" type=\"xsd:base64Binary\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_DocProtect\">\n    <xsd:attribute name=\"edit\" type=\"ST_DocProtect\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"enforcement\" type=\"s:ST_OnOff\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDocType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"catalog\"/>\n      <xsd:enumeration value=\"envelopes\"/>\n      <xsd:enumeration value=\"mailingLabels\"/>\n      <xsd:enumeration value=\"formLetters\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDocType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDataType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDest\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newDocument\"/>\n      <xsd:enumeration value=\"printer\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDest\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDest\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeOdsoFMDFieldType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"dbColumn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeOdsoFMDFieldType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeOdsoFMDFieldType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangesView\">\n    <xsd:attribute name=\"markup\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"comments\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"insDel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"inkAnnotations\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextDirection\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tb\"/>\n      <xsd:enumeration value=\"rl\"/>\n      <xsd:enumeration value=\"lr\"/>\n      <xsd:enumeration value=\"tbV\"/>\n      <xsd:enumeration value=\"rlV\"/>\n      <xsd:enumeration value=\"lrV\"/>\n      <xsd:enumeration value=\"btLr\"/>\n      <xsd:enumeration value=\"lrTb\"/>\n      <xsd:enumeration value=\"lrTbV\"/>\n      <xsd:enumeration value=\"tbLrV\"/>\n      <xsd:enumeration value=\"tbRl\"/>\n      <xsd:enumeration value=\"tbRlV\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextDirection\">\n    <xsd:attribute name=\"val\" type=\"ST_TextDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextAlignment\">\n    <xsd:attribute name=\"val\" type=\"ST_TextAlignment\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DisplacedByCustomXml\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"next\"/>\n      <xsd:enumeration value=\"prev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnnotationVMerge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cont\"/>\n      <xsd:enumeration value=\"rest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Markup\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellMergeTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"vMerge\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n        <xsd:attribute name=\"vMergeOrig\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MarkupRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookmarkRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_MarkupRange\">\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_BookmarkRange\">\n        <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MoveBookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Bookmark\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"initials\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeNumbering\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"original\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrEx\" type=\"CT_TblPrExBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPr\" type=\"CT_TcPrInner\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"trPr\" type=\"CT_TrPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGrid\" type=\"CT_TblGridBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPrBase\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"pPr\" type=\"CT_PPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_RPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RunTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:group ref=\"EG_ContentRunContent\"/>\n          <xsd:group ref=\"m:EG_OMathMathElements\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContentMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_PContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_ContentRunContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_PContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ContentRunContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_CellMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"cellIns\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellDel\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellMerge\" type=\"CT_CellMergeTrackChange\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RangeMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"bookmarkStart\" type=\"CT_Bookmark\"/>\n      <xsd:element name=\"bookmarkEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveFromRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveFromRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveToRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveToRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeStart\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"customXmlInsRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlInsRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlDelRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlDelRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveFromRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveFromRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveToRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveToRangeEnd\" type=\"CT_Markup\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_NumPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ilvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"between\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bar\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tabs\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TabStop\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextboxTightWrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"allLines\"/>\n      <xsd:enumeration value=\"firstAndLastLine\"/>\n      <xsd:enumeration value=\"firstLineOnly\"/>\n      <xsd:enumeration value=\"lastLineOnly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextboxTightWrap\">\n    <xsd:attribute name=\"val\" type=\"ST_TextboxTightWrap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepNext\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageBreakBefore\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"framePr\" type=\"CT_FramePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"widowControl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"numPr\" type=\"CT_NumPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressLineNumbers\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pBdr\" type=\"CT_PBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabs\" type=\"CT_Tabs\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressAutoHyphens\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wordWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"overflowPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"topLinePunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDE\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDN\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustRightInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacing\" type=\"CT_Spacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"ind\" type=\"CT_Ind\" minOccurs=\"0\"/>\n      <xsd:element name=\"contextualSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorIndents\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressOverlap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"jc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"textAlignment\" type=\"CT_TextAlignment\" minOccurs=\"0\"/>\n      <xsd:element name=\"textboxTightWrap\" type=\"CT_TextboxTightWrap\" minOccurs=\"0\"/>\n      <xsd:element name=\"outlineLvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrGeneral\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeid\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Object\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"control\" type=\"CT_Control\"/>\n        <xsd:element name=\"objectLink\" type=\"CT_ObjectLink\"/>\n        <xsd:element name=\"objectEmbed\" type=\"CT_ObjectEmbed\"/>\n        <xsd:element name=\"movie\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"dxaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"dyaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"movie\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectEmbed\">\n    <xsd:attribute name=\"drawAspect\" type=\"ST_ObjectDrawAspect\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldCodes\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ObjectLink\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_ObjectEmbed\">\n        <xsd:attribute name=\"updateMode\" type=\"ST_ObjectUpdateMode\" use=\"required\"/>\n        <xsd:attribute name=\"lockedField\" type=\"s:ST_OnOff\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"onCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"wp:anchor\" minOccurs=\"0\"/>\n      <xsd:element ref=\"wp:inline\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SimpleField\">\n    <xsd:sequence>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"instr\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FldCharType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"separate\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InfoTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"autoText\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFHelpTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"256\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFStatusTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"140\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"65\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"regular\"/>\n      <xsd:enumeration value=\"number\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"currentTime\"/>\n      <xsd:enumeration value=\"currentDate\"/>\n      <xsd:enumeration value=\"calculated\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FFTextType\">\n    <xsd:attribute name=\"val\" type=\"ST_FFTextType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFName\">\n    <xsd:attribute name=\"val\" type=\"ST_FFName\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FldChar\">\n    <xsd:choice>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ffData\" type=\"CT_FFData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fldCharType\" type=\"ST_FldCharType\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"docLocation\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"history\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFData\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FFName\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"enabled\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"calcOnExit\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"entryMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"exitMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"helpText\" type=\"CT_FFHelpText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"statusText\" type=\"CT_FFStatusText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"checkBox\" type=\"CT_FFCheckBox\"/>\n        <xsd:element name=\"ddList\" type=\"CT_FFDDList\"/>\n        <xsd:element name=\"textInput\" type=\"CT_FFTextInput\"/>\n      </xsd:choice>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFHelpText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFHelpTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFStatusText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFStatusTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFCheckBox\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"size\" type=\"CT_HpsMeasure\"/>\n        <xsd:element name=\"sizeAuto\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"default\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFDDList\">\n    <xsd:sequence>\n      <xsd:element name=\"result\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"listEntry\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFTextInput\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FFTextType\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxLength\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"format\" type=\"CT_String\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SectionMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nextPage\"/>\n      <xsd:enumeration value=\"nextColumn\"/>\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"evenPage\"/>\n      <xsd:enumeration value=\"oddPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SectType\">\n    <xsd:attribute name=\"val\" type=\"ST_SectionMark\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PaperSource\">\n    <xsd:attribute name=\"first\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"other\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumberFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"upperRoman\"/>\n      <xsd:enumeration value=\"lowerRoman\"/>\n      <xsd:enumeration value=\"upperLetter\"/>\n      <xsd:enumeration value=\"lowerLetter\"/>\n      <xsd:enumeration value=\"ordinal\"/>\n      <xsd:enumeration value=\"cardinalText\"/>\n      <xsd:enumeration value=\"ordinalText\"/>\n      <xsd:enumeration value=\"hex\"/>\n      <xsd:enumeration value=\"chicago\"/>\n      <xsd:enumeration value=\"ideographDigital\"/>\n      <xsd:enumeration value=\"japaneseCounting\"/>\n      <xsd:enumeration value=\"aiueo\"/>\n      <xsd:enumeration value=\"iroha\"/>\n      <xsd:enumeration value=\"decimalFullWidth\"/>\n      <xsd:enumeration value=\"decimalHalfWidth\"/>\n      <xsd:enumeration value=\"japaneseLegal\"/>\n      <xsd:enumeration value=\"japaneseDigitalTenThousand\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircle\"/>\n      <xsd:enumeration value=\"decimalFullWidth2\"/>\n      <xsd:enumeration value=\"aiueoFullWidth\"/>\n      <xsd:enumeration value=\"irohaFullWidth\"/>\n      <xsd:enumeration value=\"decimalZero\"/>\n      <xsd:enumeration value=\"bullet\"/>\n      <xsd:enumeration value=\"ganada\"/>\n      <xsd:enumeration value=\"chosung\"/>\n      <xsd:enumeration value=\"decimalEnclosedFullstop\"/>\n      <xsd:enumeration value=\"decimalEnclosedParen\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircleChinese\"/>\n      <xsd:enumeration value=\"ideographEnclosedCircle\"/>\n      <xsd:enumeration value=\"ideographTraditional\"/>\n      <xsd:enumeration value=\"ideographZodiac\"/>\n      <xsd:enumeration value=\"ideographZodiacTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCounting\"/>\n      <xsd:enumeration value=\"ideographLegalTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCountingThousand\"/>\n      <xsd:enumeration value=\"taiwaneseDigital\"/>\n      <xsd:enumeration value=\"chineseCounting\"/>\n      <xsd:enumeration value=\"chineseLegalSimplified\"/>\n      <xsd:enumeration value=\"chineseCountingThousand\"/>\n      <xsd:enumeration value=\"koreanDigital\"/>\n      <xsd:enumeration value=\"koreanCounting\"/>\n      <xsd:enumeration value=\"koreanLegal\"/>\n      <xsd:enumeration value=\"koreanDigital2\"/>\n      <xsd:enumeration value=\"vietnameseCounting\"/>\n      <xsd:enumeration value=\"russianLower\"/>\n      <xsd:enumeration value=\"russianUpper\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"numberInDash\"/>\n      <xsd:enumeration value=\"hebrew1\"/>\n      <xsd:enumeration value=\"hebrew2\"/>\n      <xsd:enumeration value=\"arabicAlpha\"/>\n      <xsd:enumeration value=\"arabicAbjad\"/>\n      <xsd:enumeration value=\"hindiVowels\"/>\n      <xsd:enumeration value=\"hindiConsonants\"/>\n      <xsd:enumeration value=\"hindiNumbers\"/>\n      <xsd:enumeration value=\"hindiCounting\"/>\n      <xsd:enumeration value=\"thaiLetters\"/>\n      <xsd:enumeration value=\"thaiNumbers\"/>\n      <xsd:enumeration value=\"thaiCounting\"/>\n      <xsd:enumeration value=\"bahtText\"/>\n      <xsd:enumeration value=\"dollarText\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageSz\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_PageOrientation\" use=\"optional\"/>\n    <xsd:attribute name=\"code\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMar\">\n    <xsd:attribute name=\"top\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"left\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"gutter\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageBorderZOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"front\"/>\n      <xsd:enumeration value=\"back\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderDisplay\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"allPages\"/>\n      <xsd:enumeration value=\"firstPage\"/>\n      <xsd:enumeration value=\"notFirstPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderOffset\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TopPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BottomPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zOrder\" type=\"ST_PageBorderZOrder\" use=\"optional\" default=\"front\"/>\n    <xsd:attribute name=\"display\" type=\"ST_PageBorderDisplay\" use=\"optional\"/>\n    <xsd:attribute name=\"offsetFrom\" type=\"ST_PageBorderOffset\" use=\"optional\" default=\"text\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Border\">\n        <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BottomPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:bottomLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:bottomRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TopPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:topLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:topRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ChapterSep\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"period\"/>\n      <xsd:enumeration value=\"colon\"/>\n      <xsd:enumeration value=\"emDash\"/>\n      <xsd:enumeration value=\"enDash\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineNumberRestart\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newPage\"/>\n      <xsd:enumeration value=\"newSection\"/>\n      <xsd:enumeration value=\"continuous\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineNumber\">\n    <xsd:attribute name=\"countBy\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"distance\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_LineNumberRestart\" use=\"optional\" default=\"newPage\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageNumber\">\n    <xsd:attribute name=\"fmt\" type=\"ST_NumberFormat\" use=\"optional\" default=\"decimal\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapStyle\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapSep\" type=\"ST_ChapterSep\" use=\"optional\" default=\"hyphen\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Column\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Columns\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"col\" type=\"CT_Column\" maxOccurs=\"45\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"equalWidth\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"720\"/>\n    <xsd:attribute name=\"num\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"sep\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VerticalJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"bottom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VerticalJc\">\n    <xsd:attribute name=\"val\" type=\"ST_VerticalJc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocGrid\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"lines\"/>\n      <xsd:enumeration value=\"linesAndChars\"/>\n      <xsd:enumeration value=\"snapToChars\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocGrid\">\n    <xsd:attribute name=\"type\" type=\"ST_DocGrid\"/>\n    <xsd:attribute name=\"linePitch\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"charSpace\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HdrFtr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"even\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"first\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FtnEdn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"separator\"/>\n      <xsd:enumeration value=\"continuationSeparator\"/>\n      <xsd:enumeration value=\"continuationNotice\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HdrFtrRef\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"type\" type=\"ST_HdrFtr\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_HdrFtrReferences\">\n    <xsd:choice>\n      <xsd:element name=\"headerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n      <xsd:element name=\"footerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_HdrFtr\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SectPrContents\">\n    <xsd:sequence>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_SectType\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgSz\" type=\"CT_PageSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgMar\" type=\"CT_PageMar\" minOccurs=\"0\"/>\n      <xsd:element name=\"paperSrc\" type=\"CT_PaperSource\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgBorders\" type=\"CT_PageBorders\" minOccurs=\"0\"/>\n      <xsd:element name=\"lnNumType\" type=\"CT_LineNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNumType\" type=\"CT_PageNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cols\" type=\"CT_Columns\" minOccurs=\"0\"/>\n      <xsd:element name=\"formProt\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"noEndnote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"titlePg\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rtlGutter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"docGrid\" type=\"CT_DocGrid\" minOccurs=\"0\"/>\n      <xsd:element name=\"printerSettings\" type=\"CT_Rel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_SectPrAttributes\">\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidSect\" type=\"ST_LongHexNumber\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_SectPrBase\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_HdrFtrReferences\" minOccurs=\"0\" maxOccurs=\"6\"/>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n      <xsd:element name=\"sectPrChange\" type=\"CT_SectPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BrType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"textWrapping\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BrClear\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Br\">\n    <xsd:attribute name=\"type\" type=\"ST_BrType\" use=\"optional\"/>\n    <xsd:attribute name=\"clear\" type=\"ST_BrClear\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PTabAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabRelativeTo\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"indent\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabLeader\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PTab\">\n    <xsd:attribute name=\"alignment\" type=\"ST_PTabAlignment\" use=\"required\"/>\n    <xsd:attribute name=\"relativeTo\" type=\"ST_PTabRelativeTo\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_PTabLeader\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sym\">\n    <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"char\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ProofErr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"spellStart\"/>\n      <xsd:enumeration value=\"spellEnd\"/>\n      <xsd:enumeration value=\"gramStart\"/>\n      <xsd:enumeration value=\"gramEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ProofErr\">\n    <xsd:attribute name=\"type\" type=\"ST_ProofErr\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdGrp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"everyone\"/>\n      <xsd:enumeration value=\"administrators\"/>\n      <xsd:enumeration value=\"contributors\"/>\n      <xsd:enumeration value=\"editors\"/>\n      <xsd:enumeration value=\"owners\"/>\n      <xsd:enumeration value=\"current\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perm\">\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PermStart\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Perm\">\n        <xsd:attribute name=\"edGrp\" type=\"ST_EdGrp\" use=\"optional\"/>\n        <xsd:attribute name=\"ed\" type=\"s:ST_String\" use=\"optional\"/>\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RunInnerContent\">\n    <xsd:choice>\n      <xsd:element name=\"br\" type=\"CT_Br\"/>\n      <xsd:element name=\"t\" type=\"CT_Text\"/>\n      <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      <xsd:element name=\"delText\" type=\"CT_Text\"/>\n      <xsd:element name=\"instrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"delInstrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"noBreakHyphen\" type=\"CT_Empty\"/>\n      <xsd:element name=\"softHyphen\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"annotationRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"separator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"continuationSeparator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"sym\" type=\"CT_Sym\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNum\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"cr\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"tab\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"object\" type=\"CT_Object\"/>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"fldChar\" type=\"CT_FldChar\"/>\n      <xsd:element name=\"ruby\" type=\"CT_Ruby\"/>\n      <xsd:element name=\"footnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"endnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"commentReference\" type=\"CT_Markup\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"ptab\" type=\"CT_PTab\" minOccurs=\"0\"/>\n      <xsd:element name=\"lastRenderedPageBreak\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RunInnerContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Hint\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"eastAsia\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Theme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"majorEastAsia\"/>\n      <xsd:enumeration value=\"majorBidi\"/>\n      <xsd:enumeration value=\"majorAscii\"/>\n      <xsd:enumeration value=\"majorHAnsi\"/>\n      <xsd:enumeration value=\"minorEastAsia\"/>\n      <xsd:enumeration value=\"minorBidi\"/>\n      <xsd:enumeration value=\"minorAscii\"/>\n      <xsd:enumeration value=\"minorHAnsi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:attribute name=\"hint\" type=\"ST_Hint\"/>\n    <xsd:attribute name=\"ascii\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hAnsi\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cs\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"asciiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"hAnsiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"eastAsiaTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"cstheme\" type=\"ST_Theme\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPrBase\">\n    <xsd:choice>\n      <xsd:element name=\"rStyle\" type=\"CT_String\"/>\n      <xsd:element name=\"rFonts\" type=\"CT_Fonts\"/>\n      <xsd:element name=\"b\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"bCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"i\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"iCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"caps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"smallCaps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"strike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"dstrike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"outline\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"shadow\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"emboss\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"imprint\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"noProof\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"vanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"webHidden\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\"/>\n      <xsd:element name=\"spacing\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"w\" type=\"CT_TextScale\"/>\n      <xsd:element name=\"kern\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"position\" type=\"CT_SignedHpsMeasure\"/>\n      <xsd:element name=\"sz\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"szCs\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Highlight\"/>\n      <xsd:element name=\"u\" type=\"CT_Underline\"/>\n      <xsd:element name=\"effect\" type=\"CT_TextEffect\"/>\n      <xsd:element name=\"bdr\" type=\"CT_Border\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\"/>\n      <xsd:element name=\"fitText\" type=\"CT_FitText\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignRun\"/>\n      <xsd:element name=\"rtl\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"cs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"em\" type=\"CT_Em\"/>\n      <xsd:element name=\"lang\" type=\"CT_Language\"/>\n      <xsd:element name=\"eastAsianLayout\" type=\"CT_EastAsianLayout\"/>\n      <xsd:element name=\"specVanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OnOff\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrContent\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_RPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrContent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_RPr\"/>\n      <xsd:element name=\"ins\" type=\"CT_MathCtrlIns\"/>\n      <xsd:element name=\"del\" type=\"CT_MathCtrlDel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_MathCtrlIns\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"del\" type=\"CT_RPrChange\" minOccurs=\"1\"/>\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathCtrlDel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_ParaRPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ParaRPrTrackChanges\">\n    <xsd:sequence>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AltChunk\">\n    <xsd:sequence>\n      <xsd:element name=\"altChunkPr\" type=\"CT_AltChunkPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AltChunkPr\">\n    <xsd:sequence>\n      <xsd:element name=\"matchSrc\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RubyAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributeLetter\"/>\n      <xsd:enumeration value=\"distributeSpace\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"rightVertical\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RubyAlign\">\n    <xsd:attribute name=\"val\" type=\"ST_RubyAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RubyPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyAlign\" type=\"CT_RubyAlign\"/>\n      <xsd:element name=\"hps\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsRaise\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsBaseText\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\"/>\n      <xsd:element name=\"dirty\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RubyContent\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RubyContent\">\n    <xsd:group ref=\"EG_RubyContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ruby\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyPr\" type=\"CT_RubyPr\"/>\n      <xsd:element name=\"rt\" type=\"CT_RubyContent\"/>\n      <xsd:element name=\"rubyBase\" type=\"CT_RubyContent\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Lock\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sdtLocked\"/>\n      <xsd:enumeration value=\"contentLocked\"/>\n      <xsd:enumeration value=\"unlocked\"/>\n      <xsd:enumeration value=\"sdtContentLocked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attribute name=\"val\" type=\"ST_Lock\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtListItem\">\n    <xsd:attribute name=\"displayText\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"value\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SdtDateMappingType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"dateTime\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtDateMappingType\">\n    <xsd:attribute name=\"val\" type=\"ST_SdtDateMappingType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalendarType\">\n    <xsd:attribute name=\"val\" type=\"s:ST_CalendarType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDate\">\n    <xsd:sequence>\n      <xsd:element name=\"dateFormat\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"storeMappedDataAs\" type=\"CT_SdtDateMappingType\" minOccurs=\"0\"/>\n      <xsd:element name=\"calendar\" type=\"CT_CalendarType\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullDate\" type=\"ST_DateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtComboBox\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartGallery\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartCategory\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartUnique\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDropDownList\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"docPart\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtText\">\n    <xsd:attribute name=\"multiLine\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:attribute name=\"prefixMappings\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"storeItemID\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"alias\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tag\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"id\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lock\" type=\"CT_Lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"placeholder\" type=\"CT_Placeholder\" minOccurs=\"0\"/>\n      <xsd:element name=\"temporary\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showingPlcHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"equation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comboBox\" type=\"CT_SdtComboBox\"/>\n        <xsd:element name=\"date\" type=\"CT_SdtDate\"/>\n        <xsd:element name=\"docPartObj\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"docPartList\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"dropDownList\" type=\"CT_SdtDropDownList\"/>\n        <xsd:element name=\"picture\" type=\"CT_Empty\"/>\n        <xsd:element name=\"richText\" type=\"CT_Empty\"/>\n        <xsd:element name=\"text\" type=\"CT_SdtText\"/>\n        <xsd:element name=\"citation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"group\" type=\"CT_Empty\"/>\n        <xsd:element name=\"bibliography\" type=\"CT_Empty\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtEndPr\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRunContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:element name=\"dir\" type=\"CT_DirContentRun\"/>\n      <xsd:element name=\"bdo\" type=\"CT_BdoContentRun\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DirContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BdoContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ltr\"/>\n      <xsd:enumeration value=\"rtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentBlockContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlBlock\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtBlock\"/>\n      <xsd:element name=\"p\" type=\"CT_P\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tbl\" type=\"CT_Tbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentBlock\">\n    <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRowContent\">\n    <xsd:choice>\n      <xsd:element name=\"tr\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRow\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRow\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentRow\">\n    <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentCellContent\">\n    <xsd:choice>\n      <xsd:element name=\"tc\" type=\"CT_Tc\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlCell\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtCell\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentCell\">\n    <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentBlock\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRun\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRun\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtCell\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentCell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRow\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRow\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Attr\">\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRun\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagRun\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"placeholder\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRow\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:sequence>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContent\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentRunContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n      <xsd:element name=\"subDoc\" type=\"CT_Rel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_P\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidP\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidRDefault\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"pct\"/>\n      <xsd:enumeration value=\"dxa\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Height\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MeasurementOrPercent\">\n    <xsd:union memberTypes=\"ST_DecimalNumberOrPercent s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblWidth\">\n    <xsd:attribute name=\"w\" type=\"ST_MeasurementOrPercent\"/>\n    <xsd:attribute name=\"type\" type=\"ST_TblWidth\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridCol\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridBase\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TblGridCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGrid\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblGridBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGridChange\" type=\"CT_TblGridChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Merge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continue\"/>\n      <xsd:enumeration value=\"restart\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpan\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hMerge\" type=\"CT_HMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"vMerge\" type=\"CT_VMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcBorders\" type=\"CT_TcBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"noWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcMar\" type=\"CT_TcMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcFitText\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrInner\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPrChange\" type=\"CT_TcPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrInner\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrBase\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_CellMarkupElements\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tc\">\n    <xsd:sequence>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Cnf\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:length value=\"12\"/>\n      <xsd:pattern value=\"[01]*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cnf\">\n    <xsd:attribute name=\"val\" type=\"ST_Cnf\"/>\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowLastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowLastColumn\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrBase\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridBefore\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridAfter\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"wBefore\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wAfter\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cantSplit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"trHeight\" type=\"CT_Height\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"trPrChange\" type=\"CT_TrPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPrEx\" type=\"CT_TblPrEx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidTr\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblLayoutType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"autofit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblLayoutType\">\n    <xsd:attribute name=\"type\" type=\"ST_TblLayoutType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblOverlap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"overlap\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblOverlap\">\n    <xsd:attribute name=\"val\" type=\"ST_TblOverlap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPPr\">\n    <xsd:attribute name=\"leftFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"rightFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"topFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"bottomFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"vertAnchor\" type=\"ST_VAnchor\"/>\n    <xsd:attribute name=\"horzAnchor\" type=\"ST_HAnchor\"/>\n    <xsd:attribute name=\"tblpXSpec\" type=\"s:ST_XAlign\"/>\n    <xsd:attribute name=\"tblpX\" type=\"ST_SignedTwipsMeasure\"/>\n    <xsd:attribute name=\"tblpYSpec\" type=\"s:ST_YAlign\"/>\n    <xsd:attribute name=\"tblpY\" type=\"ST_SignedTwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblCellMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblpPr\" type=\"CT_TblPPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblOverlap\" type=\"CT_TblOverlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bidiVisual\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleRowBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleColBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCaption\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblDescription\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrChange\" type=\"CT_TblPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrEx\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrExBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrExChange\" type=\"CT_TblPrExChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tbl\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPr\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TblGrid\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblLook\">\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FtnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pageBottom\"/>\n      <xsd:enumeration value=\"beneathText\"/>\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FtnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_FtnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EdnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_EdnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"val\" type=\"ST_NumberFormat\" use=\"required\"/>\n    <xsd:attribute name=\"format\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RestartNumber\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"eachSect\"/>\n      <xsd:enumeration value=\"eachPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumRestart\">\n    <xsd:attribute name=\"val\" type=\"ST_RestartNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnRef\">\n    <xsd:attribute name=\"customMarkFollows\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnSepRef\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdn\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_FtnEdn\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FtnEdnNumProps\">\n    <xsd:sequence>\n      <xsd:element name=\"numStart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numRestart\" type=\"CT_NumRestart\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FtnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_FtnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_EdnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_FtnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"footnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_EdnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"endnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RecipientData\">\n    <xsd:sequence>\n      <xsd:element name=\"active\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"uniqueTag\" type=\"CT_Base64Binary\" minOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Base64Binary\">\n    <xsd:attribute name=\"val\" type=\"xsd:base64Binary\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Recipients\">\n    <xsd:sequence>\n      <xsd:element name=\"recipientData\" type=\"CT_RecipientData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"recipients\" type=\"CT_Recipients\"/>\n  <xsd:complexType name=\"CT_OdsoFieldMapData\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_MailMergeOdsoFMDFieldType\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mappedName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"dynamicAddress\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"database\"/>\n      <xsd:enumeration value=\"addressBook\"/>\n      <xsd:enumeration value=\"document1\"/>\n      <xsd:enumeration value=\"document2\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"native\"/>\n      <xsd:enumeration value=\"legacy\"/>\n      <xsd:enumeration value=\"master\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeSourceType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MailMergeSourceType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Odso\">\n    <xsd:sequence>\n      <xsd:element name=\"udl\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"table\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"src\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"colDelim\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_MailMergeSourceType\" minOccurs=\"0\"/>\n      <xsd:element name=\"fHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"fieldMapData\" type=\"CT_OdsoFieldMapData\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"recipientData\" type=\"CT_Rel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MailMerge\">\n    <xsd:sequence>\n      <xsd:element name=\"mainDocumentType\" type=\"CT_MailMergeDocType\" minOccurs=\"1\"/>\n      <xsd:element name=\"linkToQuery\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataType\" type=\"CT_MailMergeDataType\" minOccurs=\"1\"/>\n      <xsd:element name=\"connectString\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"query\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"headerSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressBlankLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"destination\" type=\"CT_MailMergeDest\" minOccurs=\"0\"/>\n      <xsd:element name=\"addressFieldName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailSubject\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailAsAttachment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"viewMergedData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeRecord\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"checkErrors\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"odso\" type=\"CT_Odso\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSz\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TargetScreenSz\">\n    <xsd:attribute name=\"val\" type=\"ST_TargetScreenSz\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Compat\">\n    <xsd:sequence>\n      <xsd:element name=\"useSingleBorderforContiguousCells\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpJustification\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noTabHangInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLeading\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spaceForUL\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noColumnBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"balanceSingleByteDoubleByteWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noExtraLineSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotLeaveBackslashAlone\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ulTrailSpace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotExpandShiftReturn\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacingInWholePoints\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lineWrapLikeWord6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printBodyTextBeforeHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printColBlack\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpSpaceWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showBreaksInFrames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subFontBySize\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressBottomSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpacingAtTopOfPage\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacingWP\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpBfAfterPgBrk\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"swapBordersFacingPages\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"convMailMergeEsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"truncateFontHeightsLikeWP6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mwSmallCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"usePrinterMetrics\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressParagraphBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wrapTrailSpaces\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shapeLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignTablesRowByRow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forgetLastTabAlignment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustLineHeightInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceLikeWord95\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noSpaceRaiseLower\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseHTMLParagraphAutoSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutRawTableWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutTableRowsApart\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord97LineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakWrappedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSnapToGridInCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"selectFldWithFirstOrLastChar\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"applyBreakingRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotWrapTextWithPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseEastAsianBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord2002TableStyleRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"growAutofit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useFELayout\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useNormalStyleForList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseIndentAsNumberingTabStop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAltKinsokuLineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowSpaceOfSameStyleInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressIndentation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutofitConstrainedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autofitToFirstFixedWidthCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"underlineTabInNumList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHangulFixedWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"splitPgBreakAndParaMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignCellWithSp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakConstrainedForcedTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignInTxbx\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAnsiKerningPairs\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"cachedColBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"compatSetting\" type=\"CT_CompatSetting\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CompatSetting\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVar\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVars\">\n    <xsd:sequence>\n      <xsd:element name=\"docVar\" type=\"CT_DocVar\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocRsids\">\n    <xsd:sequence>\n      <xsd:element name=\"rsidRoot\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CharacterSpacing\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doNotCompress\"/>\n      <xsd:enumeration value=\"compressPunctuation\"/>\n      <xsd:enumeration value=\"compressPunctuationAndJapaneseKana\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CharacterSpacing\">\n    <xsd:attribute name=\"val\" type=\"ST_CharacterSpacing\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SaveThroughXslt\">\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"solutionID\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"rPrDefault\" type=\"CT_RPrDefault\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPrDefault\" type=\"CT_PPrDefault\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WmlColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorSchemeMapping\">\n    <xsd:attribute name=\"bg1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"hyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"followedHyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReadingModeInkLockDown\">\n    <xsd:attribute name=\"actualPg\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"w\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"fontSz\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WriteProtection\">\n    <xsd:attribute name=\"recommended\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Settings\">\n    <xsd:sequence>\n      <xsd:element name=\"writeProtection\" type=\"CT_WriteProtection\" minOccurs=\"0\"/>\n      <xsd:element name=\"view\" type=\"CT_View\" minOccurs=\"0\"/>\n      <xsd:element name=\"zoom\" type=\"CT_Zoom\" minOccurs=\"0\"/>\n      <xsd:element name=\"removePersonalInformation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"removeDateAndTime\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDisplayPageBoundaries\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayBackgroundShape\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printPostScriptOverText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFractionalCharacterWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedTrueTypeFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedSystemFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSubsetFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorMargins\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignBordersAndEdges\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundFooter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"gutterAtTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideSpellingErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideGrammaticalErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeWritingStyle\" type=\"CT_WritingStyle\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"proofState\" type=\"CT_Proof\" minOccurs=\"0\"/>\n      <xsd:element name=\"formsDesign\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"attachedTemplate\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkStyles\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneFormatFilter\" type=\"CT_StylePaneFilter\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneSortMethod\" type=\"CT_StyleSort\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentType\" type=\"CT_DocType\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailMerge\" type=\"CT_MailMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"revisionView\" type=\"CT_TrackChangesView\" minOccurs=\"0\"/>\n      <xsd:element name=\"trackRevisions\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackMoves\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackFormatting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentProtection\" type=\"CT_DocProtect\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoFormatOverride\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockTheme\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockQFSet\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTabStop\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoHyphenation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"consecutiveHyphenLimit\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hyphenationZone\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotHyphenateCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showEnvelope\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"summaryLength\" type=\"CT_DecimalNumberOrPrecent\" minOccurs=\"0\"/>\n      <xsd:element name=\"clickAndTypeStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTableStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"evenAndOddHeaders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldRevPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrintingSheets\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHorizontalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayVerticalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseMarginsForDrawingGridOrigin\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotShadeFormData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noPunctuationKerning\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"characterSpacingControl\" type=\"CT_CharacterSpacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"printTwoOnOne\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strictFirstAndLastChars\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksAfter\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksBefore\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"savePreviewPicture\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotValidateAgainstSchema\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ignoreMixedContent\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysShowPlaceholderText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDemarcateInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveXmlDataOnly\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useXSLTWhenSaving\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveThroughXslt\" type=\"CT_SaveThroughXslt\" minOccurs=\"0\"/>\n      <xsd:element name=\"showXMLTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysMergeEmptyNamespace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"updateFields\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hdrShapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"compat\" type=\"CT_Compat\" minOccurs=\"0\"/>\n      <xsd:element name=\"docVars\" type=\"CT_DocVars\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsids\" type=\"CT_DocRsids\" minOccurs=\"0\"/>\n      <xsd:element ref=\"m:mathPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attachedSchema\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"themeFontLang\" type=\"CT_Language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrSchemeMapping\" type=\"CT_ColorSchemeMapping\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotIncludeSubdocsInStats\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutoCompressPictures\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forceUpgrade\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"captions\" type=\"CT_Captions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"readModeInkLockDown\" type=\"CT_ReadingModeInkLockDown\" minOccurs=\"0\"/>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"sl:schemaLibrary\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotEmbedSmartTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"decimalSymbol\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"listSeparator\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleSort\">\n    <xsd:attribute name=\"val\" type=\"ST_StyleSort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StylePaneFilter\">\n    <xsd:attribute name=\"allStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"customStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"latentStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"stylesInUse\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"headingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"numberingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"tableStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnRuns\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnParagraphs\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnNumbering\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnTables\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"clearFormatting\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"top3HeadingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"visibleStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"alternateStyleNames\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleSort\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"name\"/>\n      <xsd:enumeration value=\"priority\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"font\"/>\n      <xsd:enumeration value=\"basedOn\"/>\n      <xsd:enumeration value=\"type\"/>\n      <xsd:enumeration value=\"0000\"/>\n      <xsd:enumeration value=\"0001\"/>\n      <xsd:enumeration value=\"0002\"/>\n      <xsd:enumeration value=\"0003\"/>\n      <xsd:enumeration value=\"0004\"/>\n      <xsd:enumeration value=\"0005\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\"/>\n      <xsd:element name=\"divs\" type=\"CT_Divs\" minOccurs=\"0\"/>\n      <xsd:element name=\"encoding\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"optimizeForBrowser\" type=\"CT_OptimizeForBrowser\" minOccurs=\"0\"/>\n      <xsd:element name=\"relyOnVML\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowPNG\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotRelyOnCSS\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSaveAsSingleFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotOrganizeInFolder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseLongFileNames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pixelsPerInch\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"targetScreenSz\" type=\"CT_TargetScreenSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSmartTagsAsXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameScrollbar\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameScrollbar\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameScrollbar\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptimizeForBrowser\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_OnOff\">\n        <xsd:attribute name=\"target\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frame\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"longDesc\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"sourceFileName\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"marW\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"marH\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"scrollbar\" type=\"CT_FrameScrollbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"noResizeAllowed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkedToFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameLayout\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rows\"/>\n      <xsd:enumeration value=\"cols\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameLayout\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameLayout\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FramesetSplitbar\">\n    <xsd:sequence>\n      <xsd:element name=\"w\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBorder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"flatBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frameset\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"framesetSplitbar\" type=\"CT_FramesetSplitbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"frameLayout\" type=\"CT_FrameLayout\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xsd:element name=\"frame\" type=\"CT_Frame\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumPicBullet\">\n    <xsd:choice>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"numPicBulletId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LevelSuffix\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tab\"/>\n      <xsd:enumeration value=\"space\"/>\n      <xsd:enumeration value=\"nothing\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LevelSuffix\">\n    <xsd:attribute name=\"val\" type=\"ST_LevelSuffix\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"null\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LvlLegacy\">\n    <xsd:attribute name=\"legacy\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"legacySpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"legacyIndent\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlRestart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"isLgl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suff\" type=\"CT_LevelSuffix\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlText\" type=\"CT_LevelText\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlPicBulletId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"legacy\" type=\"CT_LvlLegacy\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlJc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n    <xsd:attribute name=\"tplc\" type=\"ST_LongHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"tentative\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MultiLevelType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"singleLevel\"/>\n      <xsd:enumeration value=\"multilevel\"/>\n      <xsd:enumeration value=\"hybridMultilevel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MultiLevelType\">\n    <xsd:attribute name=\"val\" type=\"ST_MultiLevelType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbstractNum\">\n    <xsd:sequence>\n      <xsd:element name=\"nsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"multiLevelType\" type=\"CT_MultiLevelType\" minOccurs=\"0\"/>\n      <xsd:element name=\"tmpl\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"numStyleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"abstractNumId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumLvl\">\n    <xsd:sequence>\n      <xsd:element name=\"startOverride\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Num\">\n    <xsd:sequence>\n      <xsd:element name=\"abstractNumId\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"lvlOverride\" type=\"CT_NumLvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Numbering\">\n    <xsd:sequence>\n      <xsd:element name=\"numPicBullet\" type=\"CT_NumPicBullet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"abstractNum\" type=\"CT_AbstractNum\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"num\" type=\"CT_Num\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"numIdMacAtCleanup\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblStyleOverrideType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"firstRow\"/>\n      <xsd:enumeration value=\"lastRow\"/>\n      <xsd:enumeration value=\"firstCol\"/>\n      <xsd:enumeration value=\"lastCol\"/>\n      <xsd:enumeration value=\"band1Vert\"/>\n      <xsd:enumeration value=\"band2Vert\"/>\n      <xsd:enumeration value=\"band1Horz\"/>\n      <xsd:enumeration value=\"band2Horz\"/>\n      <xsd:enumeration value=\"neCell\"/>\n      <xsd:enumeration value=\"nwCell\"/>\n      <xsd:enumeration value=\"seCell\"/>\n      <xsd:enumeration value=\"swCell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblStylePr\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_TblStyleOverrideType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"table\"/>\n      <xsd:enumeration value=\"numbering\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"aliases\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"basedOn\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"next\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"link\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoRedefine\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"uiPriority\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"semiHidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"unhideWhenUsed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"qFormat\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"locked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personal\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalCompose\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalReply\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStylePr\" type=\"CT_TblStylePr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_StyleType\" use=\"optional\"/>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"default\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"customStyle\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LsdException\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"uiPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"semiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"unhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"qFormat\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LatentStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"lsdException\" type=\"CT_LsdException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"defLockedState\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUIPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"defSemiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUnhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defQFormat\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"count\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Styles\">\n    <xsd:sequence>\n      <xsd:element name=\"docDefaults\" type=\"CT_DocDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"latentStyles\" type=\"CT_LatentStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Panose\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Panose\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decorative\"/>\n      <xsd:enumeration value=\"modern\"/>\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"swiss\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pitch\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"variable\"/>\n      <xsd:enumeration value=\"default\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pitch\">\n    <xsd:attribute name=\"val\" type=\"ST_Pitch\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSig\">\n    <xsd:attribute name=\"usb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb2\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb3\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontRel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"fontKey\" type=\"s:ST_Guid\"/>\n        <xsd:attribute name=\"subsetted\" type=\"s:ST_OnOff\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:sequence>\n      <xsd:element name=\"altName\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"panose1\" type=\"CT_Panose\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_Charset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notTrueType\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pitch\" type=\"CT_Pitch\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sig\" type=\"CT_FontSig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedRegular\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBold\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBoldItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontsList\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DivBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Div\">\n    <xsd:sequence>\n      <xsd:element name=\"blockQuote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bodyDiv\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"marLeft\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marRight\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marTop\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marBottom\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"divBdr\" type=\"CT_DivBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"divsChild\" type=\"CT_Divs\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Divs\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"div\" type=\"CT_Div\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\"/>\n  <xsd:group name=\"EG_MathContent\">\n    <xsd:choice>\n      <xsd:element ref=\"m:oMathPara\"/>\n      <xsd:element ref=\"m:oMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelChunkElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_BlockLevelChunkElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"altChunk\" type=\"CT_AltChunk\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RunLevelElts\">\n    <xsd:choice>\n      <xsd:element name=\"proofErr\" minOccurs=\"0\" type=\"CT_ProofErr\"/>\n      <xsd:element name=\"permStart\" minOccurs=\"0\" type=\"CT_PermStart\"/>\n      <xsd:element name=\"permEnd\" minOccurs=\"0\" type=\"CT_Perm\"/>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ins\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_RunTrackChange\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_RunTrackChange\"/>\n      <xsd:group ref=\"EG_MathContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Body\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sectPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SectPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n        minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Footnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"footnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"footnotes\" type=\"CT_Footnotes\"/>\n  <xsd:complexType name=\"CT_Endnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"endnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"endnotes\" type=\"CT_Endnotes\"/>\n  <xsd:element name=\"hdr\" type=\"CT_HdrFtr\"/>\n  <xsd:element name=\"ftr\" type=\"CT_HdrFtr\"/>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceuri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ThemeColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"background1\"/>\n      <xsd:enumeration value=\"text1\"/>\n      <xsd:enumeration value=\"background2\"/>\n      <xsd:enumeration value=\"text2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DocPartBehavior\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"pg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartBehavior\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartBehavior\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartBehaviors\">\n    <xsd:choice>\n      <xsd:element name=\"behavior\" type=\"CT_DocPartBehavior\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"autoExp\"/>\n      <xsd:enumeration value=\"toolbar\"/>\n      <xsd:enumeration value=\"speller\"/>\n      <xsd:enumeration value=\"formFld\"/>\n      <xsd:enumeration value=\"bbPlcHdr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartTypes\">\n    <xsd:choice>\n      <xsd:element name=\"type\" type=\"CT_DocPartType\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"all\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartGallery\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"placeholder\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"docParts\"/>\n      <xsd:enumeration value=\"coverPg\"/>\n      <xsd:enumeration value=\"eq\"/>\n      <xsd:enumeration value=\"ftrs\"/>\n      <xsd:enumeration value=\"hdrs\"/>\n      <xsd:enumeration value=\"pgNum\"/>\n      <xsd:enumeration value=\"tbls\"/>\n      <xsd:enumeration value=\"watermarks\"/>\n      <xsd:enumeration value=\"autoTxt\"/>\n      <xsd:enumeration value=\"txtBox\"/>\n      <xsd:enumeration value=\"pgNumT\"/>\n      <xsd:enumeration value=\"pgNumB\"/>\n      <xsd:enumeration value=\"pgNumMargins\"/>\n      <xsd:enumeration value=\"tblOfContents\"/>\n      <xsd:enumeration value=\"bib\"/>\n      <xsd:enumeration value=\"custQuickParts\"/>\n      <xsd:enumeration value=\"custCoverPg\"/>\n      <xsd:enumeration value=\"custEq\"/>\n      <xsd:enumeration value=\"custFtrs\"/>\n      <xsd:enumeration value=\"custHdrs\"/>\n      <xsd:enumeration value=\"custPgNum\"/>\n      <xsd:enumeration value=\"custTbls\"/>\n      <xsd:enumeration value=\"custWatermarks\"/>\n      <xsd:enumeration value=\"custAutoTxt\"/>\n      <xsd:enumeration value=\"custTxtBox\"/>\n      <xsd:enumeration value=\"custPgNumT\"/>\n      <xsd:enumeration value=\"custPgNumB\"/>\n      <xsd:enumeration value=\"custPgNumMargins\"/>\n      <xsd:enumeration value=\"custTblOfContents\"/>\n      <xsd:enumeration value=\"custBib\"/>\n      <xsd:enumeration value=\"custom1\"/>\n      <xsd:enumeration value=\"custom2\"/>\n      <xsd:enumeration value=\"custom3\"/>\n      <xsd:enumeration value=\"custom4\"/>\n      <xsd:enumeration value=\"custom5\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartGallery\">\n    <xsd:attribute name=\"val\" type=\"ST_DocPartGallery\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartCategory\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gallery\" type=\"CT_DocPartGallery\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"decorated\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartPr\">\n    <xsd:all>\n      <xsd:element name=\"name\" type=\"CT_DocPartName\" minOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"category\" type=\"CT_DocPartCategory\" minOccurs=\"0\"/>\n      <xsd:element name=\"types\" type=\"CT_DocPartTypes\" minOccurs=\"0\"/>\n      <xsd:element name=\"behaviors\" type=\"CT_DocPartBehaviors\" minOccurs=\"0\"/>\n      <xsd:element name=\"description\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"guid\" type=\"CT_Guid\" minOccurs=\"0\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartPr\" type=\"CT_DocPartPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartBody\" type=\"CT_Body\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocParts\">\n    <xsd:choice>\n      <xsd:element name=\"docPart\" type=\"CT_DocPart\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:element name=\"settings\" type=\"CT_Settings\"/>\n  <xsd:element name=\"webSettings\" type=\"CT_WebSettings\"/>\n  <xsd:element name=\"fonts\" type=\"CT_FontsList\"/>\n  <xsd:element name=\"numbering\" type=\"CT_Numbering\"/>\n  <xsd:element name=\"styles\" type=\"CT_Styles\"/>\n  <xsd:simpleType name=\"ST_CaptionPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"above\"/>\n      <xsd:enumeration value=\"below\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Caption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_CaptionPos\" use=\"optional\"/>\n    <xsd:attribute name=\"chapNum\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"heading\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"noLabel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"numFmt\" type=\"ST_NumberFormat\" use=\"optional\"/>\n    <xsd:attribute name=\"sep\" type=\"ST_ChapterSep\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaptions\">\n    <xsd:sequence>\n      <xsd:element name=\"autoCaption\" type=\"CT_AutoCaption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Captions\">\n    <xsd:sequence>\n      <xsd:element name=\"caption\" type=\"CT_Caption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"autoCaptions\" type=\"CT_AutoCaptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocumentBase\">\n    <xsd:sequence>\n      <xsd:element name=\"background\" type=\"CT_Background\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Document\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"body\" type=\"CT_Body\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n        <xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlossaryDocument\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"docParts\" type=\"CT_DocParts\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:element name=\"document\" type=\"CT_Document\"/>\n  <xsd:element name=\"glossaryDocument\" type=\"CT_GlossaryDocument\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd",
    "content": "<?xml version='1.0'?>\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xs:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xs:element name=\"Types\" type=\"CT_Types\"/>\n  <xs:element name=\"Default\" type=\"CT_Default\"/>\n  <xs:element name=\"Override\" type=\"CT_Override\"/>\n\n  <xs:complexType name=\"CT_Types\">\n    <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element ref=\"Default\"/>\n      <xs:element ref=\"Override\"/>\n    </xs:choice>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Default\">\n    <xs:attribute name=\"Extension\" type=\"ST_Extension\" use=\"required\"/>\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Override\">\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n    <xs:attribute name=\"PartName\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:simpleType name=\"ST_ContentType\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))/((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))((\\s+)*;(\\s+)*(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))=((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+)|(&quot;(([\\p{IsLatin-1Supplement}\\p{IsBasicLatin}-[\\p{Cc}&#127;&quot;\\n\\r]]|(\\s+))|(\\\\[\\p{IsBasicLatin}]))*&quot;))))*)\"\n      />\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:simpleType name=\"ST_Extension\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"([!$&amp;'\\(\\)\\*\\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\\-_~])+\"/>\n    </xs:restriction>\n  </xs:simpleType>\n</xs:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:dcterms=\"http://purl.org/dc/terms/\" elementFormDefault=\"qualified\" blockDefault=\"#all\">\n\n  <xs:import namespace=\"http://purl.org/dc/elements/1.1/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd\"/>\n  <xs:import namespace=\"http://purl.org/dc/terms/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd\"/>\n  <xs:import id=\"xml\" namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n\n  <xs:element name=\"coreProperties\" type=\"CT_CoreProperties\"/>\n\n  <xs:complexType name=\"CT_CoreProperties\">\n    <xs:all>\n      <xs:element name=\"category\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"contentStatus\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dcterms:created\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:creator\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:description\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:identifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"keywords\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Keywords\"/>\n      <xs:element ref=\"dc:language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"lastModifiedBy\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"lastPrinted\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:dateTime\"/>\n      <xs:element ref=\"dcterms:modified\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"revision\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dc:subject\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"version\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n    </xs:all>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keywords\" mixed=\"true\">\n    <xs:sequence>\n      <xs:element name=\"value\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Keyword\"/>\n    </xs:sequence>\n    <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keyword\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"SignatureTime\" type=\"CT_SignatureTime\"/>\n  <xsd:element name=\"RelationshipReference\" type=\"CT_RelationshipReference\"/>\n  <xsd:element name=\"RelationshipsGroupReference\" type=\"CT_RelationshipsGroupReference\"/>\n\n  <xsd:complexType name=\"CT_SignatureTime\">\n    <xsd:sequence>\n      <xsd:element name=\"Format\" type=\"ST_Format\"/>\n      <xsd:element name=\"Value\" type=\"ST_Value\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceId\" type=\"xsd:string\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipsGroupReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceType\" type=\"xsd:anyURI\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_Format\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n\n  <xsd:simpleType name=\"ST_Value\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\\.[0-9])(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"Relationships\" type=\"CT_Relationships\"/>\n  <xsd:element name=\"Relationship\" type=\"CT_Relationship\"/>\n\n  <xsd:complexType name=\"CT_Relationships\">\n    <xsd:sequence>\n      <xsd:element ref=\"Relationship\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_Relationship\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"TargetMode\" type=\"ST_TargetMode\" use=\"optional\"/>\n        <xsd:attribute name=\"Target\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Type\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Id\" type=\"xsd:ID\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_TargetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"External\"/>\n      <xsd:enumeration value=\"Internal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/mce/mc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\tattributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\"\n\ttargetNamespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--\n    This XSD is a modified version of the one found at:\n    https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd\n\n    This XSD has 2 objectives:\n\n        1. round tripping @mc:Ignorable\n\n\t\t\t<w:document\n\t\t\t            xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t            xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t\t\t            mc:Ignorable=\"w14 w15 wp14\">\n\n        2. enabling AlternateContent to be manipulated in certain elements\n           (in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)\n\n\t\tSee further ECMA-376, 4th Edition, Office Open XML File Formats\n\t\tPart 3 : Markup Compatibility and Extensibility\n   -->\n\n  <!--  Objective 1 -->\n  <xsd:attribute name=\"Ignorable\" type=\"xsd:string\" />\n\n  <!--  Objective 2 -->\n\t<xsd:attribute name=\"MustUnderstand\" type=\"xsd:string\"  />\n\t<xsd:attribute name=\"ProcessContent\" type=\"xsd:string\"  />\n\n<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a\nFallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice\nelements. -->\n\t<xsd:element name=\"AlternateContent\">\n\t\t<xsd:complexType>\n\t\t\t<xsd:sequence>\n\t\t\t\t<xsd:element name=\"Choice\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute name=\"Requires\" type=\"xsd:string\" use=\"required\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t\t<xsd:element name=\"Fallback\" minOccurs=\"0\" maxOccurs=\"1\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t</xsd:sequence>\n\t\t\t<!-- AlternateContent elements might include the attributes Ignorable,\n\t\t\t\tMustUnderstand and ProcessContent described in this Part of ECMA-376. These\n\t\t\t\tattributes’ qualified names shall be prefixed when associated with an AlternateContent\n\t\t\t\telement. -->\n\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t</xsd:complexType>\n\t</xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns=\"http://schemas.microsoft.com/office/word/2010/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2010/wordml\">\n   <!-- <xsd:import id=\"rel\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" schemaLocation=\"orel.xsd\"/> -->\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <!-- <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartbasetypes.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartsplineproperties.xsd\"/> -->\n   <xsd:complexType name=\"CT_LongHexNumber\">\n     <xsd:attribute name=\"val\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_OnOff\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"true\"/>\n       <xsd:enumeration value=\"false\"/>\n       <xsd:enumeration value=\"0\"/>\n       <xsd:enumeration value=\"1\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_OnOff\">\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\"/>\n   </xsd:complexType>\n   <xsd:element name=\"docId\" type=\"CT_LongHexNumber\"/>\n   <xsd:element name=\"conflictMode\" type=\"CT_OnOff\"/>\n   <xsd:attributeGroup name=\"AG_Parids\">\n     <xsd:attribute name=\"paraId\" type=\"w:ST_LongHexNumber\"/>\n     <xsd:attribute name=\"textId\" type=\"w:ST_LongHexNumber\"/>\n   </xsd:attributeGroup>\n   <xsd:attribute name=\"anchorId\" type=\"w:ST_LongHexNumber\"/>\n   <xsd:attribute name=\"noSpellErr\" type=\"ST_OnOff\"/>\n   <xsd:element name=\"customXmlConflictInsRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictInsRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:element name=\"customXmlConflictDelRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictDelRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:group name=\"EG_RunLevelConflicts\">\n     <xsd:sequence>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:group name=\"EG_Conflicts\">\n     <xsd:choice>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Percentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_Percentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositivePercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_SchemeColorVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"bg1\"/>\n       <xsd:enumeration value=\"tx1\"/>\n       <xsd:enumeration value=\"bg2\"/>\n       <xsd:enumeration value=\"tx2\"/>\n       <xsd:enumeration value=\"accent1\"/>\n       <xsd:enumeration value=\"accent2\"/>\n       <xsd:enumeration value=\"accent3\"/>\n       <xsd:enumeration value=\"accent4\"/>\n       <xsd:enumeration value=\"accent5\"/>\n       <xsd:enumeration value=\"accent6\"/>\n       <xsd:enumeration value=\"hlink\"/>\n       <xsd:enumeration value=\"folHlink\"/>\n       <xsd:enumeration value=\"dk1\"/>\n       <xsd:enumeration value=\"lt1\"/>\n       <xsd:enumeration value=\"dk2\"/>\n       <xsd:enumeration value=\"lt2\"/>\n       <xsd:enumeration value=\"phClr\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_RectAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PathShadeType\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"shape\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"rect\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LineCap\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"rnd\"/>\n       <xsd:enumeration value=\"sq\"/>\n       <xsd:enumeration value=\"flat\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PresetLineDashVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"solid\"/>\n       <xsd:enumeration value=\"dot\"/>\n       <xsd:enumeration value=\"sysDot\"/>\n       <xsd:enumeration value=\"dash\"/>\n       <xsd:enumeration value=\"sysDash\"/>\n       <xsd:enumeration value=\"lgDash\"/>\n       <xsd:enumeration value=\"dashDot\"/>\n       <xsd:enumeration value=\"sysDashDot\"/>\n       <xsd:enumeration value=\"lgDashDot\"/>\n       <xsd:enumeration value=\"lgDashDotDot\"/>\n       <xsd:enumeration value=\"sysDashDotDot\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PenAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"in\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_CompoundLine\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"sng\"/>\n       <xsd:enumeration value=\"dbl\"/>\n       <xsd:enumeration value=\"thickThin\"/>\n       <xsd:enumeration value=\"thinThick\"/>\n       <xsd:enumeration value=\"tri\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_RelativeRect\">\n     <xsd:attribute name=\"l\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"t\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"r\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"b\" use=\"optional\" type=\"a:ST_Percentage\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorTransform\">\n     <xsd:choice>\n       <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\"/>\n       <xsd:element name=\"sat\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satMod\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lum\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumMod\" type=\"CT_Percentage\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SRgbColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SchemeColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorChoice\">\n     <xsd:choice>\n       <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\"/>\n       <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Color\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStop\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"pos\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStopList\">\n     <xsd:sequence>\n       <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"10\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_LinearShadeProperties\">\n     <xsd:attribute name=\"ang\" type=\"a:ST_PositiveFixedAngle\" use=\"optional\"/>\n     <xsd:attribute name=\"scaled\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PathShadeProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ShadeProperties\">\n     <xsd:choice>\n       <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\"/>\n       <xsd:element name=\"path\" type=\"CT_PathShadeProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SolidColorFillProperties\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientFillProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_FillProperties\">\n     <xsd:choice>\n       <xsd:element name=\"noFill\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\"/>\n       <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_PresetLineDashProperties\">\n     <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineDashProperties\">\n     <xsd:choice>\n       <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n     <xsd:attribute name=\"lim\" type=\"a:ST_PositivePercentage\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineJoinProperties\">\n     <xsd:choice>\n       <xsd:element name=\"round\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"bevel\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_PresetCameraType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueTop\"/>\n       <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n       <xsd:enumeration value=\"legacyObliqueLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueFront\"/>\n       <xsd:enumeration value=\"legacyObliqueRight\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueBottom\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n       <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n       <xsd:enumeration value=\"orthographicFront\"/>\n       <xsd:enumeration value=\"isometricTopUp\"/>\n       <xsd:enumeration value=\"isometricTopDown\"/>\n       <xsd:enumeration value=\"isometricBottomUp\"/>\n       <xsd:enumeration value=\"isometricBottomDown\"/>\n       <xsd:enumeration value=\"isometricLeftUp\"/>\n       <xsd:enumeration value=\"isometricLeftDown\"/>\n       <xsd:enumeration value=\"isometricRightUp\"/>\n       <xsd:enumeration value=\"isometricRightDown\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n       <xsd:enumeration value=\"obliqueTopLeft\"/>\n       <xsd:enumeration value=\"obliqueTop\"/>\n       <xsd:enumeration value=\"obliqueTopRight\"/>\n       <xsd:enumeration value=\"obliqueLeft\"/>\n       <xsd:enumeration value=\"obliqueRight\"/>\n       <xsd:enumeration value=\"obliqueBottomLeft\"/>\n       <xsd:enumeration value=\"obliqueBottom\"/>\n       <xsd:enumeration value=\"obliqueBottomRight\"/>\n       <xsd:enumeration value=\"perspectiveFront\"/>\n       <xsd:enumeration value=\"perspectiveLeft\"/>\n       <xsd:enumeration value=\"perspectiveRight\"/>\n       <xsd:enumeration value=\"perspectiveAbove\"/>\n       <xsd:enumeration value=\"perspectiveBelow\"/>\n       <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveRelaxed\"/>\n       <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Camera\">\n     <xsd:attribute name=\"prst\" use=\"required\" type=\"ST_PresetCameraType\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SphereCoords\">\n     <xsd:attribute name=\"lat\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"lon\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"rev\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_LightRigType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyFlat1\"/>\n       <xsd:enumeration value=\"legacyFlat2\"/>\n       <xsd:enumeration value=\"legacyFlat3\"/>\n       <xsd:enumeration value=\"legacyFlat4\"/>\n       <xsd:enumeration value=\"legacyNormal1\"/>\n       <xsd:enumeration value=\"legacyNormal2\"/>\n       <xsd:enumeration value=\"legacyNormal3\"/>\n       <xsd:enumeration value=\"legacyNormal4\"/>\n       <xsd:enumeration value=\"legacyHarsh1\"/>\n       <xsd:enumeration value=\"legacyHarsh2\"/>\n       <xsd:enumeration value=\"legacyHarsh3\"/>\n       <xsd:enumeration value=\"legacyHarsh4\"/>\n       <xsd:enumeration value=\"threePt\"/>\n       <xsd:enumeration value=\"balanced\"/>\n       <xsd:enumeration value=\"soft\"/>\n       <xsd:enumeration value=\"harsh\"/>\n       <xsd:enumeration value=\"flood\"/>\n       <xsd:enumeration value=\"contrasting\"/>\n       <xsd:enumeration value=\"morning\"/>\n       <xsd:enumeration value=\"sunrise\"/>\n       <xsd:enumeration value=\"sunset\"/>\n       <xsd:enumeration value=\"chilly\"/>\n       <xsd:enumeration value=\"freezing\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"twoPt\"/>\n       <xsd:enumeration value=\"glow\"/>\n       <xsd:enumeration value=\"brightRoom\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LightRigDirection\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_LightRig\">\n     <xsd:sequence>\n       <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n     <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_BevelPresetType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"relaxedInset\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"slope\"/>\n       <xsd:enumeration value=\"cross\"/>\n       <xsd:enumeration value=\"angle\"/>\n       <xsd:enumeration value=\"softRound\"/>\n       <xsd:enumeration value=\"convex\"/>\n       <xsd:enumeration value=\"coolSlant\"/>\n       <xsd:enumeration value=\"divot\"/>\n       <xsd:enumeration value=\"riblet\"/>\n       <xsd:enumeration value=\"hardEdge\"/>\n       <xsd:enumeration value=\"artDeco\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Bevel\">\n     <xsd:attribute name=\"w\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"h\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_PresetMaterialType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyMatte\"/>\n       <xsd:enumeration value=\"legacyPlastic\"/>\n       <xsd:enumeration value=\"legacyMetal\"/>\n       <xsd:enumeration value=\"legacyWireframe\"/>\n       <xsd:enumeration value=\"matte\"/>\n       <xsd:enumeration value=\"plastic\"/>\n       <xsd:enumeration value=\"metal\"/>\n       <xsd:enumeration value=\"warmMatte\"/>\n       <xsd:enumeration value=\"translucentPowder\"/>\n       <xsd:enumeration value=\"powder\"/>\n       <xsd:enumeration value=\"dkEdge\"/>\n       <xsd:enumeration value=\"softEdge\"/>\n       <xsd:enumeration value=\"clear\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"softmetal\"/>\n       <xsd:enumeration value=\"none\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Glow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Shadow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Reflection\">\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"stA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"stPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"fadeDir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_FillTextEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_TextOutlineEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"w\" use=\"optional\" type=\"a:ST_LineWidth\"/>\n     <xsd:attribute name=\"cap\" use=\"optional\" type=\"ST_LineCap\"/>\n     <xsd:attribute name=\"cmpd\" use=\"optional\" type=\"ST_CompoundLine\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_PenAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Scene3D\">\n     <xsd:sequence>\n       <xsd:element name=\"camera\" type=\"CT_Camera\"/>\n       <xsd:element name=\"lightRig\" type=\"CT_LightRig\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Props3D\">\n     <xsd:sequence>\n       <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n       <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"extrusionH\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"contourW\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrTextEffects\">\n     <xsd:sequence>\n       <xsd:element name=\"glow\" minOccurs=\"0\" type=\"CT_Glow\"/>\n       <xsd:element name=\"shadow\" minOccurs=\"0\" type=\"CT_Shadow\"/>\n       <xsd:element name=\"reflection\" minOccurs=\"0\" type=\"CT_Reflection\"/>\n       <xsd:element name=\"textOutline\" minOccurs=\"0\" type=\"CT_TextOutlineEffect\"/>\n       <xsd:element name=\"textFill\" minOccurs=\"0\" type=\"CT_FillTextEffect\"/>\n       <xsd:element name=\"scene3d\" minOccurs=\"0\" type=\"CT_Scene3D\"/>\n       <xsd:element name=\"props3d\" minOccurs=\"0\" type=\"CT_Props3D\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_Ligatures\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"standard\"/>\n       <xsd:enumeration value=\"contextual\"/>\n       <xsd:enumeration value=\"historical\"/>\n       <xsd:enumeration value=\"discretional\"/>\n       <xsd:enumeration value=\"standardContextual\"/>\n       <xsd:enumeration value=\"standardHistorical\"/>\n       <xsd:enumeration value=\"contextualHistorical\"/>\n       <xsd:enumeration value=\"standardDiscretional\"/>\n       <xsd:enumeration value=\"contextualDiscretional\"/>\n       <xsd:enumeration value=\"historicalDiscretional\"/>\n       <xsd:enumeration value=\"standardContextualHistorical\"/>\n       <xsd:enumeration value=\"standardContextualDiscretional\"/>\n       <xsd:enumeration value=\"standardHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"contextualHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"all\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Ligatures\">\n     <xsd:attribute name=\"val\" type=\"ST_Ligatures\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumForm\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"lining\"/>\n       <xsd:enumeration value=\"oldStyle\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumForm\">\n     <xsd:attribute name=\"val\" type=\"ST_NumForm\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumSpacing\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"proportional\"/>\n       <xsd:enumeration value=\"tabular\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumSpacing\">\n     <xsd:attribute name=\"val\" type=\"ST_NumSpacing\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StyleSet\">\n     <xsd:attribute name=\"id\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StylisticSets\">\n     <xsd:sequence minOccurs=\"0\">\n       <xsd:element name=\"styleSet\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_StyleSet\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrOpenType\">\n     <xsd:sequence>\n       <xsd:element name=\"ligatures\" minOccurs=\"0\" type=\"CT_Ligatures\"/>\n       <xsd:element name=\"numForm\" minOccurs=\"0\" type=\"CT_NumForm\"/>\n       <xsd:element name=\"numSpacing\" minOccurs=\"0\" type=\"CT_NumSpacing\"/>\n       <xsd:element name=\"stylisticSets\" minOccurs=\"0\" type=\"CT_StylisticSets\"/>\n       <xsd:element name=\"cntxtAlts\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:element name=\"discardImageEditingData\" type=\"CT_OnOff\"/>\n   <xsd:element name=\"defaultImageDpi\" type=\"CT_DefaultImageDpi\"/>\n   <xsd:complexType name=\"CT_DefaultImageDpi\">\n     <xsd:attribute name=\"val\" type=\"w:ST_DecimalNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"entityPicker\" type=\"w:CT_Empty\"/>\n   <xsd:complexType name=\"CT_SdtCheckboxSymbol\">\n     <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n     <xsd:attribute name=\"val\" type=\"w:ST_ShortHexNumber\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SdtCheckbox\">\n     <xsd:sequence>\n       <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n       <xsd:element name=\"checkedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n       <xsd:element name=\"uncheckedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:element name=\"checkbox\" type=\"CT_SdtCheckbox\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2012/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:element name=\"color\" type=\"w12:CT_Color\"/>\n   <xsd:simpleType name=\"ST_SdtAppearance\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"boundingBox\"/>\n       <xsd:enumeration value=\"tags\"/>\n       <xsd:enumeration value=\"hidden\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:element name=\"dataBinding\" type=\"w12:CT_DataBinding\"/>\n   <xsd:complexType name=\"CT_SdtAppearance\">\n     <xsd:attribute name=\"val\" type=\"ST_SdtAppearance\"/>\n   </xsd:complexType>\n   <xsd:element name=\"appearance\" type=\"CT_SdtAppearance\"/>\n   <xsd:complexType name=\"CT_CommentsEx\">\n     <xsd:sequence>\n       <xsd:element name=\"commentEx\" type=\"CT_CommentEx\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentEx\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"paraIdParent\" type=\"w12:ST_LongHexNumber\" use=\"optional\"/>\n     <xsd:attribute name=\"done\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsEx\" type=\"CT_CommentsEx\"/>\n   <xsd:complexType name=\"CT_People\">\n     <xsd:sequence>\n       <xsd:element name=\"person\" type=\"CT_Person\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PresenceInfo\">\n     <xsd:attribute name=\"providerId\" type=\"xsd:string\" use=\"required\"/>\n     <xsd:attribute name=\"userId\" type=\"xsd:string\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Person\">\n     <xsd:sequence>\n       <xsd:element name=\"presenceInfo\" type=\"CT_PresenceInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"people\" type=\"CT_People\"/>\n   <xsd:complexType name=\"CT_SdtRepeatedSection\">\n     <xsd:sequence>\n       <xsd:element name=\"sectionTitle\" type=\"w12:CT_String\" minOccurs=\"0\"/>\n       <xsd:element name=\"doNotAllowInsertDeleteSection\" type=\"w12:CT_OnOff\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_Guid\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Guid\">\n     <xsd:attribute name=\"val\" type=\"ST_Guid\"/>\n   </xsd:complexType>\n   <xsd:element name=\"repeatingSection\" type=\"CT_SdtRepeatedSection\"/>\n   <xsd:element name=\"repeatingSectionItem\" type=\"w12:CT_Empty\"/>\n   <xsd:element name=\"chartTrackingRefBased\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"collapsed\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"docId\" type=\"CT_Guid\"/>\n   <xsd:element name=\"footnoteColumns\" type=\"w12:CT_DecimalNumber\"/>\n   <xsd:element name=\"webExtensionLinked\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"webExtensionCreated\" type=\"w12:CT_OnOff\"/>\n   <xsd:attribute name=\"restartNumberingAfterBreak\" type=\"s:ST_OnOff\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_Extension\">\n     <xsd:sequence>\n       <xsd:any processContents=\"lax\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_ExtensionList\">\n     <xsd:sequence>\n       <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\">\n   <xsd:import id=\"w16\" namespace=\"http://schemas.microsoft.com/office/word/2018/wordml\" schemaLocation=\"wml-2018.xsd\"/>\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import id=\"s\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"commentExtensible\" type=\"CT_CommentExtensible\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"durableId\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"dateUtc\" type=\"w:ST_DateTime\" use=\"optional\"/>\n     <xsd:attribute name=\"intelligentPlaceholder\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsExtensible\" type=\"CT_CommentsExtensible\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" targetNamespace=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsIds\">\n     <xsd:sequence>\n       <xsd:element name=\"commentId\" type=\"CT_CommentId\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentId\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"durableId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsIds\" type=\"CT_CommentsIds\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" targetNamespace=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:attribute name=\"storeItemChecksum\" type=\"w12:ST_String\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_SymEx\">\n     <xsd:attribute name=\"font\" type=\"w12:ST_String\"/>\n     <xsd:attribute name=\"char\" type=\"w12:ST_LongHexNumber\"/>\n   </xsd:complexType>\n   <xsd:element name=\"symEx\" type=\"CT_SymEx\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/docx/scripts/office/soffice.py",
    "content": "\"\"\"\nHelper for running LibreOffice (soffice) in environments where AF_UNIX\nsockets may be blocked (e.g., sandboxed VMs).  Detects the restriction\nat runtime and applies an LD_PRELOAD shim if needed.\n\nUsage:\n    from office.soffice import run_soffice, get_soffice_env\n\n    # Option 1 – run soffice directly\n    result = run_soffice([\"--headless\", \"--convert-to\", \"pdf\", \"input.docx\"])\n\n    # Option 2 – get env dict for your own subprocess calls\n    env = get_soffice_env()\n    subprocess.run([\"soffice\", ...], env=env)\n\"\"\"\n\nimport os\nimport socket\nimport subprocess\nimport tempfile\nfrom pathlib import Path\n\n\ndef get_soffice_env() -> dict:\n    env = os.environ.copy()\n    env[\"SAL_USE_VCLPLUGIN\"] = \"svp\"\n\n    if _needs_shim():\n        shim = _ensure_shim()\n        env[\"LD_PRELOAD\"] = str(shim)\n\n    return env\n\n\ndef run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:\n    env = get_soffice_env()\n    return subprocess.run([\"soffice\"] + args, env=env, **kwargs)\n\n\n\n_SHIM_SO = Path(tempfile.gettempdir()) / \"lo_socket_shim.so\"\n\n\ndef _needs_shim() -> bool:\n    try:\n        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        s.close()\n        return False\n    except OSError:\n        return True\n\n\ndef _ensure_shim() -> Path:\n    if _SHIM_SO.exists():\n        return _SHIM_SO\n\n    src = Path(tempfile.gettempdir()) / \"lo_socket_shim.c\"\n    src.write_text(_SHIM_SOURCE)\n    subprocess.run(\n        [\"gcc\", \"-shared\", \"-fPIC\", \"-o\", str(_SHIM_SO), str(src), \"-ldl\"],\n        check=True,\n        capture_output=True,\n    )\n    src.unlink()\n    return _SHIM_SO\n\n\n\n_SHIM_SOURCE = r\"\"\"\n#define _GNU_SOURCE\n#include <dlfcn.h>\n#include <errno.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/socket.h>\n#include <unistd.h>\n\nstatic int (*real_socket)(int, int, int);\nstatic int (*real_socketpair)(int, int, int, int[2]);\nstatic int (*real_listen)(int, int);\nstatic int (*real_accept)(int, struct sockaddr *, socklen_t *);\nstatic int (*real_close)(int);\nstatic int (*real_read)(int, void *, size_t);\n\n/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */\nstatic int is_shimmed[1024];\nstatic int peer_of[1024];\nstatic int wake_r[1024];            /* accept() blocks reading this */\nstatic int wake_w[1024];            /* close()  writes to this      */\nstatic int listener_fd = -1;        /* FD that received listen()    */\n\n__attribute__((constructor))\nstatic void init(void) {\n    real_socket     = dlsym(RTLD_NEXT, \"socket\");\n    real_socketpair = dlsym(RTLD_NEXT, \"socketpair\");\n    real_listen     = dlsym(RTLD_NEXT, \"listen\");\n    real_accept     = dlsym(RTLD_NEXT, \"accept\");\n    real_close      = dlsym(RTLD_NEXT, \"close\");\n    real_read       = dlsym(RTLD_NEXT, \"read\");\n    for (int i = 0; i < 1024; i++) {\n        peer_of[i] = -1;\n        wake_r[i]  = -1;\n        wake_w[i]  = -1;\n    }\n}\n\n/* ---- socket ---------------------------------------------------------- */\nint socket(int domain, int type, int protocol) {\n    if (domain == AF_UNIX) {\n        int fd = real_socket(domain, type, protocol);\n        if (fd >= 0) return fd;\n        /* socket(AF_UNIX) blocked – fall back to socketpair(). */\n        int sv[2];\n        if (real_socketpair(domain, type, protocol, sv) == 0) {\n            if (sv[0] >= 0 && sv[0] < 1024) {\n                is_shimmed[sv[0]] = 1;\n                peer_of[sv[0]]    = sv[1];\n                int wp[2];\n                if (pipe(wp) == 0) {\n                    wake_r[sv[0]] = wp[0];\n                    wake_w[sv[0]] = wp[1];\n                }\n            }\n            return sv[0];\n        }\n        errno = EPERM;\n        return -1;\n    }\n    return real_socket(domain, type, protocol);\n}\n\n/* ---- listen ---------------------------------------------------------- */\nint listen(int sockfd, int backlog) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        listener_fd = sockfd;\n        return 0;\n    }\n    return real_listen(sockfd, backlog);\n}\n\n/* ---- accept ---------------------------------------------------------- */\nint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        /* Block until close() writes to the wake pipe. */\n        if (wake_r[sockfd] >= 0) {\n            char buf;\n            real_read(wake_r[sockfd], &buf, 1);\n        }\n        errno = ECONNABORTED;\n        return -1;\n    }\n    return real_accept(sockfd, addr, addrlen);\n}\n\n/* ---- close ----------------------------------------------------------- */\nint close(int fd) {\n    if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {\n        int was_listener = (fd == listener_fd);\n        is_shimmed[fd] = 0;\n\n        if (wake_w[fd] >= 0) {              /* unblock accept() */\n            char c = 0;\n            write(wake_w[fd], &c, 1);\n            real_close(wake_w[fd]);\n            wake_w[fd] = -1;\n        }\n        if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd]  = -1; }\n        if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }\n\n        if (was_listener)\n            _exit(0);                        /* conversion done – exit */\n    }\n    return real_close(fd);\n}\n\"\"\"\n\n\n\nif __name__ == \"__main__\":\n    import sys\n    result = run_soffice(sys.argv[1:])\n    sys.exit(result.returncode)\n"
  },
  {
    "path": "skills/docx/scripts/office/unpack.py",
    "content": "\"\"\"Unpack Office files (DOCX, PPTX, XLSX) for editing.\n\nExtracts the ZIP archive, pretty-prints XML files, and optionally:\n- Merges adjacent runs with identical formatting (DOCX only)\n- Simplifies adjacent tracked changes from same author (DOCX only)\n\nUsage:\n    python unpack.py <office_file> <output_dir> [options]\n\nExamples:\n    python unpack.py document.docx unpacked/\n    python unpack.py presentation.pptx unpacked/\n    python unpack.py document.docx unpacked/ --merge-runs false\n\"\"\"\n\nimport argparse\nimport sys\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom helpers.merge_runs import merge_runs as do_merge_runs\nfrom helpers.simplify_redlines import simplify_redlines as do_simplify_redlines\n\nSMART_QUOTE_REPLACEMENTS = {\n    \"\\u201c\": \"&#x201C;\",  \n    \"\\u201d\": \"&#x201D;\",  \n    \"\\u2018\": \"&#x2018;\",  \n    \"\\u2019\": \"&#x2019;\",  \n}\n\n\ndef unpack(\n    input_file: str,\n    output_directory: str,\n    merge_runs: bool = True,\n    simplify_redlines: bool = True,\n) -> tuple[None, str]:\n    input_path = Path(input_file)\n    output_path = Path(output_directory)\n    suffix = input_path.suffix.lower()\n\n    if not input_path.exists():\n        return None, f\"Error: {input_file} does not exist\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {input_file} must be a .docx, .pptx, or .xlsx file\"\n\n    try:\n        output_path.mkdir(parents=True, exist_ok=True)\n\n        with zipfile.ZipFile(input_path, \"r\") as zf:\n            zf.extractall(output_path)\n\n        xml_files = list(output_path.rglob(\"*.xml\")) + list(output_path.rglob(\"*.rels\"))\n        for xml_file in xml_files:\n            _pretty_print_xml(xml_file)\n\n        message = f\"Unpacked {input_file} ({len(xml_files)} XML files)\"\n\n        if suffix == \".docx\":\n            if simplify_redlines:\n                simplify_count, _ = do_simplify_redlines(str(output_path))\n                message += f\", simplified {simplify_count} tracked changes\"\n\n            if merge_runs:\n                merge_count, _ = do_merge_runs(str(output_path))\n                message += f\", merged {merge_count} runs\"\n\n        for xml_file in xml_files:\n            _escape_smart_quotes(xml_file)\n\n        return None, message\n\n    except zipfile.BadZipFile:\n        return None, f\"Error: {input_file} is not a valid Office file\"\n    except Exception as e:\n        return None, f\"Error unpacking: {e}\"\n\n\ndef _pretty_print_xml(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        dom = defusedxml.minidom.parseString(content)\n        xml_file.write_bytes(dom.toprettyxml(indent=\"  \", encoding=\"utf-8\"))\n    except Exception:\n        pass  \n\n\ndef _escape_smart_quotes(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        for char, entity in SMART_QUOTE_REPLACEMENTS.items():\n            content = content.replace(char, entity)\n        xml_file.write_text(content, encoding=\"utf-8\")\n    except Exception:\n        pass\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Unpack an Office file (DOCX, PPTX, XLSX) for editing\"\n    )\n    parser.add_argument(\"input_file\", help=\"Office file to unpack\")\n    parser.add_argument(\"output_directory\", help=\"Output directory\")\n    parser.add_argument(\n        \"--merge-runs\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent runs with identical formatting (DOCX only, default: true)\",\n    )\n    parser.add_argument(\n        \"--simplify-redlines\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent tracked changes from same author (DOCX only, default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = unpack(\n        args.input_file,\n        args.output_directory,\n        merge_runs=args.merge_runs,\n        simplify_redlines=args.simplify_redlines,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/docx/scripts/office/validate.py",
    "content": "\"\"\"\nCommand line tool to validate Office document XML files against XSD schemas and tracked changes.\n\nUsage:\n    python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]\n\nThe first argument can be either:\n- An unpacked directory containing the Office document XML files\n- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory\n\nAuto-repair fixes:\n- paraId/durableId values that exceed OOXML limits\n- Missing xml:space=\"preserve\" on w:t elements with whitespace\n\"\"\"\n\nimport argparse\nimport sys\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Validate Office document XML files\")\n    parser.add_argument(\n        \"path\",\n        help=\"Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)\",\n    )\n    parser.add_argument(\n        \"--original\",\n        required=False,\n        default=None,\n        help=\"Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.\",\n    )\n    parser.add_argument(\n        \"-v\",\n        \"--verbose\",\n        action=\"store_true\",\n        help=\"Enable verbose output\",\n    )\n    parser.add_argument(\n        \"--auto-repair\",\n        action=\"store_true\",\n        help=\"Automatically repair common issues (hex IDs, whitespace preservation)\",\n    )\n    parser.add_argument(\n        \"--author\",\n        default=\"Claude\",\n        help=\"Author name for redlining validation (default: Claude)\",\n    )\n    args = parser.parse_args()\n\n    path = Path(args.path)\n    assert path.exists(), f\"Error: {path} does not exist\"\n\n    original_file = None\n    if args.original:\n        original_file = Path(args.original)\n        assert original_file.is_file(), f\"Error: {original_file} is not a file\"\n        assert original_file.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"], (\n            f\"Error: {original_file} must be a .docx, .pptx, or .xlsx file\"\n        )\n\n    file_extension = (original_file or path).suffix.lower()\n    assert file_extension in [\".docx\", \".pptx\", \".xlsx\"], (\n        f\"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file.\"\n    )\n\n    if path.is_file() and path.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"]:\n        temp_dir = tempfile.mkdtemp()\n        with zipfile.ZipFile(path, \"r\") as zf:\n            zf.extractall(temp_dir)\n        unpacked_dir = Path(temp_dir)\n    else:\n        assert path.is_dir(), f\"Error: {path} is not a directory or Office file\"\n        unpacked_dir = path\n\n    match file_extension:\n        case \".docx\":\n            validators = [\n                DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n            if original_file:\n                validators.append(\n                    RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)  \n                )\n        case \".pptx\":\n            validators = [\n                PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n        case _:\n            print(f\"Error: Validation not supported for file type {file_extension}\")\n            sys.exit(1)\n\n    if args.auto_repair:\n        total_repairs = sum(v.repair() for v in validators)\n        if total_repairs:\n            print(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        print(\"All validations PASSED!\")\n\n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/docx/scripts/office/validators/__init__.py",
    "content": "\"\"\"\nValidation modules for Word document processing.\n\"\"\"\n\nfrom .base import BaseSchemaValidator\nfrom .docx import DOCXSchemaValidator\nfrom .pptx import PPTXSchemaValidator\nfrom .redlining import RedliningValidator\n\n__all__ = [\n    \"BaseSchemaValidator\",\n    \"DOCXSchemaValidator\",\n    \"PPTXSchemaValidator\",\n    \"RedliningValidator\",\n]\n"
  },
  {
    "path": "skills/docx/scripts/office/validators/base.py",
    "content": "\"\"\"\nBase validator with common validation logic for document files.\n\"\"\"\n\nimport re\nfrom pathlib import Path\n\nimport defusedxml.minidom\nimport lxml.etree\n\n\nclass BaseSchemaValidator:\n\n    IGNORED_VALIDATION_ERRORS = [\n        \"hyphenationZone\",\n        \"purl.org/dc/terms\",\n    ]\n\n    UNIQUE_ID_REQUIREMENTS = {\n        \"comment\": (\"id\", \"file\"),  \n        \"commentrangestart\": (\"id\", \"file\"),  \n        \"commentrangeend\": (\"id\", \"file\"),  \n        \"bookmarkstart\": (\"id\", \"file\"),  \n        \"bookmarkend\": (\"id\", \"file\"),  \n        \"sldid\": (\"id\", \"file\"),  \n        \"sldmasterid\": (\"id\", \"global\"),  \n        \"sldlayoutid\": (\"id\", \"global\"),  \n        \"cm\": (\"authorid\", \"file\"),  \n        \"sheet\": (\"sheetid\", \"file\"),  \n        \"definedname\": (\"id\", \"file\"),  \n        \"cxnsp\": (\"id\", \"file\"),  \n        \"sp\": (\"id\", \"file\"),  \n        \"pic\": (\"id\", \"file\"),  \n        \"grpsp\": (\"id\", \"file\"),  \n    }\n\n    EXCLUDED_ID_CONTAINERS = {\n        \"sectionlst\",  \n    }\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    SCHEMA_MAPPINGS = {\n        \"word\": \"ISO-IEC29500-4_2016/wml.xsd\",  \n        \"ppt\": \"ISO-IEC29500-4_2016/pml.xsd\",  \n        \"xl\": \"ISO-IEC29500-4_2016/sml.xsd\",  \n        \"[Content_Types].xml\": \"ecma/fouth-edition/opc-contentTypes.xsd\",\n        \"app.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd\",\n        \"core.xml\": \"ecma/fouth-edition/opc-coreProperties.xsd\",\n        \"custom.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd\",\n        \".rels\": \"ecma/fouth-edition/opc-relationships.xsd\",\n        \"people.xml\": \"microsoft/wml-2012.xsd\",\n        \"commentsIds.xml\": \"microsoft/wml-cid-2016.xsd\",\n        \"commentsExtensible.xml\": \"microsoft/wml-cex-2018.xsd\",\n        \"commentsExtended.xml\": \"microsoft/wml-2012.xsd\",\n        \"chart\": \"ISO-IEC29500-4_2016/dml-chart.xsd\",\n        \"theme\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n        \"drawing\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n    }\n\n    MC_NAMESPACE = \"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\"\n\n    PACKAGE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/relationships\"\n    )\n    OFFICE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    )\n    CONTENT_TYPES_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/content-types\"\n    )\n\n    MAIN_CONTENT_FOLDERS = {\"word\", \"ppt\", \"xl\"}\n\n    OOXML_NAMESPACES = {\n        \"http://schemas.openxmlformats.org/officeDocument/2006/math\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n        \"http://schemas.openxmlformats.org/schemaLibrary/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chart\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/diagram\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n        \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\",\n        \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\",\n        \"http://www.w3.org/XML/1998/namespace\",\n    }\n\n    def __init__(self, unpacked_dir, original_file=None, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir).resolve()\n        self.original_file = Path(original_file) if original_file else None\n        self.verbose = verbose\n\n        self.schemas_dir = Path(__file__).parent.parent / \"schemas\"\n\n        patterns = [\"*.xml\", \"*.rels\"]\n        self.xml_files = [\n            f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)\n        ]\n\n        if not self.xml_files:\n            print(f\"Warning: No XML files found in {self.unpacked_dir}\")\n\n    def validate(self):\n        raise NotImplementedError(\"Subclasses must implement the validate method\")\n\n    def repair(self) -> int:\n        return self.repair_whitespace_preservation()\n\n    def repair_whitespace_preservation(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if elem.tagName.endswith(\":t\") and elem.firstChild:\n                        text = elem.firstChild.nodeValue\n                        if text and (text.startswith((' ', '\\t')) or text.endswith((' ', '\\t'))):\n                            if elem.getAttribute(\"xml:space\") != \"preserve\":\n                                elem.setAttribute(\"xml:space\", \"preserve\")\n                                text_preview = repr(text[:30]) + \"...\" if len(text) > 30 else repr(text)\n                                print(f\"  Repaired: {xml_file.name}: Added xml:space='preserve' to {elem.tagName}: {text_preview}\")\n                                repairs += 1\n                                modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n    def validate_xml(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                lxml.etree.parse(str(xml_file))\n            except lxml.etree.XMLSyntaxError as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Line {e.lineno}: {e.msg}\"\n                )\n            except Exception as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Unexpected error: {str(e)}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} XML violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All XML files are well-formed\")\n            return True\n\n    def validate_namespaces(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                declared = set(root.nsmap.keys()) - {None}  \n\n                for attr_val in [\n                    v for k, v in root.attrib.items() if k.endswith(\"Ignorable\")\n                ]:\n                    undeclared = set(attr_val.split()) - declared\n                    errors.extend(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Namespace '{ns}' in Ignorable but not declared\"\n                        for ns in undeclared\n                    )\n            except lxml.etree.XMLSyntaxError:\n                continue\n\n        if errors:\n            print(f\"FAILED - {len(errors)} namespace issues:\")\n            for error in errors:\n                print(error)\n            return False\n        if self.verbose:\n            print(\"PASSED - All namespace prefixes properly declared\")\n        return True\n\n    def validate_unique_ids(self):\n        errors = []\n        global_ids = {}  \n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                file_ids = {}  \n\n                mc_elements = root.xpath(\n                    \".//mc:AlternateContent\", namespaces={\"mc\": self.MC_NAMESPACE}\n                )\n                for elem in mc_elements:\n                    elem.getparent().remove(elem)\n\n                for elem in root.iter():\n                    tag = (\n                        elem.tag.split(\"}\")[-1].lower()\n                        if \"}\" in elem.tag\n                        else elem.tag.lower()\n                    )\n\n                    if tag in self.UNIQUE_ID_REQUIREMENTS:\n                        in_excluded_container = any(\n                            ancestor.tag.split(\"}\")[-1].lower() in self.EXCLUDED_ID_CONTAINERS\n                            for ancestor in elem.iterancestors()\n                        )\n                        if in_excluded_container:\n                            continue\n\n                        attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]\n\n                        id_value = None\n                        for attr, value in elem.attrib.items():\n                            attr_local = (\n                                attr.split(\"}\")[-1].lower()\n                                if \"}\" in attr\n                                else attr.lower()\n                            )\n                            if attr_local == attr_name:\n                                id_value = value\n                                break\n\n                        if id_value is not None:\n                            if scope == \"global\":\n                                if id_value in global_ids:\n                                    prev_file, prev_line, prev_tag = global_ids[\n                                        id_value\n                                    ]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> \"\n                                        f\"already used in {prev_file} at line {prev_line} in <{prev_tag}>\"\n                                    )\n                                else:\n                                    global_ids[id_value] = (\n                                        xml_file.relative_to(self.unpacked_dir),\n                                        elem.sourceline,\n                                        tag,\n                                    )\n                            elif scope == \"file\":\n                                key = (tag, attr_name)\n                                if key not in file_ids:\n                                    file_ids[key] = {}\n\n                                if id_value in file_ids[key]:\n                                    prev_line = file_ids[key][id_value]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> \"\n                                        f\"(first occurrence at line {prev_line})\"\n                                    )\n                                else:\n                                    file_ids[key][id_value] = elem.sourceline\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} ID uniqueness violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All required IDs are unique\")\n            return True\n\n    def validate_file_references(self):\n        errors = []\n\n        rels_files = list(self.unpacked_dir.rglob(\"*.rels\"))\n\n        if not rels_files:\n            if self.verbose:\n                print(\"PASSED - No .rels files found\")\n            return True\n\n        all_files = []\n        for file_path in self.unpacked_dir.rglob(\"*\"):\n            if (\n                file_path.is_file()\n                and file_path.name != \"[Content_Types].xml\"\n                and not file_path.name.endswith(\".rels\")\n            ):  \n                all_files.append(file_path.resolve())\n\n        all_referenced_files = set()\n\n        if self.verbose:\n            print(\n                f\"Found {len(rels_files)} .rels files and {len(all_files)} target files\"\n            )\n\n        for rels_file in rels_files:\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                rels_dir = rels_file.parent\n\n                referenced_files = set()\n                broken_refs = []\n\n                for rel in rels_root.findall(\n                    \".//ns:Relationship\",\n                    namespaces={\"ns\": self.PACKAGE_RELATIONSHIPS_NAMESPACE},\n                ):\n                    target = rel.get(\"Target\")\n                    if target and not target.startswith(\n                        (\"http\", \"mailto:\")\n                    ):  \n                        if target.startswith(\"/\"):\n                            target_path = self.unpacked_dir / target.lstrip(\"/\")\n                        elif rels_file.name == \".rels\":\n                            target_path = self.unpacked_dir / target\n                        else:\n                            base_dir = rels_dir.parent\n                            target_path = base_dir / target\n\n                        try:\n                            target_path = target_path.resolve()\n                            if target_path.exists() and target_path.is_file():\n                                referenced_files.add(target_path)\n                                all_referenced_files.add(target_path)\n                            else:\n                                broken_refs.append((target, rel.sourceline))\n                        except (OSError, ValueError):\n                            broken_refs.append((target, rel.sourceline))\n\n                if broken_refs:\n                    rel_path = rels_file.relative_to(self.unpacked_dir)\n                    for broken_ref, line_num in broken_refs:\n                        errors.append(\n                            f\"  {rel_path}: Line {line_num}: Broken reference to {broken_ref}\"\n                        )\n\n            except Exception as e:\n                rel_path = rels_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error parsing {rel_path}: {e}\")\n\n        unreferenced_files = set(all_files) - all_referenced_files\n\n        if unreferenced_files:\n            for unref_file in sorted(unreferenced_files):\n                unref_rel_path = unref_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Unreferenced file: {unref_rel_path}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"CRITICAL: These errors will cause the document to appear corrupt. \"\n                + \"Broken references MUST be fixed, \"\n                + \"and unreferenced files MUST be referenced or removed.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All references are valid and all files are properly referenced\"\n                )\n            return True\n\n    def validate_all_relationship_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.suffix == \".rels\":\n                continue\n\n            rels_dir = xml_file.parent / \"_rels\"\n            rels_file = rels_dir / f\"{xml_file.name}.rels\"\n\n            if not rels_file.exists():\n                continue\n\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n                rid_to_type = {}\n\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rid = rel.get(\"Id\")\n                    rel_type = rel.get(\"Type\", \"\")\n                    if rid:\n                        if rid in rid_to_type:\n                            rels_rel_path = rels_file.relative_to(self.unpacked_dir)\n                            errors.append(\n                                f\"  {rels_rel_path}: Line {rel.sourceline}: \"\n                                f\"Duplicate relationship ID '{rid}' (IDs must be unique)\"\n                            )\n                        type_name = (\n                            rel_type.split(\"/\")[-1] if \"/\" in rel_type else rel_type\n                        )\n                        rid_to_type[rid] = type_name\n\n                xml_root = lxml.etree.parse(str(xml_file)).getroot()\n\n                r_ns = self.OFFICE_RELATIONSHIPS_NAMESPACE\n                rid_attrs_to_check = [\"id\", \"embed\", \"link\"]\n                for elem in xml_root.iter():\n                    for attr_name in rid_attrs_to_check:\n                        rid_attr = elem.get(f\"{{{r_ns}}}{attr_name}\")\n                        if not rid_attr:\n                            continue\n                        xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                        elem_name = (\n                            elem.tag.split(\"}\")[-1] if \"}\" in elem.tag else elem.tag\n                        )\n\n                        if rid_attr not in rid_to_type:\n                            errors.append(\n                                f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                f\"<{elem_name}> r:{attr_name} references non-existent relationship '{rid_attr}' \"\n                                f\"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})\"\n                            )\n                        elif attr_name == \"id\" and self.ELEMENT_RELATIONSHIP_TYPES:\n                            expected_type = self._get_expected_relationship_type(\n                                elem_name\n                            )\n                            if expected_type:\n                                actual_type = rid_to_type[rid_attr]\n                                if expected_type not in actual_type.lower():\n                                    errors.append(\n                                        f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                        f\"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' \"\n                                        f\"but should point to a '{expected_type}' relationship\"\n                                    )\n\n            except Exception as e:\n                xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error processing {xml_rel_path}: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship ID reference errors:\")\n            for error in errors:\n                print(error)\n            print(\"\\nThese ID mismatches will cause the document to appear corrupt!\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All relationship ID references are valid\")\n            return True\n\n    def _get_expected_relationship_type(self, element_name):\n        elem_lower = element_name.lower()\n\n        if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:\n            return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]\n\n        if elem_lower.endswith(\"id\") and len(elem_lower) > 2:\n            prefix = elem_lower[:-2]  \n            if prefix.endswith(\"master\"):\n                return prefix.lower()\n            elif prefix.endswith(\"layout\"):\n                return prefix.lower()\n            else:\n                if prefix == \"sld\":\n                    return \"slide\"\n                return prefix.lower()\n\n        if elem_lower.endswith(\"reference\") and len(elem_lower) > 9:\n            prefix = elem_lower[:-9]  \n            return prefix.lower()\n\n        return None\n\n    def validate_content_types(self):\n        errors = []\n\n        content_types_file = self.unpacked_dir / \"[Content_Types].xml\"\n        if not content_types_file.exists():\n            print(\"FAILED - [Content_Types].xml file not found\")\n            return False\n\n        try:\n            root = lxml.etree.parse(str(content_types_file)).getroot()\n            declared_parts = set()\n            declared_extensions = set()\n\n            for override in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override\"\n            ):\n                part_name = override.get(\"PartName\")\n                if part_name is not None:\n                    declared_parts.add(part_name.lstrip(\"/\"))\n\n            for default in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default\"\n            ):\n                extension = default.get(\"Extension\")\n                if extension is not None:\n                    declared_extensions.add(extension.lower())\n\n            declarable_roots = {\n                \"sld\",\n                \"sldLayout\",\n                \"sldMaster\",\n                \"presentation\",  \n                \"document\",  \n                \"workbook\",\n                \"worksheet\",  \n                \"theme\",  \n            }\n\n            media_extensions = {\n                \"png\": \"image/png\",\n                \"jpg\": \"image/jpeg\",\n                \"jpeg\": \"image/jpeg\",\n                \"gif\": \"image/gif\",\n                \"bmp\": \"image/bmp\",\n                \"tiff\": \"image/tiff\",\n                \"wmf\": \"image/x-wmf\",\n                \"emf\": \"image/x-emf\",\n            }\n\n            all_files = list(self.unpacked_dir.rglob(\"*\"))\n            all_files = [f for f in all_files if f.is_file()]\n\n            for xml_file in self.xml_files:\n                path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(\n                    \"\\\\\", \"/\"\n                )\n\n                if any(\n                    skip in path_str\n                    for skip in [\".rels\", \"[Content_Types]\", \"docProps/\", \"_rels/\"]\n                ):\n                    continue\n\n                try:\n                    root_tag = lxml.etree.parse(str(xml_file)).getroot().tag\n                    root_name = root_tag.split(\"}\")[-1] if \"}\" in root_tag else root_tag\n\n                    if root_name in declarable_roots and path_str not in declared_parts:\n                        errors.append(\n                            f\"  {path_str}: File with <{root_name}> root not declared in [Content_Types].xml\"\n                        )\n\n                except Exception:\n                    continue  \n\n            for file_path in all_files:\n                if file_path.suffix.lower() in {\".xml\", \".rels\"}:\n                    continue\n                if file_path.name == \"[Content_Types].xml\":\n                    continue\n                if \"_rels\" in file_path.parts or \"docProps\" in file_path.parts:\n                    continue\n\n                extension = file_path.suffix.lstrip(\".\").lower()\n                if extension and extension not in declared_extensions:\n                    if extension in media_extensions:\n                        relative_path = file_path.relative_to(self.unpacked_dir)\n                        errors.append(\n                            f'  {relative_path}: File with extension \\'{extension}\\' not declared in [Content_Types].xml - should add: <Default Extension=\"{extension}\" ContentType=\"{media_extensions[extension]}\"/>'\n                        )\n\n        except Exception as e:\n            errors.append(f\"  Error parsing [Content_Types].xml: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} content type declaration errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All content files are properly declared in [Content_Types].xml\"\n                )\n            return True\n\n    def validate_file_against_xsd(self, xml_file, verbose=False):\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n\n        is_valid, current_errors = self._validate_single_file_xsd(\n            xml_file, unpacked_dir\n        )\n\n        if is_valid is None:\n            return None, set()  \n        elif is_valid:\n            return True, set()  \n\n        original_errors = self._get_original_file_errors(xml_file)\n\n        assert current_errors is not None\n        new_errors = current_errors - original_errors\n\n        new_errors = {\n            e for e in new_errors\n            if not any(pattern in e for pattern in self.IGNORED_VALIDATION_ERRORS)\n        }\n\n        if new_errors:\n            if verbose:\n                relative_path = xml_file.relative_to(unpacked_dir)\n                print(f\"FAILED - {relative_path}: {len(new_errors)} new error(s)\")\n                for error in list(new_errors)[:3]:\n                    truncated = error[:250] + \"...\" if len(error) > 250 else error\n                    print(f\"  - {truncated}\")\n            return False, new_errors\n        else:\n            if verbose:\n                print(\n                    f\"PASSED - No new errors (original had {len(current_errors)} errors)\"\n                )\n            return True, set()\n\n    def validate_against_xsd(self):\n        new_errors = []\n        original_error_count = 0\n        valid_count = 0\n        skipped_count = 0\n\n        for xml_file in self.xml_files:\n            relative_path = str(xml_file.relative_to(self.unpacked_dir))\n            is_valid, new_file_errors = self.validate_file_against_xsd(\n                xml_file, verbose=False\n            )\n\n            if is_valid is None:\n                skipped_count += 1\n                continue\n            elif is_valid and not new_file_errors:\n                valid_count += 1\n                continue\n            elif is_valid:\n                original_error_count += 1\n                valid_count += 1\n                continue\n\n            new_errors.append(f\"  {relative_path}: {len(new_file_errors)} new error(s)\")\n            for error in list(new_file_errors)[:3]:  \n                new_errors.append(\n                    f\"    - {error[:250]}...\" if len(error) > 250 else f\"    - {error}\"\n                )\n\n        if self.verbose:\n            print(f\"Validated {len(self.xml_files)} files:\")\n            print(f\"  - Valid: {valid_count}\")\n            print(f\"  - Skipped (no schema): {skipped_count}\")\n            if original_error_count:\n                print(f\"  - With original errors (ignored): {original_error_count}\")\n            print(\n                f\"  - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith('    ')]) or 0}\"\n            )\n\n        if new_errors:\n            print(\"\\nFAILED - Found NEW validation errors:\")\n            for error in new_errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"\\nPASSED - No new XSD validation errors introduced\")\n            return True\n\n    def _get_schema_path(self, xml_file):\n        if xml_file.name in self.SCHEMA_MAPPINGS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]\n\n        if xml_file.suffix == \".rels\":\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\".rels\"]\n\n        if \"charts/\" in str(xml_file) and xml_file.name.startswith(\"chart\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"chart\"]\n\n        if \"theme/\" in str(xml_file) and xml_file.name.startswith(\"theme\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"theme\"]\n\n        if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]\n\n        return None\n\n    def _clean_ignorable_namespaces(self, xml_doc):\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        for elem in xml_copy.iter():\n            attrs_to_remove = []\n\n            for attr in elem.attrib:\n                if \"{\" in attr:\n                    ns = attr.split(\"}\")[0][1:]\n                    if ns not in self.OOXML_NAMESPACES:\n                        attrs_to_remove.append(attr)\n\n            for attr in attrs_to_remove:\n                del elem.attrib[attr]\n\n        self._remove_ignorable_elements(xml_copy)\n\n        return lxml.etree.ElementTree(xml_copy)\n\n    def _remove_ignorable_elements(self, root):\n        elements_to_remove = []\n\n        for elem in list(root):\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n\n            tag_str = str(elem.tag)\n            if tag_str.startswith(\"{\"):\n                ns = tag_str.split(\"}\")[0][1:]\n                if ns not in self.OOXML_NAMESPACES:\n                    elements_to_remove.append(elem)\n                    continue\n\n            self._remove_ignorable_elements(elem)\n\n        for elem in elements_to_remove:\n            root.remove(elem)\n\n    def _preprocess_for_mc_ignorable(self, xml_doc):\n        root = xml_doc.getroot()\n\n        if f\"{{{self.MC_NAMESPACE}}}Ignorable\" in root.attrib:\n            del root.attrib[f\"{{{self.MC_NAMESPACE}}}Ignorable\"]\n\n        return xml_doc\n\n    def _validate_single_file_xsd(self, xml_file, base_path):\n        schema_path = self._get_schema_path(xml_file)\n        if not schema_path:\n            return None, None  \n\n        try:\n            with open(schema_path, \"rb\") as xsd_file:\n                parser = lxml.etree.XMLParser()\n                xsd_doc = lxml.etree.parse(\n                    xsd_file, parser=parser, base_url=str(schema_path)\n                )\n                schema = lxml.etree.XMLSchema(xsd_doc)\n\n            with open(xml_file, \"r\") as f:\n                xml_doc = lxml.etree.parse(f)\n\n            xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)\n            xml_doc = self._preprocess_for_mc_ignorable(xml_doc)\n\n            relative_path = xml_file.relative_to(base_path)\n            if (\n                relative_path.parts\n                and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS\n            ):\n                xml_doc = self._clean_ignorable_namespaces(xml_doc)\n\n            if schema.validate(xml_doc):\n                return True, set()\n            else:\n                errors = set()\n                for error in schema.error_log:\n                    errors.add(error.message)\n                return False, errors\n\n        except Exception as e:\n            return False, {str(e)}\n\n    def _get_original_file_errors(self, xml_file):\n        if self.original_file is None:\n            return set()\n\n        import tempfile\n        import zipfile\n\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n        relative_path = xml_file.relative_to(unpacked_dir)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                zip_ref.extractall(temp_path)\n\n            original_xml_file = temp_path / relative_path\n\n            if not original_xml_file.exists():\n                return set()\n\n            is_valid, errors = self._validate_single_file_xsd(\n                original_xml_file, temp_path\n            )\n            return errors if errors else set()\n\n    def _remove_template_tags_from_text_nodes(self, xml_doc):\n        warnings = []\n        template_pattern = re.compile(r\"\\{\\{[^}]*\\}\\}\")\n\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        def process_text_content(text, content_type):\n            if not text:\n                return text\n            matches = list(template_pattern.finditer(text))\n            if matches:\n                for match in matches:\n                    warnings.append(\n                        f\"Found template tag in {content_type}: {match.group()}\"\n                    )\n                return template_pattern.sub(\"\", text)\n            return text\n\n        for elem in xml_copy.iter():\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n            tag_str = str(elem.tag)\n            if tag_str.endswith(\"}t\") or tag_str == \"t\":\n                continue\n\n            elem.text = process_text_content(elem.text, \"text content\")\n            elem.tail = process_text_content(elem.tail, \"tail content\")\n\n        return lxml.etree.ElementTree(xml_copy), warnings\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/docx/scripts/office/validators/docx.py",
    "content": "\"\"\"\nValidator for Word document XML files against XSD schemas.\n\"\"\"\n\nimport random\nimport re\nimport tempfile\nimport zipfile\n\nimport defusedxml.minidom\nimport lxml.etree\n\nfrom .base import BaseSchemaValidator\n\n\nclass DOCXSchemaValidator(BaseSchemaValidator):\n\n    WORD_2006_NAMESPACE = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    W14_NAMESPACE = \"http://schemas.microsoft.com/office/word/2010/wordml\"\n    W16CID_NAMESPACE = \"http://schemas.microsoft.com/office/word/2016/wordml/cid\"\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_whitespace_preservation():\n            all_valid = False\n\n        if not self.validate_deletions():\n            all_valid = False\n\n        if not self.validate_insertions():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_id_constraints():\n            all_valid = False\n\n        if not self.validate_comment_markers():\n            all_valid = False\n\n        self.compare_paragraph_counts()\n\n        return all_valid\n\n    def validate_whitespace_preservation(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter(f\"{{{self.WORD_2006_NAMESPACE}}}t\"):\n                    if elem.text:\n                        text = elem.text\n                        if re.search(r\"^[ \\t\\n\\r]\", text) or re.search(\n                            r\"[ \\t\\n\\r]$\", text\n                        ):\n                            xml_space_attr = f\"{{{self.XML_NAMESPACE}}}space\"\n                            if (\n                                xml_space_attr not in elem.attrib\n                                or elem.attrib[xml_space_attr] != \"preserve\"\n                            ):\n                                text_preview = (\n                                    repr(text)[:50] + \"...\"\n                                    if len(repr(text)) > 50\n                                    else repr(text)\n                                )\n                                errors.append(\n                                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                    f\"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}\"\n                                )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} whitespace preservation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All whitespace is properly preserved\")\n            return True\n\n    def validate_deletions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                for t_elem in root.xpath(\".//w:del//w:t\", namespaces=namespaces):\n                    if t_elem.text:\n                        text_preview = (\n                            repr(t_elem.text)[:50] + \"...\"\n                            if len(repr(t_elem.text)) > 50\n                            else repr(t_elem.text)\n                        )\n                        errors.append(\n                            f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}\"\n                        )\n\n                for instr_elem in root.xpath(\n                    \".//w:del//w:instrText\", namespaces=namespaces\n                ):\n                    text_preview = (\n                        repr(instr_elem.text or \"\")[:50] + \"...\"\n                        if len(repr(instr_elem.text or \"\")) > 50\n                        else repr(instr_elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} deletion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:t elements found within w:del elements\")\n            return True\n\n    def count_paragraphs_in_unpacked(self):\n        count = 0\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n            except Exception as e:\n                print(f\"Error counting paragraphs in unpacked document: {e}\")\n\n        return count\n\n    def count_paragraphs_in_original(self):\n        original = self.original_file\n        if original is None:\n            return 0\n\n        count = 0\n\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                with zipfile.ZipFile(original, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_dir)\n\n                doc_xml_path = temp_dir + \"/word/document.xml\"\n                root = lxml.etree.parse(doc_xml_path).getroot()\n\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n\n        except Exception as e:\n            print(f\"Error counting paragraphs in original document: {e}\")\n\n        return count\n\n    def validate_insertions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                invalid_elements = root.xpath(\n                    \".//w:ins//w:delText[not(ancestor::w:del)]\", namespaces=namespaces\n                )\n\n                for elem in invalid_elements:\n                    text_preview = (\n                        repr(elem.text or \"\")[:50] + \"...\"\n                        if len(repr(elem.text or \"\")) > 50\n                        else repr(elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} insertion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:delText elements within w:ins elements\")\n            return True\n\n    def compare_paragraph_counts(self):\n        original_count = self.count_paragraphs_in_original()\n        new_count = self.count_paragraphs_in_unpacked()\n\n        diff = new_count - original_count\n        diff_str = f\"+{diff}\" if diff > 0 else str(diff)\n        print(f\"\\nParagraphs: {original_count} → {new_count} ({diff_str})\")\n\n    def _parse_id_value(self, val: str, base: int = 16) -> int:\n        return int(val, base)\n\n    def validate_id_constraints(self):\n        errors = []\n        para_id_attr = f\"{{{self.W14_NAMESPACE}}}paraId\"\n        durable_id_attr = f\"{{{self.W16CID_NAMESPACE}}}durableId\"\n\n        for xml_file in self.xml_files:\n            try:\n                for elem in lxml.etree.parse(str(xml_file)).iter():\n                    if val := elem.get(para_id_attr):\n                        if self._parse_id_value(val, base=16) >= 0x80000000:\n                            errors.append(\n                                f\"  {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000\"\n                            )\n\n                    if val := elem.get(durable_id_attr):\n                        if xml_file.name == \"numbering.xml\":\n                            try:\n                                if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:\n                                    errors.append(\n                                        f\"  {xml_file.name}:{elem.sourceline}: \"\n                                        f\"durableId={val} >= 0x7FFFFFFF\"\n                                    )\n                            except ValueError:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} must be decimal in numbering.xml\"\n                                )\n                        else:\n                            if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} >= 0x7FFFFFFF\"\n                                )\n            except Exception:\n                pass\n\n        if errors:\n            print(f\"FAILED - {len(errors)} ID constraint violations:\")\n            for e in errors:\n                print(e)\n        elif self.verbose:\n            print(\"PASSED - All paraId/durableId values within constraints\")\n        return not errors\n\n    def validate_comment_markers(self):\n        errors = []\n\n        document_xml = None\n        comments_xml = None\n        for xml_file in self.xml_files:\n            if xml_file.name == \"document.xml\" and \"word\" in str(xml_file):\n                document_xml = xml_file\n            elif xml_file.name == \"comments.xml\":\n                comments_xml = xml_file\n\n        if not document_xml:\n            if self.verbose:\n                print(\"PASSED - No document.xml found (skipping comment validation)\")\n            return True\n\n        try:\n            doc_root = lxml.etree.parse(str(document_xml)).getroot()\n            namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n            range_starts = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeStart\", namespaces=namespaces\n                )\n            }\n            range_ends = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeEnd\", namespaces=namespaces\n                )\n            }\n            references = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentReference\", namespaces=namespaces\n                )\n            }\n\n            orphaned_ends = range_ends - range_starts\n            for comment_id in sorted(\n                orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeEnd id=\"{comment_id}\" has no matching commentRangeStart'\n                )\n\n            orphaned_starts = range_starts - range_ends\n            for comment_id in sorted(\n                orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeStart id=\"{comment_id}\" has no matching commentRangeEnd'\n                )\n\n            comment_ids = set()\n            if comments_xml and comments_xml.exists():\n                comments_root = lxml.etree.parse(str(comments_xml)).getroot()\n                comment_ids = {\n                    elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                    for elem in comments_root.xpath(\n                        \".//w:comment\", namespaces=namespaces\n                    )\n                }\n\n                marker_ids = range_starts | range_ends | references\n                invalid_refs = marker_ids - comment_ids\n                for comment_id in sorted(\n                    invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0\n                ):\n                    if comment_id:  \n                        errors.append(\n                            f'  document.xml: marker id=\"{comment_id}\" references non-existent comment'\n                        )\n\n        except (lxml.etree.XMLSyntaxError, Exception) as e:\n            errors.append(f\"  Error parsing XML: {e}\")\n\n        if errors:\n            print(f\"FAILED - {len(errors)} comment marker violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All comment markers properly paired\")\n            return True\n\n    def repair(self) -> int:\n        repairs = super().repair()\n        repairs += self.repair_durableId()\n        return repairs\n\n    def repair_durableId(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if not elem.hasAttribute(\"w16cid:durableId\"):\n                        continue\n\n                    durable_id = elem.getAttribute(\"w16cid:durableId\")\n                    needs_repair = False\n\n                    if xml_file.name == \"numbering.xml\":\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n                    else:\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n\n                    if needs_repair:\n                        value = random.randint(1, 0x7FFFFFFE)\n                        if xml_file.name == \"numbering.xml\":\n                            new_id = str(value)  \n                        else:\n                            new_id = f\"{value:08X}\"  \n\n                        elem.setAttribute(\"w16cid:durableId\", new_id)\n                        print(\n                            f\"  Repaired: {xml_file.name}: durableId {durable_id} → {new_id}\"\n                        )\n                        repairs += 1\n                        modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/docx/scripts/office/validators/pptx.py",
    "content": "\"\"\"\nValidator for PowerPoint presentation XML files against XSD schemas.\n\"\"\"\n\nimport re\n\nfrom .base import BaseSchemaValidator\n\n\nclass PPTXSchemaValidator(BaseSchemaValidator):\n\n    PRESENTATIONML_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\"\n    )\n\n    ELEMENT_RELATIONSHIP_TYPES = {\n        \"sldid\": \"slide\",\n        \"sldmasterid\": \"slidemaster\",\n        \"notesmasterid\": \"notesmaster\",\n        \"sldlayoutid\": \"slidelayout\",\n        \"themeid\": \"theme\",\n        \"tablestyleid\": \"tablestyles\",\n    }\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_uuid_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_slide_layout_ids():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_notes_slide_references():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_no_duplicate_slide_layouts():\n            all_valid = False\n\n        return all_valid\n\n    def validate_uuid_ids(self):\n        import lxml.etree\n\n        errors = []\n        uuid_pattern = re.compile(\n            r\"^[\\{\\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\\}\\)]?$\"\n        )\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter():\n                    for attr, value in elem.attrib.items():\n                        attr_name = attr.split(\"}\")[-1].lower()\n                        if attr_name == \"id\" or attr_name.endswith(\"id\"):\n                            if self._looks_like_uuid(value):\n                                if not uuid_pattern.match(value):\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters\"\n                                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} UUID ID validation errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All UUID-like IDs contain valid hex values\")\n            return True\n\n    def _looks_like_uuid(self, value):\n        clean_value = value.strip(\"{}()\").replace(\"-\", \"\")\n        return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)\n\n    def validate_slide_layout_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        slide_masters = list(self.unpacked_dir.glob(\"ppt/slideMasters/*.xml\"))\n\n        if not slide_masters:\n            if self.verbose:\n                print(\"PASSED - No slide masters found\")\n            return True\n\n        for slide_master in slide_masters:\n            try:\n                root = lxml.etree.parse(str(slide_master)).getroot()\n\n                rels_file = slide_master.parent / \"_rels\" / f\"{slide_master.name}.rels\"\n\n                if not rels_file.exists():\n                    errors.append(\n                        f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                        f\"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}\"\n                    )\n                    continue\n\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                valid_layout_rids = set()\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"slideLayout\" in rel_type:\n                        valid_layout_rids.add(rel.get(\"Id\"))\n\n                for sld_layout_id in root.findall(\n                    f\".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId\"\n                ):\n                    r_id = sld_layout_id.get(\n                        f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\"\n                    )\n                    layout_id = sld_layout_id.get(\"id\")\n\n                    if r_id and r_id not in valid_layout_rids:\n                        errors.append(\n                            f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' \"\n                            f\"references r:id='{r_id}' which is not found in slide layout relationships\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {slide_master.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} slide layout ID validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"Remove invalid references or add missing slide layouts to the relationships file.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slide layout IDs reference valid slide layouts\")\n            return True\n\n    def validate_no_duplicate_slide_layouts(self):\n        import lxml.etree\n\n        errors = []\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                layout_rels = [\n                    rel\n                    for rel in root.findall(\n                        f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                    )\n                    if \"slideLayout\" in rel.get(\"Type\", \"\")\n                ]\n\n                if len(layout_rels) > 1:\n                    errors.append(\n                        f\"  {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references\"\n                    )\n\n            except Exception as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(\"FAILED - Found slides with duplicate slideLayout references:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slides have exactly one slideLayout reference\")\n            return True\n\n    def validate_notes_slide_references(self):\n        import lxml.etree\n\n        errors = []\n        notes_slide_references = {}  \n\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        if not slide_rels_files:\n            if self.verbose:\n                print(\"PASSED - No slide relationship files found\")\n            return True\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                for rel in root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"notesSlide\" in rel_type:\n                        target = rel.get(\"Target\", \"\")\n                        if target:\n                            normalized_target = target.replace(\"../\", \"\")\n\n                            slide_name = rels_file.stem.replace(\n                                \".xml\", \"\"\n                            )  \n\n                            if normalized_target not in notes_slide_references:\n                                notes_slide_references[normalized_target] = []\n                            notes_slide_references[normalized_target].append(\n                                (slide_name, rels_file)\n                            )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        for target, references in notes_slide_references.items():\n            if len(references) > 1:\n                slide_names = [ref[0] for ref in references]\n                errors.append(\n                    f\"  Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}\"\n                )\n                for slide_name, rels_file in references:\n                    errors.append(f\"    - {rels_file.relative_to(self.unpacked_dir)}\")\n\n        if errors:\n            print(\n                f\"FAILED - Found {len([e for e in errors if not e.startswith('    ')])} notes slide reference validation errors:\"\n            )\n            for error in errors:\n                print(error)\n            print(\"Each slide may optionally have its own slide file.\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All notes slide references are unique\")\n            return True\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/docx/scripts/office/validators/redlining.py",
    "content": "\"\"\"\nValidator for tracked changes in Word documents.\n\"\"\"\n\nimport subprocess\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\n\nclass RedliningValidator:\n\n    def __init__(self, unpacked_dir, original_docx, verbose=False, author=\"Claude\"):\n        self.unpacked_dir = Path(unpacked_dir)\n        self.original_docx = Path(original_docx)\n        self.verbose = verbose\n        self.author = author\n        self.namespaces = {\n            \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n        }\n\n    def repair(self) -> int:\n        return 0\n\n    def validate(self):\n        modified_file = self.unpacked_dir / \"word\" / \"document.xml\"\n        if not modified_file.exists():\n            print(f\"FAILED - Modified document.xml not found at {modified_file}\")\n            return False\n\n        try:\n            import xml.etree.ElementTree as ET\n\n            tree = ET.parse(modified_file)\n            root = tree.getroot()\n\n            del_elements = root.findall(\".//w:del\", self.namespaces)\n            ins_elements = root.findall(\".//w:ins\", self.namespaces)\n\n            author_del_elements = [\n                elem\n                for elem in del_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n            author_ins_elements = [\n                elem\n                for elem in ins_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n\n            if not author_del_elements and not author_ins_elements:\n                if self.verbose:\n                    print(f\"PASSED - No tracked changes by {self.author} found.\")\n                return True\n\n        except Exception:\n            pass\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            try:\n                with zipfile.ZipFile(self.original_docx, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_path)\n            except Exception as e:\n                print(f\"FAILED - Error unpacking original docx: {e}\")\n                return False\n\n            original_file = temp_path / \"word\" / \"document.xml\"\n            if not original_file.exists():\n                print(\n                    f\"FAILED - Original document.xml not found in {self.original_docx}\"\n                )\n                return False\n\n            try:\n                import xml.etree.ElementTree as ET\n\n                modified_tree = ET.parse(modified_file)\n                modified_root = modified_tree.getroot()\n                original_tree = ET.parse(original_file)\n                original_root = original_tree.getroot()\n            except ET.ParseError as e:\n                print(f\"FAILED - Error parsing XML files: {e}\")\n                return False\n\n            self._remove_author_tracked_changes(original_root)\n            self._remove_author_tracked_changes(modified_root)\n\n            modified_text = self._extract_text_content(modified_root)\n            original_text = self._extract_text_content(original_root)\n\n            if modified_text != original_text:\n                error_message = self._generate_detailed_diff(\n                    original_text, modified_text\n                )\n                print(error_message)\n                return False\n\n            if self.verbose:\n                print(f\"PASSED - All changes by {self.author} are properly tracked\")\n            return True\n\n    def _generate_detailed_diff(self, original_text, modified_text):\n        error_parts = [\n            f\"FAILED - Document text doesn't match after removing {self.author}'s tracked changes\",\n            \"\",\n            \"Likely causes:\",\n            \"  1. Modified text inside another author's <w:ins> or <w:del> tags\",\n            \"  2. Made edits without proper tracked changes\",\n            \"  3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion\",\n            \"\",\n            \"For pre-redlined documents, use correct patterns:\",\n            \"  - To reject another's INSERTION: Nest <w:del> inside their <w:ins>\",\n            \"  - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>\",\n            \"\",\n        ]\n\n        git_diff = self._get_git_word_diff(original_text, modified_text)\n        if git_diff:\n            error_parts.extend([\"Differences:\", \"============\", git_diff])\n        else:\n            error_parts.append(\"Unable to generate word diff (git not available)\")\n\n        return \"\\n\".join(error_parts)\n\n    def _get_git_word_diff(self, original_text, modified_text):\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                temp_path = Path(temp_dir)\n\n                original_file = temp_path / \"original.txt\"\n                modified_file = temp_path / \"modified.txt\"\n\n                original_file.write_text(original_text, encoding=\"utf-8\")\n                modified_file.write_text(modified_text, encoding=\"utf-8\")\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"--word-diff-regex=.\",  \n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n\n                    if content_lines:\n                        return \"\\n\".join(content_lines)\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n                    return \"\\n\".join(content_lines)\n\n        except (subprocess.CalledProcessError, FileNotFoundError, Exception):\n            pass\n\n        return None\n\n    def _remove_author_tracked_changes(self, root):\n        ins_tag = f\"{{{self.namespaces['w']}}}ins\"\n        del_tag = f\"{{{self.namespaces['w']}}}del\"\n        author_attr = f\"{{{self.namespaces['w']}}}author\"\n\n        for parent in root.iter():\n            to_remove = []\n            for child in parent:\n                if child.tag == ins_tag and child.get(author_attr) == self.author:\n                    to_remove.append(child)\n            for elem in to_remove:\n                parent.remove(elem)\n\n        deltext_tag = f\"{{{self.namespaces['w']}}}delText\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        for parent in root.iter():\n            to_process = []\n            for child in parent:\n                if child.tag == del_tag and child.get(author_attr) == self.author:\n                    to_process.append((child, list(parent).index(child)))\n\n            for del_elem, del_index in reversed(to_process):\n                for elem in del_elem.iter():\n                    if elem.tag == deltext_tag:\n                        elem.tag = t_tag\n\n                for child in reversed(list(del_elem)):\n                    parent.insert(del_index, child)\n                parent.remove(del_elem)\n\n    def _extract_text_content(self, root):\n        p_tag = f\"{{{self.namespaces['w']}}}p\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        paragraphs = []\n        for p_elem in root.findall(f\".//{p_tag}\"):\n            text_parts = []\n            for t_elem in p_elem.findall(f\".//{t_tag}\"):\n                if t_elem.text:\n                    text_parts.append(t_elem.text)\n            paragraph_text = \"\".join(text_parts)\n            if paragraph_text:\n                paragraphs.append(paragraph_text)\n\n        return \"\\n\".join(paragraphs)\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/docx/scripts/templates/comments.xml",
    "content": "<?xml version=\"1.0\" ?>\n<w:comments xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w:comments>\n"
  },
  {
    "path": "skills/docx/scripts/templates/commentsExtended.xml",
    "content": "<?xml version=\"1.0\" ?>\n<w15:commentsEx xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w15:commentsEx>\n"
  },
  {
    "path": "skills/docx/scripts/templates/commentsExtensible.xml",
    "content": "<?xml version=\"1.0\" ?>\n<w16cex:commentsExtensible xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" xmlns:cr=\"http://schemas.microsoft.com/office/comments/2020/reactions\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl cr w16du wp14\">\n</w16cex:commentsExtensible>\n"
  },
  {
    "path": "skills/docx/scripts/templates/commentsIds.xml",
    "content": "<?xml version=\"1.0\" ?>\n<w16cid:commentsIds xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w16cid:commentsIds>\n"
  },
  {
    "path": "skills/docx/scripts/templates/people.xml",
    "content": "<?xml version=\"1.0\" ?>\n<w15:people xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n</w15:people>\n"
  },
  {
    "path": "skills/frontend-design/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "skills/frontend-design/SKILL.md",
    "content": "---\nname: frontend-design\ndescription: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.\nlicense: Complete terms in LICENSE.txt\n---\n\nThis skill guides creation of distinctive, production-grade frontend interfaces that avoid generic \"AI slop\" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.\n\nThe user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.\n\n## Design Thinking\n\nBefore coding, understand the context and commit to a BOLD aesthetic direction:\n- **Purpose**: What problem does this interface solve? Who uses it?\n- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.\n- **Constraints**: Technical requirements (framework, performance, accessibility).\n- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?\n\n**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.\n\nThen implement working code (HTML/CSS/JS, React, Vue, etc.) that is:\n- Production-grade and functional\n- Visually striking and memorable\n- Cohesive with a clear aesthetic point-of-view\n- Meticulously refined in every detail\n\n## Frontend Aesthetics Guidelines\n\nFocus on:\n- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.\n- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.\n- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.\n- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.\n- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.\n\nNEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.\n\nInterpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.\n\n**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.\n\nRemember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.\n"
  },
  {
    "path": "skills/internal-comms/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/internal-comms/SKILL.md",
    "content": "---\nname: internal-comms\ndescription: A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).\nlicense: Complete terms in LICENSE.txt\n---\n\n## When to use this skill\nTo write internal communications, use this skill for:\n- 3P updates (Progress, Plans, Problems)\n- Company newsletters\n- FAQ responses\n- Status reports\n- Leadership updates\n- Project updates\n- Incident reports\n\n## How to use this skill\n\nTo write any internal communication:\n\n1. **Identify the communication type** from the request\n2. **Load the appropriate guideline file** from the `examples/` directory:\n    - `examples/3p-updates.md` - For Progress/Plans/Problems team updates\n    - `examples/company-newsletter.md` - For company-wide newsletters\n    - `examples/faq-answers.md` - For answering frequently asked questions\n    - `examples/general-comms.md` - For anything else that doesn't explicitly match one of the above\n3. **Follow the specific instructions** in that file for formatting, tone, and content gathering\n\nIf the communication type doesn't match any existing guideline, ask for clarification or more context about the desired format.\n\n## Keywords\n3P updates, company newsletter, company comms, weekly update, faqs, common questions, updates, internal comms\n"
  },
  {
    "path": "skills/internal-comms/examples/3p-updates.md",
    "content": "## Instructions\nYou are being asked to write a 3P update. 3P updates stand for \"Progress, Plans, Problems.\" The main audience is for executives, leadership, other teammates, etc. They're meant to be very succinct and to-the-point: think something you can read in 30-60sec or less. They're also for people with some, but not a lot of context on what the team does.\n\n3Ps can cover a team of any size, ranging all the way up to the entire company. The bigger the team, the less granular the tasks should be. For example, \"mobile team\" might have \"shipped feature\" or \"fixed bugs,\" whereas the company might have really meaty 3Ps, like \"hired 20 new people\" or \"closed 10 new deals.\" \n\nThey represent the work of the team across a time period, almost always one week. They include three sections:\n1) Progress: what the team has accomplished over the next time period. Focus mainly on things shipped, milestones achieved, tasks created, etc.\n2) Plans: what the team plans to do over the next time period. Focus on what things are top-of-mind, really high priority, etc. for the team.\n3) Problems: anything that is slowing the team down. This could be things like too few people, bugs or blockers that are preventing the team from moving forward, some deal that fell through, etc.\n\nBefore writing them, make sure that you know the team name. If it's not specified, you can ask explicitly what the team name you're writing for is.\n\n\n## Tools Available\nWhenever possible, try to pull from available sources to get the information you need:\n- Slack: posts from team members with their updates - ideally look for posts in large channels with lots of reactions\n- Google Drive: docs written from critical team members with lots of views\n- Email: emails with lots of responses of lots of content that seems relevant\n- Calendar: non-recurring meetings that have a lot of importance, like product reviews, etc.\n\n\nTry to gather as much context as you can, focusing on the things that covered the time period you're writing for:\n- Progress: anything between a week ago and today\n- Plans: anything from today to the next week\n- Problems: anything between a week ago and today\n\n\nIf you don't have access, you can ask the user for things they want to cover. They might also include these things to you directly, in which case you're mostly just formatting for this particular format.\n\n## Workflow\n\n1. **Clarify scope**: Confirm the team name and time period (usually past week for Progress/Problems, next\nweek for Plans)\n2. **Gather information**: Use available tools or ask the user directly\n3. **Draft the update**: Follow the strict formatting guidelines\n4. **Review**: Ensure it's concise (30-60 seconds to read) and data-driven\n\n## Formatting\n\nThe format is always the same, very strict formatting. Never use any formatting other than this. Pick an emoji that is fun and captures the vibe of the team and update.\n\n[pick an emoji] [Team Name] (Dates Covered, usually a week)\nProgress: [1-3 sentences of content]\nPlans: [1-3 sentences of content]\nProblems: [1-3 sentences of content]\n\nEach section should be no more than 1-3 sentences: clear, to the point. It should be data-driven, and generally include metrics where possible. The tone should be very matter-of-fact, not super prose-heavy."
  },
  {
    "path": "skills/internal-comms/examples/company-newsletter.md",
    "content": "## Instructions\nYou are being asked to write a company-wide newsletter update. You are meant to summarize the past week/month of a company in the form of a newsletter that the entire company will read. It should be maybe ~20-25 bullet points long. It will be sent via Slack and email, so make it consumable for that.\n\nIdeally it includes the following attributes:\n- Lots of links: pulling documents from Google Drive that are very relevant, linking to prominent Slack messages in announce channels and from executives, perhgaps referencing emails that went company-wide, highlighting significant things that have happened in the company.\n- Short and to-the-point: each bullet should probably be no longer than ~1-2 sentences\n- Use the \"we\" tense, as you are part of the company. Many of the bullets should say \"we did this\" or \"we did that\"\n\n## Tools to use\nIf you have access to the following tools, please try to use them. If not, you can also let the user know directly that their responses would be better if they gave them access.\n\n- Slack: look for messages in channels with lots of people, with lots of reactions or lots of responses within the thread\n- Email: look for things from executives that discuss company-wide announcements\n- Calendar: if there were meetings with large attendee lists, particularly things like All-Hands meetings, big company announcements, etc. If there were documents attached to those meetings, those are great links to include.\n- Documents: if there were new docs published in the last week or two that got a lot of attention, you can link them. These should be things like company-wide vision docs, plans for the upcoming quarter or half, things authored by critical executives, etc.\n- External press: if you see references to articles or press we've received over the past week, that could be really cool too.\n\nIf you don't have access to any of these things, you can ask the user for things they want to cover. In this case, you'll mostly just be polishing up and fitting to this format more directly.\n\n## Sections\nThe company is pretty big: 1000+ people. There are a variety of different teams and initiatives going on across the company. To make sure the update works well, try breaking it into sections of similar things. You might break into clusters like {product development, go to market, finance} or {recruiting, execution, vision}, or {external news, internal news} etc. Try to make sure the different areas of the company are highlighted well.\n\n## Prioritization\nFocus on:\n- Company-wide impact (not team-specific details)\n- Announcements from leadership\n- Major milestones and achievements\n- Information that affects most employees\n- External recognition or press\n\nAvoid:\n- Overly granular team updates (save those for 3Ps)\n- Information only relevant to small groups\n- Duplicate information already communicated\n\n## Example Formats\n\n:megaphone: Company Announcements\n- Announcement 1\n- Announcement 2\n- Announcement 3\n\n:dart: Progress on Priorities\n- Area 1\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n- Area 2\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n- Area 3\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n\n:pillar: Leadership Updates\n- Post 1\n- Post 2\n- Post 3\n\n:thread: Social Updates\n- Update 1\n- Update 2\n- Update 3\n"
  },
  {
    "path": "skills/internal-comms/examples/faq-answers.md",
    "content": "## Instructions\nYou are an assistant for answering questions that are being asked across the company. Every week, there are lots of questions that get asked across the company, and your goal is to try to summarize what those questions are. We want our company to be well-informed and on the same page, so your job is to produce a set of frequently asked questions that our employees are asking and attempt to answer them. Your singular job is to do two things:\n\n- Find questions that are big sources of confusion for lots of employees at the company, generally about things that affect a large portion of the employee base\n- Attempt to give a nice summarized answer to that question in order to minimize confusion.\n\nSome examples of areas that may be interesting to folks: recent corporate events (fundraising, new executives, etc.), upcoming launches, hiring progress, changes to vision or focus, etc.\n\n\n## Tools Available\nYou should use the company's available tools, where communication and work happens. For most companies, it looks something like this:\n- Slack: questions being asked across the company - it could be questions in response to posts with lots of responses, questions being asked with lots of reactions or thumbs up to show support, or anything else to show that a large number of employees want to ask the same things\n- Email: emails with FAQs written directly in them can be a good source as well\n- Documents: docs in places like Google Drive, linked on calendar events, etc. can also be a good source of FAQs, either directly added or inferred based on the contents of the doc\n\n## Formatting\nThe formatting should be pretty basic:\n\n- *Question*: [insert question - 1 sentence]\n- *Answer*: [insert answer - 1-2 sentence]\n\n## Guidance\nMake sure you're being holistic in your questions. Don't focus too much on just the user in question or the team they are a part of, but try to capture the entire company. Try to be as holistic as you can in reading all the tools available, producing responses that are relevant to all at the company.\n\n## Answer Guidelines\n- Base answers on official company communications when possible\n- If information is uncertain, indicate that clearly\n- Link to authoritative sources (docs, announcements, emails)\n- Keep tone professional but approachable\n- Flag if a question requires executive input or official response"
  },
  {
    "path": "skills/internal-comms/examples/general-comms.md",
    "content": "  ## Instructions\n  You are being asked to write internal company communication that doesn't fit into the standard formats (3P\n  updates, newsletters, or FAQs).\n\n  Before proceeding:\n  1. Ask the user about their target audience\n  2. Understand the communication's purpose\n  3. Clarify the desired tone (formal, casual, urgent, informational)\n  4. Confirm any specific formatting requirements\n\n  Use these general principles:\n  - Be clear and concise\n  - Use active voice\n  - Put the most important information first\n  - Include relevant links and references\n  - Match the company's communication style"
  },
  {
    "path": "skills/mac-use/SKILL.md",
    "content": "---\nname: mac-use\ndescription: Control macOS GUI apps visually — take screenshots, click, scroll, type. Use when the user asks to interact with any Mac desktop application's graphical interface.\nmetadata: {\"openclaw\":{\"emoji\":\"🖥️\",\"requires\":{\"bins\":[\"python3\"]},\"os\":[\"darwin\"],\"install\":[{\"id\":\"python-brew\",\"kind\":\"brew\",\"formula\":\"python\",\"bins\":[\"python3\"],\"label\":\"Install Python 3 (brew)\"}]}}\n---\n\n# Mac Use\n\nControl any macOS GUI application through a **screenshot → pick element → click → verify** loop.\n\n## Setup\n\n**Platform**: macOS only (requires Apple Vision framework for OCR)\n\n**System binaries** (pre-installed on macOS):\n- `python3` — via Homebrew (`brew install python`)\n- `screencapture` — built-in macOS utility\n\n**Python packages** — install from the skill directory:\n```bash\npip3 install --break-system-packages -r {baseDir}/requirements.txt\n```\n\n## How It Works\n\nThe `screenshot` command captures a window, uses **Apple Vision OCR** to detect all text elements, draws numbered annotations on the image, and returns both:\n1. **Annotated image** at `/tmp/mac_use.png` — numbered green boxes around each detected text\n2. **Element list** in JSON — `[{num: 1, text: \"Submit\", at: [500, 200]}, {num: 2, text: \"Cancel\", at: [600, 200]}, ...]` where `at` is the center point `[x, y]` on the 1000x1000 canvas (origin at top-left)\n\nYou receive both by calling Bash (gets JSON with element list) and then Read on `/tmp/mac_use.png` (gets the visual). **Always do both** so you can cross-reference the numbers with what you see.\n\n## Quick Reference\n\n```bash\n# List all visible windows\npython3 {baseDir}/scripts/mac_use.py list\n\n# Screenshot + annotate (returns image + numbered element list)\npython3 {baseDir}/scripts/mac_use.py screenshot <app> [--id N]\n\n# Click element by number (primary click method)\npython3 {baseDir}/scripts/mac_use.py clicknum <N>\n\n# Click at canvas coordinates (fallback for unlabeled icons)\npython3 {baseDir}/scripts/mac_use.py click --app <app> [--id N] <x> <y>\n\n# Scroll inside a window\npython3 {baseDir}/scripts/mac_use.py scroll --app <app> [--id N] <direction> <amount>\n\n# Type text (uses clipboard paste — supports all languages)\npython3 {baseDir}/scripts/mac_use.py type [--app <app>] \"text here\"\n\n# Press key or combo\npython3 {baseDir}/scripts/mac_use.py key [--app <app>] <combo>\n```\n\n## Workflow\n\n1. **Open** the target app with `open -a \"App Name\"` (optionally with a URL or file path)\n2. **Wait** for it to load: `sleep 2`\n3. **Screenshot** the app:\n   ```bash\n   python3 {baseDir}/scripts/mac_use.py screenshot <app> [--id N]\n   ```\n   This returns JSON with `file` (image path) and `elements` (numbered text list).\n4. **Read** the annotated image at `/tmp/mac_use.png` to see the numbered elements visually\n5. **Decide** which element to interact with:\n   - **Prefer `clicknum N`** — pick the number of a detected text element\n   - **Fallback `click --app <app> x y`** — only for unlabeled icons (arrows, close buttons, cart icons) that have no text and therefore no number\n6. **Act** using `clicknum`, `type`, `key`, or `scroll`\n7. **Screenshot again** to verify the result\n8. Repeat from step 3\n\n## Commands\n\n### list\n\nShow all visible app windows.\n\n```bash\npython3 {baseDir}/scripts/mac_use.py list\n```\n\nReturns JSON array: `[{\"app\":\"Google Chrome\",\"title\":\"Wikipedia\",\"id\":4527,\"x\":120,\"y\":80,\"w\":1200,\"h\":800}, ...]`\n\n### screenshot\n\nCapture a window, detect text elements via OCR, annotate with numbered markers, and return the element list. The target window is automatically raised to the top before capture, so overlapping windows are handled.\n\n```bash\npython3 {baseDir}/scripts/mac_use.py screenshot chrome\npython3 {baseDir}/scripts/mac_use.py screenshot chrome --id 4527\n```\n\n- `<app>`: fuzzy, case-insensitive match (e.g. \"chrome\" matches \"Google Chrome\")\n- `--id N`: target a specific window ID (required when multiple windows of the same app exist)\n- Returns JSON with:\n  - `file`: path to annotated screenshot (`/tmp/mac_use.png`)\n  - `id`, `app`, `title`, `scale`: window metadata\n  - `elements`: array of `{num, text, at}` — the numbered clickable text elements, where `at` is `[x, y]` center coordinates on the 1000x1000 canvas (origin at top-left)\n- If multiple windows match, returns a list of windows instead — pick one and retry with `--id`\n- The image is 1000x1000 pixels with green bounding boxes and blue number badges\n- Element map is saved to `/tmp/mac_use_elements.json` for `clicknum`\n\n### clicknum\n\nClick on a numbered element from the last screenshot. **This is the primary click method.**\n\n```bash\npython3 {baseDir}/scripts/mac_use.py clicknum 5\npython3 {baseDir}/scripts/mac_use.py clicknum 12\n```\n\n- `N`: the element number from the last `screenshot` output\n- Reads the saved element map, activates the window, and clicks at the element's center\n- Returns JSON with `clicked_num`, `text`, canvas coords, and absolute screen coords\n\n### click\n\nClick at a position using canvas coordinates. **Fallback only — use for unlabeled icons.**\n\n```bash\npython3 {baseDir}/scripts/mac_use.py click --app chrome 500 300\npython3 {baseDir}/scripts/mac_use.py click --app chrome --id 4527 500 300\n```\n\n- **Coordinates are canvas positions (0-1000)** from the screenshot image\n- x=0 is left, x=1000 is right; y=0 is top, y=1000 is bottom\n- Use this only when Vision OCR didn't detect the element (icon-only buttons, images, etc.)\n\n### scroll\n\nScroll inside an app window.\n\n```bash\npython3 {baseDir}/scripts/mac_use.py scroll --app chrome down 5\npython3 {baseDir}/scripts/mac_use.py scroll --app notes up 10\n```\n\n- Directions: `up`, `down`, `left`, `right`\n- Amount: number of scroll clicks (3-5 for moderate, 10+ for fast scrolling)\n- Mouse is moved to the center of the window before scrolling\n\n### type\n\nType text into the currently focused input field.\n\n```bash\npython3 {baseDir}/scripts/mac_use.py type --app chrome \"hello world\"\npython3 {baseDir}/scripts/mac_use.py type --app chrome \"你好世界\"\n```\n\n- `--app`: activates the app first to ensure keystrokes go to the right window\n- Uses clipboard paste (Cmd+V) for reliable Unicode/CJK support\n- **Always click on the target input field first** before typing\n\n### key\n\nPress a single key or key combination.\n\n```bash\npython3 {baseDir}/scripts/mac_use.py key --app chrome return\npython3 {baseDir}/scripts/mac_use.py key --app chrome cmd+a\npython3 {baseDir}/scripts/mac_use.py key --app chrome cmd+shift+s\n```\n\n- `--app`: activates the app first\n- Common keys: `return`, `tab`, `escape`, `space`, `delete`, `backspace`, `up`, `down`, `left`, `right`\n- Modifiers: `cmd`, `ctrl`, `alt`/`opt`, `shift`\n\n## Important Rules\n\n- **Always screenshot before your first interaction** with an app\n- **Always screenshot after an action** to verify the result\n- **Always Read the screenshot image** after running the screenshot command — you need both the element list AND the visual\n- **Prefer `clicknum`** over `click` — only use direct coordinates for unlabeled icons\n- **Click before typing** — ensure the correct input field has focus first\n- **Multiple windows**: if you get `multiple_windows` error, use `list` to see all windows, then pass `--id`\n- **Popup windows** (like WeChat mini-program panels) are separate windows with their own IDs — use `list` to find them and `--id` to target them\n- **Wait after opening apps**: use `sleep 2-3` after `open -a` before taking a screenshot\n- **Activate the app** before screenshot/click: prepend `osascript -e 'tell application \"AppName\" to activate' && sleep 1` when the target app may be behind other windows\n- **Do not type passwords or secrets** via this tool\n\n## Coordinate System (for fallback `click` only)\n\nScreenshots are rendered onto a **1000x1000 canvas**:\n- **Origin (0, 0)** is at the **top-left** corner\n- **x** increases left to right (0 = left edge, 1000 = right edge)\n- **y** increases top to bottom (0 = top edge, 1000 = bottom edge)\n- The app window is scaled to fit (aspect ratio preserved), centered, with dark gray padding\n\n## Example: Order food on Meituan in WeChat\n\n```bash\n# 1. Open WeChat\nopen -a \"WeChat\"\nsleep 3\n\n# 2. Screenshot WeChat — find the mini program window\npython3 {baseDir}/scripts/mac_use.py list\n# → find the mini program window ID\n\n# 3. Screenshot the mini program (annotated + element list)\npython3 {baseDir}/scripts/mac_use.py screenshot 微信 --id 41266\n# → returns: {\"file\": \"/tmp/mac_use.png\", \"elements\": [{num: 1, text: \"搜索\", at: [500, 200]}, ...]}\n# → Read /tmp/mac_use.png to see annotated image\n\n# 4. Click \"搜索\" (element #1)\npython3 {baseDir}/scripts/mac_use.py clicknum 1\n\n# 5. Type search query\npython3 {baseDir}/scripts/mac_use.py type --app 微信 \"炸鸡\"\n\n# 6. Press Enter\npython3 {baseDir}/scripts/mac_use.py key --app 微信 return\nsleep 2\n\n# 7. Screenshot to see results\npython3 {baseDir}/scripts/mac_use.py screenshot 微信 --id 41266\n# → Read /tmp/mac_use.png, pick a restaurant by number\n\n# 8. Click on a restaurant (e.g. element #5)\npython3 {baseDir}/scripts/mac_use.py clicknum 5\n```\n"
  },
  {
    "path": "skills/mac-use/requirements.txt",
    "content": "pyobjc-framework-Vision>=12.0\npyautogui>=0.9\nPillow>=10.0\n"
  },
  {
    "path": "skills/mac-use/scripts/mac_use.py",
    "content": "#!/usr/bin/env python3\n\"\"\"mac_use.py - macOS GUI automation helper.\n\nSubcommands:\n  list                              List all visible app windows\n  screenshot <app> [--id N]         Capture + annotate an app's window\n  clicknum <N>                      Click element N from last screenshot\n  click --app <app> [--id N] x y    Click at canvas coords (0-1000)\n  scroll --app <app> [--id N] <dir> <amount>  Scroll inside a window\n  type <text>                       Type text (via clipboard paste)\n  key <combo>                       Press key combo (e.g. return, cmd+v)\n\"\"\"\n\nimport argparse\nimport json\nimport re\nimport subprocess\nimport sys\nimport time\n\nimport pyautogui\nimport Vision\nimport Quartz\nfrom Foundation import NSURL\nfrom PIL import Image, ImageDraw, ImageFont\nfrom Quartz import (\n    CGWindowListCopyWindowInfo,\n    kCGWindowListOptionOnScreenOnly,\n    kCGNullWindowID,\n)\n\n# Keep failsafe on but set a short pause\npyautogui.FAILSAFE = True\npyautogui.PAUSE = 0.05\n\nSCREENSHOT_PATH = \"/tmp/mac_use.png\"\nSCREENSHOT_FULL = \"/tmp/mac_use_full.png\"\nELEMENTS_FILE = \"/tmp/mac_use_elements.json\"\nCANVAS_SIZE = 1000\n\n\n# ---------------------------------------------------------------------------\n# Window helpers\n# ---------------------------------------------------------------------------\n\ndef get_windows():\n    \"\"\"Return all visible normal windows as a list of dicts.\"\"\"\n    raw = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID)\n    windows = []\n    for w in raw:\n        if w.get(\"kCGWindowLayer\", -1) != 0:\n            continue\n        name = w.get(\"kCGWindowOwnerName\", \"\")\n        title = w.get(\"kCGWindowName\", \"\")\n        wid = w.get(\"kCGWindowNumber\", 0)\n        bounds = w.get(\"kCGWindowBounds\", {})\n        if not name or not wid:\n            continue\n        bw = int(bounds.get(\"Width\", 0))\n        bh = int(bounds.get(\"Height\", 0))\n        if bw < 50 or bh < 50:\n            continue\n        windows.append({\n            \"app\": str(name),\n            \"title\": str(title) if title else \"\",\n            \"id\": int(wid),\n            \"x\": int(bounds.get(\"X\", 0)),\n            \"y\": int(bounds.get(\"Y\", 0)),\n            \"w\": bw,\n            \"h\": bh,\n        })\n    return windows\n\n\ndef find_window(app_name, window_id=None):\n    \"\"\"Find window(s) by fuzzy app name and optional ID.\"\"\"\n    windows = get_windows()\n    app_lower = app_name.lower()\n    matches = [w for w in windows if app_lower in w[\"app\"].lower()]\n\n    if not matches:\n        all_apps = sorted(set(w[\"app\"] for w in windows))\n        return None, {\n            \"error\": \"no_window\",\n            \"message\": f\"No visible window matching '{app_name}'\",\n            \"available_apps\": all_apps,\n        }\n\n    if window_id is not None:\n        for w in matches:\n            if w[\"id\"] == window_id:\n                return w, None\n        return None, {\n            \"error\": \"window_id_not_found\",\n            \"message\": f\"No window with ID {window_id} for '{app_name}'\",\n            \"windows\": matches,\n        }\n\n    if len(matches) == 1:\n        return matches[0], None\n\n    return None, {\n        \"error\": \"multiple_windows\",\n        \"message\": f\"Multiple windows match '{app_name}'. Pass --id to choose one.\",\n        \"windows\": matches,\n    }\n\n\ndef get_display_scale():\n    \"\"\"Get the display's backing scale factor directly from Quartz.\"\"\"\n    try:\n        from Quartz import (\n            CGDisplayCopyDisplayMode, CGMainDisplayID,\n            CGDisplayModeGetPixelWidth, CGDisplayModeGetWidth,\n        )\n        mode = CGDisplayCopyDisplayMode(CGMainDisplayID())\n        pixel_w = CGDisplayModeGetPixelWidth(mode)\n        logical_w = CGDisplayModeGetWidth(mode)\n        if logical_w > 0:\n            s = pixel_w / logical_w\n            if 0.8 < s < 1.2:\n                return 1.0\n            elif 1.8 < s < 2.2:\n                return 2.0\n            return s\n    except Exception:\n        pass\n    return 1.0\n\n\ndef activate_app(app_name):\n    \"\"\"Bring an app to the foreground.\"\"\"\n    subprocess.run(\n        [\"osascript\", \"-e\", f'tell application \"{app_name}\" to activate'],\n        capture_output=True,\n        timeout=5,\n    )\n    time.sleep(0.3)\n\n\ndef raise_window(app_name, window_title):\n    \"\"\"Raise a specific window to the top of the window stack via AXRaise.\"\"\"\n    # Escape double quotes in the title for AppleScript\n    safe_title = window_title.replace('\\\\', '\\\\\\\\').replace('\"', '\\\\\"')\n    script = (\n        f'tell application \"System Events\" to tell process \"{app_name}\" '\n        f'to perform action \"AXRaise\" of window \"{safe_title}\"'\n    )\n    try:\n        subprocess.run([\"osascript\", \"-e\", script], capture_output=True, timeout=5)\n        time.sleep(0.3)\n    except Exception:\n        pass\n\n\ndef activate_and_find(app_name, window_id=None):\n    \"\"\"Activate app first (restores from Stage Manager), then find window.\"\"\"\n    windows = get_windows()\n    app_lower = app_name.lower()\n    matches = [w for w in windows if app_lower in w[\"app\"].lower()]\n    if matches:\n        activate_app(matches[0][\"app\"])\n        time.sleep(0.3)\n    return find_window(app_name, window_id)\n\n\ndef output(data):\n    \"\"\"Print JSON to stdout.\"\"\"\n    print(json.dumps(data, ensure_ascii=False))\n\n\ndef fail(data):\n    \"\"\"Print JSON error to stdout and exit 1.\"\"\"\n    output(data)\n    sys.exit(1)\n\n\n# ---------------------------------------------------------------------------\n# Canvas helpers\n# ---------------------------------------------------------------------------\n\ndef reliable_click(x, y):\n    \"\"\"Click using CGEvent with proper click count and timing.\n    More reliable than pyautogui for webviews and mini programs.\n    \"\"\"\n    from Quartz import (\n        CGEventCreateMouseEvent, CGEventPost,\n        CGEventSetIntegerValueField,\n        kCGEventLeftMouseDown, kCGEventLeftMouseUp,\n        kCGMouseButtonLeft, kCGHIDEventTap,\n        kCGMouseEventClickState,\n    )\n    point = (x, y)\n    # Move mouse first so the window registers hover\n    pyautogui.moveTo(x, y)\n    time.sleep(0.15)\n    # mouseDown with clickState=1\n    down = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, point, kCGMouseButtonLeft)\n    CGEventSetIntegerValueField(down, kCGMouseEventClickState, 1)\n    CGEventPost(kCGHIDEventTap, down)\n    time.sleep(0.08)\n    # mouseUp with clickState=1\n    up = CGEventCreateMouseEvent(None, kCGEventLeftMouseUp, point, kCGMouseButtonLeft)\n    CGEventSetIntegerValueField(up, kCGMouseEventClickState, 1)\n    CGEventPost(kCGHIDEventTap, up)\n\n\ndef canvas_to_abs(canvas_x, canvas_y, win, scale):\n    \"\"\"Convert canvas coordinates (0-1000) to absolute screen coordinates.\"\"\"\n    orig_w = int(win[\"w\"] * scale)\n    orig_h = int(win[\"h\"] * scale)\n    fit = min(CANVAS_SIZE / orig_w, CANVAS_SIZE / orig_h)\n    new_w = int(orig_w * fit)\n    new_h = int(orig_h * fit)\n    ox = (CANVAS_SIZE - new_w) / 2\n    oy = (CANVAS_SIZE - new_h) / 2\n\n    orig_px = (canvas_x - ox) / fit\n    orig_py = (canvas_y - oy) / fit\n\n    abs_x = win[\"x\"] + orig_px / scale\n    abs_y = win[\"y\"] + orig_py / scale\n    return abs_x, abs_y\n\n\n# ---------------------------------------------------------------------------\n# Screenshot, detection & annotation\n# ---------------------------------------------------------------------------\n\ndef capture_full_screen():\n    \"\"\"Take a full-screen screenshot. Returns True on success.\"\"\"\n    r = subprocess.run(\n        [\"/usr/sbin/screencapture\", \"-x\", SCREENSHOT_FULL],\n        capture_output=True, timeout=10,\n    )\n    return r.returncode == 0\n\n\ndef crop_window(win):\n    \"\"\"Crop the full-screen screenshot to a window's bounds,\n    then fit into a CANVAS_SIZE x CANVAS_SIZE square (no grid overlay).\n    \"\"\"\n    img = Image.open(SCREENSHOT_FULL)\n    img_w, img_h = img.size\n\n    scale = get_display_scale()\n\n    left = int(win[\"x\"] * scale)\n    top = int(win[\"y\"] * scale)\n    right = int((win[\"x\"] + win[\"w\"]) * scale)\n    bottom = int((win[\"y\"] + win[\"h\"]) * scale)\n\n    left = max(0, left)\n    top = max(0, top)\n    right = min(img_w, right)\n    bottom = min(img_h, bottom)\n\n    cropped = img.crop((left, top, right, bottom))\n    orig_w, orig_h = cropped.size\n\n    fit = min(CANVAS_SIZE / orig_w, CANVAS_SIZE / orig_h)\n    new_w = int(orig_w * fit)\n    new_h = int(orig_h * fit)\n    resized = cropped.resize((new_w, new_h), Image.LANCZOS)\n\n    canvas = Image.new(\"RGBA\", (CANVAS_SIZE, CANVAS_SIZE), (128, 128, 128, 255))\n    ox = (CANVAS_SIZE - new_w) // 2\n    oy = (CANVAS_SIZE - new_h) // 2\n    canvas.paste(resized.convert(\"RGBA\"), (ox, oy))\n\n    canvas = canvas.convert(\"RGB\")\n    canvas.save(SCREENSHOT_PATH)\n    return scale\n\n\ndef detect_text_elements(image_path):\n    \"\"\"Use Vision framework to detect text regions in an image.\n    Returns list of dicts with text, position, size in canvas coords (0-1000).\n    \"\"\"\n    img_url = NSURL.fileURLWithPath_(image_path)\n    img_source = Quartz.CGImageSourceCreateWithURL(img_url, None)\n    if not img_source:\n        return []\n    cg_image = Quartz.CGImageSourceCreateImageAtIndex(img_source, 0, None)\n    if not cg_image:\n        return []\n\n    request = Vision.VNRecognizeTextRequest.alloc().init()\n    request.setRecognitionLanguages_([\"zh-Hans\", \"en\"])\n    request.setRecognitionLevel_(Vision.VNRequestTextRecognitionLevelAccurate)\n\n    handler = Vision.VNImageRequestHandler.alloc().initWithCGImage_options_(\n        cg_image, None\n    )\n    success, err = handler.performRequests_error_([request], None)\n    if not success:\n        return []\n\n    elements = []\n    for obs in request.results():\n        candidate = obs.topCandidates_(1)[0]\n        text = candidate.string()\n        conf = candidate.confidence()\n        box = obs.boundingBox()\n\n        # Vision coords: bottom-left origin, normalized 0-1\n        # Canvas coords: top-left origin, 0-1000\n        x1 = box.origin.x * CANVAS_SIZE\n        y1 = (1.0 - box.origin.y - box.size.height) * CANVAS_SIZE\n        w = box.size.width * CANVAS_SIZE\n        h = box.size.height * CANVAS_SIZE\n        cx = x1 + w / 2\n        cy = y1 + h / 2\n\n        elements.append({\n            \"text\": text,\n            \"at\": [round(cx), round(cy)],\n            \"x1\": round(x1),\n            \"y1\": round(y1),\n            \"w\": round(w),\n            \"h\": round(h),\n            \"conf\": round(conf, 2),\n        })\n\n    return elements\n\n\ndef is_noise(elem):\n    \"\"\"Filter out noise elements.\"\"\"\n    text = elem[\"text\"].strip()\n\n    # Grid labels: 100-900 in multiples of 100\n    if re.match(r\"^\\d{3}$\", text):\n        val = int(text)\n        if val % 100 == 0 and 100 <= val <= 900:\n            return True\n\n    # Single/double digit numbers (badge counts, noise)\n    if re.match(r\"^\\d{1,2}$\", text):\n        return True\n\n    # Single punctuation or symbols\n    if re.match(r\"^[•·\\.\\*\\-—_=|/\\\\:;,!?~`\\s！？。，、]+$\", text):\n        return True\n\n    return False\n\n\ndef draw_annotations(image_path, elements, output_path):\n    \"\"\"Draw numbered markers on the screenshot for each element.\"\"\"\n    img = Image.open(image_path).convert(\"RGBA\")\n    overlay = Image.new(\"RGBA\", img.size, (0, 0, 0, 0))\n    draw = ImageDraw.Draw(overlay, \"RGBA\")\n\n    try:\n        font = ImageFont.truetype(\"/System/Library/Fonts/Helvetica.ttc\", 14)\n    except Exception:\n        font = ImageFont.load_default()\n\n    for elem in elements:\n        num = elem[\"num\"]\n        x1, y1, w, h = elem[\"x1\"], elem[\"y1\"], elem[\"w\"], elem[\"h\"]\n\n        # Green bounding box\n        draw.rectangle(\n            [(x1 - 1, y1 - 1), (x1 + w + 1, y1 + h + 1)],\n            outline=(0, 200, 0, 180),\n            width=2,\n        )\n\n        # Blue number badge\n        label = str(num)\n        bbox = font.getbbox(label)\n        tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]\n        pad = 3\n\n        bx = x1 - 2\n        by = y1 - th - pad * 2 - 2\n        if by < 0:\n            by = y1 + h + 2\n\n        draw.rectangle(\n            [(bx, by), (bx + tw + pad * 2, by + th + pad * 2)],\n            fill=(0, 120, 255, 220),\n        )\n        draw.text((bx + pad, by + pad), label, fill=(255, 255, 255, 255), font=font)\n\n    result = Image.alpha_composite(img, overlay).convert(\"RGB\")\n    result.save(output_path)\n\n\n# ---------------------------------------------------------------------------\n# Subcommands\n# ---------------------------------------------------------------------------\n\ndef cmd_list(_args):\n    windows = get_windows()\n    output(windows)\n\n\ndef cmd_screenshot(args):\n    win, err = activate_and_find(args.app, args.id)\n    if err:\n        fail(err)\n\n    # Re-activate app and raise the specific window to the top\n    activate_app(win[\"app\"])\n    if win.get(\"title\"):\n        raise_window(win[\"app\"], win[\"title\"])\n\n    if not capture_full_screen():\n        fail({\"error\": \"screenshot_failed\",\n              \"message\": \"screencapture failed. Check Screen Recording permission.\"})\n    try:\n        scale = crop_window(win)\n    except Exception as e:\n        fail({\"error\": \"crop_failed\", \"message\": str(e)})\n\n    # Detect text elements\n    all_elements = detect_text_elements(SCREENSHOT_PATH)\n\n    # Filter noise, require minimum confidence\n    elements = [\n        e for e in all_elements\n        if not is_noise(e) and e[\"conf\"] >= 0.1 and len(e[\"text\"].strip()) > 0\n    ]\n\n    # Sort top-to-bottom, left-to-right\n    elements.sort(key=lambda e: (e[\"at\"][1] // 30, e[\"at\"][0]))\n\n    # Number them\n    for i, elem in enumerate(elements):\n        elem[\"num\"] = i + 1\n\n    # Draw annotations onto screenshot\n    draw_annotations(SCREENSHOT_PATH, elements, SCREENSHOT_PATH)\n\n    # Save element map for clicknum\n    with open(ELEMENTS_FILE, \"w\") as f:\n        json.dump({\n            \"window\": {\n                \"id\": win[\"id\"],\n                \"app\": win[\"app\"],\n                \"title\": win[\"title\"],\n                \"x\": win[\"x\"], \"y\": win[\"y\"],\n                \"w\": win[\"w\"], \"h\": win[\"h\"],\n            },\n            \"scale\": scale,\n            \"elements\": elements,\n        }, f, ensure_ascii=False, indent=2)\n\n    output({\n        \"file\": SCREENSHOT_PATH,\n        \"id\": win[\"id\"],\n        \"app\": win[\"app\"],\n        \"title\": win[\"title\"],\n        \"scale\": scale,\n        \"elements\": [\n            {\"num\": e[\"num\"], \"text\": e[\"text\"], \"at\": e[\"at\"]}\n            for e in elements\n        ],\n    })\n\n\ndef cmd_clicknum(args):\n    \"\"\"Click on element N from the last screenshot.\"\"\"\n    try:\n        with open(ELEMENTS_FILE) as f:\n            data = json.load(f)\n    except FileNotFoundError:\n        fail({\"error\": \"no_elements\", \"message\": \"Run screenshot first.\"})\n\n    num = args.num\n    elements = data[\"elements\"]\n    match = [e for e in elements if e[\"num\"] == num]\n    if not match:\n        fail({\n            \"error\": \"invalid_num\",\n            \"message\": f\"Element {num} not found. Valid: 1-{len(elements)}\",\n        })\n\n    elem = match[0]\n    win_data = data[\"window\"]\n    scale = data[\"scale\"]\n\n    # Activate window\n    win, err = activate_and_find(win_data[\"app\"], win_data[\"id\"])\n    if err:\n        fail(err)\n\n    # Convert canvas coords to absolute screen coords\n    abs_x, abs_y = canvas_to_abs(elem[\"at\"][0], elem[\"at\"][1], win, scale)\n\n    reliable_click(abs_x, abs_y)\n\n    output({\n        \"ok\": True,\n        \"clicked_num\": num,\n        \"text\": elem[\"text\"],\n        \"canvas\": elem[\"at\"],\n        \"abs\": [round(abs_x), round(abs_y)],\n    })\n\n\ndef cmd_click(args):\n    win, err = activate_and_find(args.app, args.id)\n    if err:\n        fail(err)\n\n    scale = get_display_scale()\n    abs_x, abs_y = canvas_to_abs(args.x, args.y, win, scale)\n\n    reliable_click(abs_x, abs_y)\n\n    output({\"ok\": True, \"clicked\": [round(abs_x), round(abs_y)], \"scale\": scale})\n\n\ndef cmd_scroll(args):\n    win, err = activate_and_find(args.app, args.id)\n    if err:\n        fail(err)\n\n    cx = win[\"x\"] + win[\"w\"] / 2\n    cy = win[\"y\"] + win[\"h\"] / 2\n    pyautogui.moveTo(cx, cy)\n\n    d = args.direction.lower()\n    n = args.amount\n    if d == \"down\":\n        pyautogui.scroll(-n)\n    elif d == \"up\":\n        pyautogui.scroll(n)\n    elif d == \"left\":\n        pyautogui.hscroll(-n)\n    elif d == \"right\":\n        pyautogui.hscroll(n)\n    else:\n        fail({\"error\": \"invalid_direction\", \"message\": f\"Use up/down/left/right, got '{d}'\"})\n\n    output({\"ok\": True, \"scrolled\": d, \"amount\": n})\n\n\ndef keystroke_via_osascript(key, modifiers=None):\n    \"\"\"Send a keystroke via osascript (System Events).\"\"\"\n    if modifiers:\n        if len(modifiers) == 1:\n            mod_str = f\" using {modifiers[0]} down\"\n        else:\n            mod_str = \" using {\" + \", \".join(f\"{m} down\" for m in modifiers) + \"}\"\n    else:\n        mod_str = \"\"\n    script = f'tell application \"System Events\" to keystroke \"{key}\"{mod_str}'\n    r = subprocess.run([\"osascript\", \"-e\", script], capture_output=True, timeout=10)\n    if r.returncode != 0:\n        sys.stderr.write(f\"osascript keystroke failed: {r.stderr.decode().strip()}\\n\")\n\n\ndef keycode_via_osascript(code, modifiers=None):\n    \"\"\"Send a key code via osascript (System Events).\"\"\"\n    if modifiers:\n        if len(modifiers) == 1:\n            mod_str = f\" using {modifiers[0]} down\"\n        else:\n            mod_str = \" using {\" + \", \".join(f\"{m} down\" for m in modifiers) + \"}\"\n    else:\n        mod_str = \"\"\n    script = f'tell application \"System Events\" to key code {code}{mod_str}'\n    r = subprocess.run([\"osascript\", \"-e\", script], capture_output=True, timeout=10)\n    if r.returncode != 0:\n        sys.stderr.write(f\"osascript keycode failed: {r.stderr.decode().strip()}\\n\")\n\n\ndef cmd_type(args):\n    if args.app:\n        activate_and_find(args.app)\n\n    proc = subprocess.Popen([\"pbcopy\"], stdin=subprocess.PIPE)\n    proc.communicate(args.text.encode(\"utf-8\"))\n\n    keystroke_via_osascript(\"v\", [\"command\"])\n    time.sleep(0.1)\n\n    output({\"ok\": True, \"typed\": len(args.text)})\n\n\ndef cmd_key(args):\n    if args.app:\n        activate_and_find(args.app)\n\n    combo = args.combo\n    parts = [p.strip() for p in combo.split(\"+\")]\n\n    modifier_names = {\"cmd\", \"ctrl\", \"alt\", \"opt\", \"shift\", \"command\", \"control\", \"option\"}\n    modifiers = []\n    main_key = None\n\n    for p in parts:\n        low = p.lower()\n        if low in modifier_names:\n            mod_map = {\n                \"cmd\": \"command\", \"command\": \"command\",\n                \"ctrl\": \"control\", \"control\": \"control\",\n                \"alt\": \"option\", \"opt\": \"option\", \"option\": \"option\",\n                \"shift\": \"shift\",\n            }\n            modifiers.append(mod_map[low])\n        else:\n            main_key = low\n\n    if main_key is None:\n        fail({\"error\": \"no_key\", \"message\": f\"No key specified in combo '{combo}'\"})\n\n    keycode_map = {\n        \"return\": 36, \"enter\": 36, \"tab\": 48, \"space\": 49,\n        \"delete\": 51, \"backspace\": 51, \"escape\": 53, \"esc\": 53,\n        \"up\": 126, \"down\": 125, \"left\": 123, \"right\": 124,\n        \"home\": 115, \"end\": 119, \"pageup\": 116, \"pagedown\": 121,\n        \"f1\": 122, \"f2\": 120, \"f3\": 99, \"f4\": 118, \"f5\": 96,\n    }\n\n    if main_key in keycode_map:\n        keycode_via_osascript(keycode_map[main_key], modifiers if modifiers else None)\n    else:\n        keystroke_via_osascript(main_key, modifiers if modifiers else None)\n\n    output({\"ok\": True, \"pressed\": combo})\n\n\n# ---------------------------------------------------------------------------\n# CLI\n# ---------------------------------------------------------------------------\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"macOS GUI automation helper\")\n    sub = parser.add_subparsers(dest=\"command\")\n\n    # list\n    sub.add_parser(\"list\", help=\"List all visible windows\")\n\n    # screenshot (with annotation)\n    p_ss = sub.add_parser(\"screenshot\", help=\"Screenshot + annotate an app window\")\n    p_ss.add_argument(\"app\", help=\"App name (fuzzy, case-insensitive)\")\n    p_ss.add_argument(\"--id\", type=int, default=None, help=\"Window ID for disambiguation\")\n\n    # clicknum\n    p_cn = sub.add_parser(\"clicknum\", help=\"Click element N from last screenshot\")\n    p_cn.add_argument(\"num\", type=int, help=\"Element number to click\")\n\n    # click (legacy — direct canvas coords)\n    p_cl = sub.add_parser(\"click\", help=\"Click at canvas coords (0-1000)\")\n    p_cl.add_argument(\"--app\", required=True, help=\"App name (fuzzy)\")\n    p_cl.add_argument(\"--id\", type=int, default=None, help=\"Window ID\")\n    p_cl.add_argument(\"x\", type=int, help=\"Canvas X coordinate (0-1000)\")\n    p_cl.add_argument(\"y\", type=int, help=\"Canvas Y coordinate (0-1000)\")\n\n    # scroll\n    p_sc = sub.add_parser(\"scroll\", help=\"Scroll inside an app window\")\n    p_sc.add_argument(\"--app\", required=True, help=\"App name (fuzzy)\")\n    p_sc.add_argument(\"--id\", type=int, default=None, help=\"Window ID\")\n    p_sc.add_argument(\"direction\", choices=[\"up\", \"down\", \"left\", \"right\"])\n    p_sc.add_argument(\"amount\", type=int, help=\"Scroll clicks (3-5 moderate, 10+ fast)\")\n\n    # type\n    p_ty = sub.add_parser(\"type\", help=\"Type text via clipboard paste\")\n    p_ty.add_argument(\"--app\", default=None, help=\"App name to activate first (fuzzy)\")\n    p_ty.add_argument(\"text\", help=\"Text to type\")\n\n    # key\n    p_ke = sub.add_parser(\"key\", help=\"Press key or combo (e.g. return, cmd+v)\")\n    p_ke.add_argument(\"--app\", default=None, help=\"App name to activate first (fuzzy)\")\n    p_ke.add_argument(\"combo\", help=\"Key combo like 'return', 'cmd+v', 'cmd+shift+s'\")\n\n    args = parser.parse_args()\n    if not args.command:\n        parser.print_help()\n        sys.exit(1)\n\n    dispatch = {\n        \"list\": cmd_list,\n        \"screenshot\": cmd_screenshot,\n        \"clicknum\": cmd_clicknum,\n        \"click\": cmd_click,\n        \"scroll\": cmd_scroll,\n        \"type\": cmd_type,\n        \"key\": cmd_key,\n    }\n    dispatch[args.command](args)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/mcp-builder/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/mcp-builder/SKILL.md",
    "content": "---\nname: mcp-builder\ndescription: Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).\nlicense: Complete terms in LICENSE.txt\n---\n\n# MCP Server Development Guide\n\n## Overview\n\nCreate MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. The quality of an MCP server is measured by how well it enables LLMs to accomplish real-world tasks.\n\n---\n\n# Process\n\n## 🚀 High-Level Workflow\n\nCreating a high-quality MCP server involves four main phases:\n\n### Phase 1: Deep Research and Planning\n\n#### 1.1 Understand Modern MCP Design\n\n**API Coverage vs. Workflow Tools:**\nBalance comprehensive API endpoint coverage with specialized workflow tools. Workflow tools can be more convenient for specific tasks, while comprehensive coverage gives agents flexibility to compose operations. Performance varies by client—some clients benefit from code execution that combines basic tools, while others work better with higher-level workflows. When uncertain, prioritize comprehensive API coverage.\n\n**Tool Naming and Discoverability:**\nClear, descriptive tool names help agents find the right tools quickly. Use consistent prefixes (e.g., `github_create_issue`, `github_list_repos`) and action-oriented naming.\n\n**Context Management:**\nAgents benefit from concise tool descriptions and the ability to filter/paginate results. Design tools that return focused, relevant data. Some clients support code execution which can help agents filter and process data efficiently.\n\n**Actionable Error Messages:**\nError messages should guide agents toward solutions with specific suggestions and next steps.\n\n#### 1.2 Study MCP Protocol Documentation\n\n**Navigate the MCP specification:**\n\nStart with the sitemap to find relevant pages: `https://modelcontextprotocol.io/sitemap.xml`\n\nThen fetch specific pages with `.md` suffix for markdown format (e.g., `https://modelcontextprotocol.io/specification/draft.md`).\n\nKey pages to review:\n- Specification overview and architecture\n- Transport mechanisms (streamable HTTP, stdio)\n- Tool, resource, and prompt definitions\n\n#### 1.3 Study Framework Documentation\n\n**Recommended stack:**\n- **Language**: TypeScript (high-quality SDK support and good compatibility in many execution environments e.g. MCPB. Plus AI models are good at generating TypeScript code, benefiting from its broad usage, static typing and good linting tools)\n- **Transport**: Streamable HTTP for remote servers, using stateless JSON (simpler to scale and maintain, as opposed to stateful sessions and streaming responses). stdio for local servers.\n\n**Load framework documentation:**\n\n- **MCP Best Practices**: [📋 View Best Practices](./reference/mcp_best_practices.md) - Core guidelines\n\n**For TypeScript (recommended):**\n- **TypeScript SDK**: Use WebFetch to load `https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/README.md`\n- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples\n\n**For Python:**\n- **Python SDK**: Use WebFetch to load `https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n- [🐍 Python Guide](./reference/python_mcp_server.md) - Python patterns and examples\n\n#### 1.4 Plan Your Implementation\n\n**Understand the API:**\nReview the service's API documentation to identify key endpoints, authentication requirements, and data models. Use web search and WebFetch as needed.\n\n**Tool Selection:**\nPrioritize comprehensive API coverage. List endpoints to implement, starting with the most common operations.\n\n---\n\n### Phase 2: Implementation\n\n#### 2.1 Set Up Project Structure\n\nSee language-specific guides for project setup:\n- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - Project structure, package.json, tsconfig.json\n- [🐍 Python Guide](./reference/python_mcp_server.md) - Module organization, dependencies\n\n#### 2.2 Implement Core Infrastructure\n\nCreate shared utilities:\n- API client with authentication\n- Error handling helpers\n- Response formatting (JSON/Markdown)\n- Pagination support\n\n#### 2.3 Implement Tools\n\nFor each tool:\n\n**Input Schema:**\n- Use Zod (TypeScript) or Pydantic (Python)\n- Include constraints and clear descriptions\n- Add examples in field descriptions\n\n**Output Schema:**\n- Define `outputSchema` where possible for structured data\n- Use `structuredContent` in tool responses (TypeScript SDK feature)\n- Helps clients understand and process tool outputs\n\n**Tool Description:**\n- Concise summary of functionality\n- Parameter descriptions\n- Return type schema\n\n**Implementation:**\n- Async/await for I/O operations\n- Proper error handling with actionable messages\n- Support pagination where applicable\n- Return both text content and structured data when using modern SDKs\n\n**Annotations:**\n- `readOnlyHint`: true/false\n- `destructiveHint`: true/false\n- `idempotentHint`: true/false\n- `openWorldHint`: true/false\n\n---\n\n### Phase 3: Review and Test\n\n#### 3.1 Code Quality\n\nReview for:\n- No duplicated code (DRY principle)\n- Consistent error handling\n- Full type coverage\n- Clear tool descriptions\n\n#### 3.2 Build and Test\n\n**TypeScript:**\n- Run `npm run build` to verify compilation\n- Test with MCP Inspector: `npx @modelcontextprotocol/inspector`\n\n**Python:**\n- Verify syntax: `python -m py_compile your_server.py`\n- Test with MCP Inspector\n\nSee language-specific guides for detailed testing approaches and quality checklists.\n\n---\n\n### Phase 4: Create Evaluations\n\nAfter implementing your MCP server, create comprehensive evaluations to test its effectiveness.\n\n**Load [✅ Evaluation Guide](./reference/evaluation.md) for complete evaluation guidelines.**\n\n#### 4.1 Understand Evaluation Purpose\n\nUse evaluations to test whether LLMs can effectively use your MCP server to answer realistic, complex questions.\n\n#### 4.2 Create 10 Evaluation Questions\n\nTo create effective evaluations, follow the process outlined in the evaluation guide:\n\n1. **Tool Inspection**: List available tools and understand their capabilities\n2. **Content Exploration**: Use READ-ONLY operations to explore available data\n3. **Question Generation**: Create 10 complex, realistic questions\n4. **Answer Verification**: Solve each question yourself to verify answers\n\n#### 4.3 Evaluation Requirements\n\nEnsure each question is:\n- **Independent**: Not dependent on other questions\n- **Read-only**: Only non-destructive operations required\n- **Complex**: Requiring multiple tool calls and deep exploration\n- **Realistic**: Based on real use cases humans would care about\n- **Verifiable**: Single, clear answer that can be verified by string comparison\n- **Stable**: Answer won't change over time\n\n#### 4.4 Output Format\n\nCreate an XML file with this structure:\n\n```xml\n<evaluation>\n  <qa_pair>\n    <question>Find discussions about AI model launches with animal codenames. One model needed a specific safety designation that uses the format ASL-X. What number X was being determined for the model named after a spotted wild cat?</question>\n    <answer>3</answer>\n  </qa_pair>\n<!-- More qa_pairs... -->\n</evaluation>\n```\n\n---\n\n# Reference Files\n\n## 📚 Documentation Library\n\nLoad these resources as needed during development:\n\n### Core MCP Documentation (Load First)\n- **MCP Protocol**: Start with sitemap at `https://modelcontextprotocol.io/sitemap.xml`, then fetch specific pages with `.md` suffix\n- [📋 MCP Best Practices](./reference/mcp_best_practices.md) - Universal MCP guidelines including:\n  - Server and tool naming conventions\n  - Response format guidelines (JSON vs Markdown)\n  - Pagination best practices\n  - Transport selection (streamable HTTP vs stdio)\n  - Security and error handling standards\n\n### SDK Documentation (Load During Phase 1/2)\n- **Python SDK**: Fetch from `https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n- **TypeScript SDK**: Fetch from `https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/README.md`\n\n### Language-Specific Implementation Guides (Load During Phase 2)\n- [🐍 Python Implementation Guide](./reference/python_mcp_server.md) - Complete Python/FastMCP guide with:\n  - Server initialization patterns\n  - Pydantic model examples\n  - Tool registration with `@mcp.tool`\n  - Complete working examples\n  - Quality checklist\n\n- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Complete TypeScript guide with:\n  - Project structure\n  - Zod schema patterns\n  - Tool registration with `server.registerTool`\n  - Complete working examples\n  - Quality checklist\n\n### Evaluation Guide (Load During Phase 4)\n- [✅ Evaluation Guide](./reference/evaluation.md) - Complete evaluation creation guide with:\n  - Question creation guidelines\n  - Answer verification strategies\n  - XML format specifications\n  - Example questions and answers\n  - Running an evaluation with the provided scripts\n"
  },
  {
    "path": "skills/mcp-builder/reference/evaluation.md",
    "content": "# MCP Server Evaluation Guide\n\n## Overview\n\nThis document provides guidance on creating comprehensive evaluations for MCP servers. Evaluations test whether LLMs can effectively use your MCP server to answer realistic, complex questions using only the tools provided.\n\n---\n\n## Quick Reference\n\n### Evaluation Requirements\n- Create 10 human-readable questions\n- Questions must be READ-ONLY, INDEPENDENT, NON-DESTRUCTIVE\n- Each question requires multiple tool calls (potentially dozens)\n- Answers must be single, verifiable values\n- Answers must be STABLE (won't change over time)\n\n### Output Format\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Your question here</question>\n      <answer>Single verifiable answer</answer>\n   </qa_pair>\n</evaluation>\n```\n\n---\n\n## Purpose of Evaluations\n\nThe measure of quality of an MCP server is NOT how well or comprehensively the server implements tools, but how well these implementations (input/output schemas, docstrings/descriptions, functionality) enable LLMs with no other context and access ONLY to the MCP servers to answer realistic and difficult questions.\n\n## Evaluation Overview\n\nCreate 10 human-readable questions requiring ONLY READ-ONLY, INDEPENDENT, NON-DESTRUCTIVE, and IDEMPOTENT operations to answer. Each question should be:\n- Realistic\n- Clear and concise\n- Unambiguous\n- Complex, requiring potentially dozens of tool calls or steps\n- Answerable with a single, verifiable value that you identify in advance\n\n## Question Guidelines\n\n### Core Requirements\n\n1. **Questions MUST be independent**\n   - Each question should NOT depend on the answer to any other question\n   - Should not assume prior write operations from processing another question\n\n2. **Questions MUST require ONLY NON-DESTRUCTIVE AND IDEMPOTENT tool use**\n   - Should not instruct or require modifying state to arrive at the correct answer\n\n3. **Questions must be REALISTIC, CLEAR, CONCISE, and COMPLEX**\n   - Must require another LLM to use multiple (potentially dozens of) tools or steps to answer\n\n### Complexity and Depth\n\n4. **Questions must require deep exploration**\n   - Consider multi-hop questions requiring multiple sub-questions and sequential tool calls\n   - Each step should benefit from information found in previous questions\n\n5. **Questions may require extensive paging**\n   - May need paging through multiple pages of results\n   - May require querying old data (1-2 years out-of-date) to find niche information\n   - The questions must be DIFFICULT\n\n6. **Questions must require deep understanding**\n   - Rather than surface-level knowledge\n   - May pose complex ideas as True/False questions requiring evidence\n   - May use multiple-choice format where LLM must search different hypotheses\n\n7. **Questions must not be solvable with straightforward keyword search**\n   - Do not include specific keywords from the target content\n   - Use synonyms, related concepts, or paraphrases\n   - Require multiple searches, analyzing multiple related items, extracting context, then deriving the answer\n\n### Tool Testing\n\n8. **Questions should stress-test tool return values**\n   - May elicit tools returning large JSON objects or lists, overwhelming the LLM\n   - Should require understanding multiple modalities of data:\n     - IDs and names\n     - Timestamps and datetimes (months, days, years, seconds)\n     - File IDs, names, extensions, and mimetypes\n     - URLs, GIDs, etc.\n   - Should probe the tool's ability to return all useful forms of data\n\n9. **Questions should MOSTLY reflect real human use cases**\n   - The kinds of information retrieval tasks that HUMANS assisted by an LLM would care about\n\n10. **Questions may require dozens of tool calls**\n    - This challenges LLMs with limited context\n    - Encourages MCP server tools to reduce information returned\n\n11. **Include ambiguous questions**\n    - May be ambiguous OR require difficult decisions on which tools to call\n    - Force the LLM to potentially make mistakes or misinterpret\n    - Ensure that despite AMBIGUITY, there is STILL A SINGLE VERIFIABLE ANSWER\n\n### Stability\n\n12. **Questions must be designed so the answer DOES NOT CHANGE**\n    - Do not ask questions that rely on \"current state\" which is dynamic\n    - For example, do not count:\n      - Number of reactions to a post\n      - Number of replies to a thread\n      - Number of members in a channel\n\n13. **DO NOT let the MCP server RESTRICT the kinds of questions you create**\n    - Create challenging and complex questions\n    - Some may not be solvable with the available MCP server tools\n    - Questions may require specific output formats (datetime vs. epoch time, JSON vs. MARKDOWN)\n    - Questions may require dozens of tool calls to complete\n\n## Answer Guidelines\n\n### Verification\n\n1. **Answers must be VERIFIABLE via direct string comparison**\n   - If the answer can be re-written in many formats, clearly specify the output format in the QUESTION\n   - Examples: \"Use YYYY/MM/DD.\", \"Respond True or False.\", \"Answer A, B, C, or D and nothing else.\"\n   - Answer should be a single VERIFIABLE value such as:\n     - User ID, user name, display name, first name, last name\n     - Channel ID, channel name\n     - Message ID, string\n     - URL, title\n     - Numerical quantity\n     - Timestamp, datetime\n     - Boolean (for True/False questions)\n     - Email address, phone number\n     - File ID, file name, file extension\n     - Multiple choice answer\n   - Answers must not require special formatting or complex, structured output\n   - Answer will be verified using DIRECT STRING COMPARISON\n\n### Readability\n\n2. **Answers should generally prefer HUMAN-READABLE formats**\n   - Examples: names, first name, last name, datetime, file name, message string, URL, yes/no, true/false, a/b/c/d\n   - Rather than opaque IDs (though IDs are acceptable)\n   - The VAST MAJORITY of answers should be human-readable\n\n### Stability\n\n3. **Answers must be STABLE/STATIONARY**\n   - Look at old content (e.g., conversations that have ended, projects that have launched, questions answered)\n   - Create QUESTIONS based on \"closed\" concepts that will always return the same answer\n   - Questions may ask to consider a fixed time window to insulate from non-stationary answers\n   - Rely on context UNLIKELY to change\n   - Example: if finding a paper name, be SPECIFIC enough so answer is not confused with papers published later\n\n4. **Answers must be CLEAR and UNAMBIGUOUS**\n   - Questions must be designed so there is a single, clear answer\n   - Answer can be derived from using the MCP server tools\n\n### Diversity\n\n5. **Answers must be DIVERSE**\n   - Answer should be a single VERIFIABLE value in diverse modalities and formats\n   - User concept: user ID, user name, display name, first name, last name, email address, phone number\n   - Channel concept: channel ID, channel name, channel topic\n   - Message concept: message ID, message string, timestamp, month, day, year\n\n6. **Answers must NOT be complex structures**\n   - Not a list of values\n   - Not a complex object\n   - Not a list of IDs or strings\n   - Not natural language text\n   - UNLESS the answer can be straightforwardly verified using DIRECT STRING COMPARISON\n   - And can be realistically reproduced\n   - It should be unlikely that an LLM would return the same list in any other order or format\n\n## Evaluation Process\n\n### Step 1: Documentation Inspection\n\nRead the documentation of the target API to understand:\n- Available endpoints and functionality\n- If ambiguity exists, fetch additional information from the web\n- Parallelize this step AS MUCH AS POSSIBLE\n- Ensure each subagent is ONLY examining documentation from the file system or on the web\n\n### Step 2: Tool Inspection\n\nList the tools available in the MCP server:\n- Inspect the MCP server directly\n- Understand input/output schemas, docstrings, and descriptions\n- WITHOUT calling the tools themselves at this stage\n\n### Step 3: Developing Understanding\n\nRepeat steps 1 & 2 until you have a good understanding:\n- Iterate multiple times\n- Think about the kinds of tasks you want to create\n- Refine your understanding\n- At NO stage should you READ the code of the MCP server implementation itself\n- Use your intuition and understanding to create reasonable, realistic, but VERY challenging tasks\n\n### Step 4: Read-Only Content Inspection\n\nAfter understanding the API and tools, USE the MCP server tools:\n- Inspect content using READ-ONLY and NON-DESTRUCTIVE operations ONLY\n- Goal: identify specific content (e.g., users, channels, messages, projects, tasks) for creating realistic questions\n- Should NOT call any tools that modify state\n- Will NOT read the code of the MCP server implementation itself\n- Parallelize this step with individual sub-agents pursuing independent explorations\n- Ensure each subagent is only performing READ-ONLY, NON-DESTRUCTIVE, and IDEMPOTENT operations\n- BE CAREFUL: SOME TOOLS may return LOTS OF DATA which would cause you to run out of CONTEXT\n- Make INCREMENTAL, SMALL, AND TARGETED tool calls for exploration\n- In all tool call requests, use the `limit` parameter to limit results (<10)\n- Use pagination\n\n### Step 5: Task Generation\n\nAfter inspecting the content, create 10 human-readable questions:\n- An LLM should be able to answer these with the MCP server\n- Follow all question and answer guidelines above\n\n## Output Format\n\nEach QA pair consists of a question and an answer. The output should be an XML file with this structure:\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the project created in Q2 2024 with the highest number of completed tasks. What is the project name?</question>\n      <answer>Website Redesign</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Search for issues labeled as \"bug\" that were closed in March 2024. Which user closed the most issues? Provide their username.</question>\n      <answer>sarah_dev</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Look for pull requests that modified files in the /api directory and were merged between January 1 and January 31, 2024. How many different contributors worked on these PRs?</question>\n      <answer>7</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Find the repository with the most stars that was created before 2023. What is the repository name?</question>\n      <answer>data-pipeline</answer>\n   </qa_pair>\n</evaluation>\n```\n\n## Evaluation Examples\n\n### Good Questions\n\n**Example 1: Multi-hop question requiring deep exploration (GitHub MCP)**\n```xml\n<qa_pair>\n   <question>Find the repository that was archived in Q3 2023 and had previously been the most forked project in the organization. What was the primary programming language used in that repository?</question>\n   <answer>Python</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires multiple searches to find archived repositories\n- Needs to identify which had the most forks before archival\n- Requires examining repository details for the language\n- Answer is a simple, verifiable value\n- Based on historical (closed) data that won't change\n\n**Example 2: Requires understanding context without keyword matching (Project Management MCP)**\n```xml\n<qa_pair>\n   <question>Locate the initiative focused on improving customer onboarding that was completed in late 2023. The project lead created a retrospective document after completion. What was the lead's role title at that time?</question>\n   <answer>Product Manager</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Doesn't use specific project name (\"initiative focused on improving customer onboarding\")\n- Requires finding completed projects from specific timeframe\n- Needs to identify the project lead and their role\n- Requires understanding context from retrospective documents\n- Answer is human-readable and stable\n- Based on completed work (won't change)\n\n**Example 3: Complex aggregation requiring multiple steps (Issue Tracker MCP)**\n```xml\n<qa_pair>\n   <question>Among all bugs reported in January 2024 that were marked as critical priority, which assignee resolved the highest percentage of their assigned bugs within 48 hours? Provide the assignee's username.</question>\n   <answer>alex_eng</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires filtering bugs by date, priority, and status\n- Needs to group by assignee and calculate resolution rates\n- Requires understanding timestamps to determine 48-hour windows\n- Tests pagination (potentially many bugs to process)\n- Answer is a single username\n- Based on historical data from specific time period\n\n**Example 4: Requires synthesis across multiple data types (CRM MCP)**\n```xml\n<qa_pair>\n   <question>Find the account that upgraded from the Starter to Enterprise plan in Q4 2023 and had the highest annual contract value. What industry does this account operate in?</question>\n   <answer>Healthcare</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires understanding subscription tier changes\n- Needs to identify upgrade events in specific timeframe\n- Requires comparing contract values\n- Must access account industry information\n- Answer is simple and verifiable\n- Based on completed historical transactions\n\n### Poor Questions\n\n**Example 1: Answer changes over time**\n```xml\n<qa_pair>\n   <question>How many open issues are currently assigned to the engineering team?</question>\n   <answer>47</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- The answer will change as issues are created, closed, or reassigned\n- Not based on stable/stationary data\n- Relies on \"current state\" which is dynamic\n\n**Example 2: Too easy with keyword search**\n```xml\n<qa_pair>\n   <question>Find the pull request with title \"Add authentication feature\" and tell me who created it.</question>\n   <answer>developer123</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- Can be solved with a straightforward keyword search for exact title\n- Doesn't require deep exploration or understanding\n- No synthesis or analysis needed\n\n**Example 3: Ambiguous answer format**\n```xml\n<qa_pair>\n   <question>List all the repositories that have Python as their primary language.</question>\n   <answer>repo1, repo2, repo3, data-pipeline, ml-tools</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- Answer is a list that could be returned in any order\n- Difficult to verify with direct string comparison\n- LLM might format differently (JSON array, comma-separated, newline-separated)\n- Better to ask for a specific aggregate (count) or superlative (most stars)\n\n## Verification Process\n\nAfter creating evaluations:\n\n1. **Examine the XML file** to understand the schema\n2. **Load each task instruction** and in parallel using the MCP server and tools, identify the correct answer by attempting to solve the task YOURSELF\n3. **Flag any operations** that require WRITE or DESTRUCTIVE operations\n4. **Accumulate all CORRECT answers** and replace any incorrect answers in the document\n5. **Remove any `<qa_pair>`** that require WRITE or DESTRUCTIVE operations\n\nRemember to parallelize solving tasks to avoid running out of context, then accumulate all answers and make changes to the file at the end.\n\n## Tips for Creating Quality Evaluations\n\n1. **Think Hard and Plan Ahead** before generating tasks\n2. **Parallelize Where Opportunity Arises** to speed up the process and manage context\n3. **Focus on Realistic Use Cases** that humans would actually want to accomplish\n4. **Create Challenging Questions** that test the limits of the MCP server's capabilities\n5. **Ensure Stability** by using historical data and closed concepts\n6. **Verify Answers** by solving the questions yourself using the MCP server tools\n7. **Iterate and Refine** based on what you learn during the process\n\n---\n\n# Running Evaluations\n\nAfter creating your evaluation file, you can use the provided evaluation harness to test your MCP server.\n\n## Setup\n\n1. **Install Dependencies**\n\n   ```bash\n   pip install -r scripts/requirements.txt\n   ```\n\n   Or install manually:\n   ```bash\n   pip install anthropic mcp\n   ```\n\n2. **Set API Key**\n\n   ```bash\n   export ANTHROPIC_API_KEY=your_api_key_here\n   ```\n\n## Evaluation File Format\n\nEvaluation files use XML format with `<qa_pair>` elements:\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the project created in Q2 2024 with the highest number of completed tasks. What is the project name?</question>\n      <answer>Website Redesign</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Search for issues labeled as \"bug\" that were closed in March 2024. Which user closed the most issues? Provide their username.</question>\n      <answer>sarah_dev</answer>\n   </qa_pair>\n</evaluation>\n```\n\n## Running Evaluations\n\nThe evaluation script (`scripts/evaluation.py`) supports three transport types:\n\n**Important:**\n- **stdio transport**: The evaluation script automatically launches and manages the MCP server process for you. Do not run the server manually.\n- **sse/http transports**: You must start the MCP server separately before running the evaluation. The script connects to the already-running server at the specified URL.\n\n### 1. Local STDIO Server\n\nFor locally-run MCP servers (script launches the server automatically):\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_mcp_server.py \\\n  evaluation.xml\n```\n\nWith environment variables:\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_mcp_server.py \\\n  -e API_KEY=abc123 \\\n  -e DEBUG=true \\\n  evaluation.xml\n```\n\n### 2. Server-Sent Events (SSE)\n\nFor SSE-based MCP servers (you must start the server first):\n\n```bash\npython scripts/evaluation.py \\\n  -t sse \\\n  -u https://example.com/mcp \\\n  -H \"Authorization: Bearer token123\" \\\n  -H \"X-Custom-Header: value\" \\\n  evaluation.xml\n```\n\n### 3. HTTP (Streamable HTTP)\n\nFor HTTP-based MCP servers (you must start the server first):\n\n```bash\npython scripts/evaluation.py \\\n  -t http \\\n  -u https://example.com/mcp \\\n  -H \"Authorization: Bearer token123\" \\\n  evaluation.xml\n```\n\n## Command-Line Options\n\n```\nusage: evaluation.py [-h] [-t {stdio,sse,http}] [-m MODEL] [-c COMMAND]\n                     [-a ARGS [ARGS ...]] [-e ENV [ENV ...]] [-u URL]\n                     [-H HEADERS [HEADERS ...]] [-o OUTPUT]\n                     eval_file\n\npositional arguments:\n  eval_file             Path to evaluation XML file\n\noptional arguments:\n  -h, --help            Show help message\n  -t, --transport       Transport type: stdio, sse, or http (default: stdio)\n  -m, --model           Claude model to use (default: claude-3-7-sonnet-20250219)\n  -o, --output          Output file for report (default: print to stdout)\n\nstdio options:\n  -c, --command         Command to run MCP server (e.g., python, node)\n  -a, --args            Arguments for the command (e.g., server.py)\n  -e, --env             Environment variables in KEY=VALUE format\n\nsse/http options:\n  -u, --url             MCP server URL\n  -H, --header          HTTP headers in 'Key: Value' format\n```\n\n## Output\n\nThe evaluation script generates a detailed report including:\n\n- **Summary Statistics**:\n  - Accuracy (correct/total)\n  - Average task duration\n  - Average tool calls per task\n  - Total tool calls\n\n- **Per-Task Results**:\n  - Prompt and expected response\n  - Actual response from the agent\n  - Whether the answer was correct (✅/❌)\n  - Duration and tool call details\n  - Agent's summary of its approach\n  - Agent's feedback on the tools\n\n### Save Report to File\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_server.py \\\n  -o evaluation_report.md \\\n  evaluation.xml\n```\n\n## Complete Example Workflow\n\nHere's a complete example of creating and running an evaluation:\n\n1. **Create your evaluation file** (`my_evaluation.xml`):\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the user who created the most issues in January 2024. What is their username?</question>\n      <answer>alice_developer</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Among all pull requests merged in Q1 2024, which repository had the highest number? Provide the repository name.</question>\n      <answer>backend-api</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Find the project that was completed in December 2023 and had the longest duration from start to finish. How many days did it take?</question>\n      <answer>127</answer>\n   </qa_pair>\n</evaluation>\n```\n\n2. **Install dependencies**:\n\n```bash\npip install -r scripts/requirements.txt\nexport ANTHROPIC_API_KEY=your_api_key\n```\n\n3. **Run evaluation**:\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a github_mcp_server.py \\\n  -e GITHUB_TOKEN=ghp_xxx \\\n  -o github_eval_report.md \\\n  my_evaluation.xml\n```\n\n4. **Review the report** in `github_eval_report.md` to:\n   - See which questions passed/failed\n   - Read the agent's feedback on your tools\n   - Identify areas for improvement\n   - Iterate on your MCP server design\n\n## Troubleshooting\n\n### Connection Errors\n\nIf you get connection errors:\n- **STDIO**: Verify the command and arguments are correct\n- **SSE/HTTP**: Check the URL is accessible and headers are correct\n- Ensure any required API keys are set in environment variables or headers\n\n### Low Accuracy\n\nIf many evaluations fail:\n- Review the agent's feedback for each task\n- Check if tool descriptions are clear and comprehensive\n- Verify input parameters are well-documented\n- Consider whether tools return too much or too little data\n- Ensure error messages are actionable\n\n### Timeout Issues\n\nIf tasks are timing out:\n- Use a more capable model (e.g., `claude-3-7-sonnet-20250219`)\n- Check if tools are returning too much data\n- Verify pagination is working correctly\n- Consider simplifying complex questions"
  },
  {
    "path": "skills/mcp-builder/reference/mcp_best_practices.md",
    "content": "# MCP Server Best Practices\n\n## Quick Reference\n\n### Server Naming\n- **Python**: `{service}_mcp` (e.g., `slack_mcp`)\n- **Node/TypeScript**: `{service}-mcp-server` (e.g., `slack-mcp-server`)\n\n### Tool Naming\n- Use snake_case with service prefix\n- Format: `{service}_{action}_{resource}`\n- Example: `slack_send_message`, `github_create_issue`\n\n### Response Formats\n- Support both JSON and Markdown formats\n- JSON for programmatic processing\n- Markdown for human readability\n\n### Pagination\n- Always respect `limit` parameter\n- Return `has_more`, `next_offset`, `total_count`\n- Default to 20-50 items\n\n### Transport\n- **Streamable HTTP**: For remote servers, multi-client scenarios\n- **stdio**: For local integrations, command-line tools\n- Avoid SSE (deprecated in favor of streamable HTTP)\n\n---\n\n## Server Naming Conventions\n\nFollow these standardized naming patterns:\n\n**Python**: Use format `{service}_mcp` (lowercase with underscores)\n- Examples: `slack_mcp`, `github_mcp`, `jira_mcp`\n\n**Node/TypeScript**: Use format `{service}-mcp-server` (lowercase with hyphens)\n- Examples: `slack-mcp-server`, `github-mcp-server`, `jira-mcp-server`\n\nThe name should be general, descriptive of the service being integrated, easy to infer from the task description, and without version numbers.\n\n---\n\n## Tool Naming and Design\n\n### Tool Naming\n\n1. **Use snake_case**: `search_users`, `create_project`, `get_channel_info`\n2. **Include service prefix**: Anticipate that your MCP server may be used alongside other MCP servers\n   - Use `slack_send_message` instead of just `send_message`\n   - Use `github_create_issue` instead of just `create_issue`\n3. **Be action-oriented**: Start with verbs (get, list, search, create, etc.)\n4. **Be specific**: Avoid generic names that could conflict with other servers\n\n### Tool Design\n\n- Tool descriptions must narrowly and unambiguously describe functionality\n- Descriptions must precisely match actual functionality\n- Provide tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- Keep tool operations focused and atomic\n\n---\n\n## Response Formats\n\nAll tools that return data should support multiple formats:\n\n### JSON Format (`response_format=\"json\"`)\n- Machine-readable structured data\n- Include all available fields and metadata\n- Consistent field names and types\n- Use for programmatic processing\n\n### Markdown Format (`response_format=\"markdown\"`, typically default)\n- Human-readable formatted text\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format\n- Show display names with IDs in parentheses\n- Omit verbose metadata\n\n---\n\n## Pagination\n\nFor tools that list resources:\n\n- **Always respect the `limit` parameter**\n- **Implement pagination**: Use `offset` or cursor-based pagination\n- **Return pagination metadata**: Include `has_more`, `next_offset`/`next_cursor`, `total_count`\n- **Never load all results into memory**: Especially important for large datasets\n- **Default to reasonable limits**: 20-50 items is typical\n\nExample pagination response:\n```json\n{\n  \"total\": 150,\n  \"count\": 20,\n  \"offset\": 0,\n  \"items\": [...],\n  \"has_more\": true,\n  \"next_offset\": 20\n}\n```\n\n---\n\n## Transport Options\n\n### Streamable HTTP\n\n**Best for**: Remote servers, web services, multi-client scenarios\n\n**Characteristics**:\n- Bidirectional communication over HTTP\n- Supports multiple simultaneous clients\n- Can be deployed as a web service\n- Enables server-to-client notifications\n\n**Use when**:\n- Serving multiple clients simultaneously\n- Deploying as a cloud service\n- Integration with web applications\n\n### stdio\n\n**Best for**: Local integrations, command-line tools\n\n**Characteristics**:\n- Standard input/output stream communication\n- Simple setup, no network configuration needed\n- Runs as a subprocess of the client\n\n**Use when**:\n- Building tools for local development environments\n- Integrating with desktop applications\n- Single-user, single-session scenarios\n\n**Note**: stdio servers should NOT log to stdout (use stderr for logging)\n\n### Transport Selection\n\n| Criterion | stdio | Streamable HTTP |\n|-----------|-------|-----------------|\n| **Deployment** | Local | Remote |\n| **Clients** | Single | Multiple |\n| **Complexity** | Low | Medium |\n| **Real-time** | No | Yes |\n\n---\n\n## Security Best Practices\n\n### Authentication and Authorization\n\n**OAuth 2.1**:\n- Use secure OAuth 2.1 with certificates from recognized authorities\n- Validate access tokens before processing requests\n- Only accept tokens specifically intended for your server\n\n**API Keys**:\n- Store API keys in environment variables, never in code\n- Validate keys on server startup\n- Provide clear error messages when authentication fails\n\n### Input Validation\n\n- Sanitize file paths to prevent directory traversal\n- Validate URLs and external identifiers\n- Check parameter sizes and ranges\n- Prevent command injection in system calls\n- Use schema validation (Pydantic/Zod) for all inputs\n\n### Error Handling\n\n- Don't expose internal errors to clients\n- Log security-relevant errors server-side\n- Provide helpful but not revealing error messages\n- Clean up resources after errors\n\n### DNS Rebinding Protection\n\nFor streamable HTTP servers running locally:\n- Enable DNS rebinding protection\n- Validate the `Origin` header on all incoming connections\n- Bind to `127.0.0.1` rather than `0.0.0.0`\n\n---\n\n## Tool Annotations\n\nProvide annotations to help clients understand tool behavior:\n\n| Annotation | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `readOnlyHint` | boolean | false | Tool does not modify its environment |\n| `destructiveHint` | boolean | true | Tool may perform destructive updates |\n| `idempotentHint` | boolean | false | Repeated calls with same args have no additional effect |\n| `openWorldHint` | boolean | true | Tool interacts with external entities |\n\n**Important**: Annotations are hints, not security guarantees. Clients should not make security-critical decisions based solely on annotations.\n\n---\n\n## Error Handling\n\n- Use standard JSON-RPC error codes\n- Report tool errors within result objects (not protocol-level errors)\n- Provide helpful, specific error messages with suggested next steps\n- Don't expose internal implementation details\n- Clean up resources properly on errors\n\nExample error handling:\n```typescript\ntry {\n  const result = performOperation();\n  return { content: [{ type: \"text\", text: result }] };\n} catch (error) {\n  return {\n    isError: true,\n    content: [{\n      type: \"text\",\n      text: `Error: ${error.message}. Try using filter='active_only' to reduce results.`\n    }]\n  };\n}\n```\n\n---\n\n## Testing Requirements\n\nComprehensive testing should cover:\n\n- **Functional testing**: Verify correct execution with valid/invalid inputs\n- **Integration testing**: Test interaction with external systems\n- **Security testing**: Validate auth, input sanitization, rate limiting\n- **Performance testing**: Check behavior under load, timeouts\n- **Error handling**: Ensure proper error reporting and cleanup\n\n---\n\n## Documentation Requirements\n\n- Provide clear documentation of all tools and capabilities\n- Include working examples (at least 3 per major feature)\n- Document security considerations\n- Specify required permissions and access levels\n- Document rate limits and performance characteristics\n"
  },
  {
    "path": "skills/mcp-builder/reference/node_mcp_server.md",
    "content": "# Node/TypeScript MCP Server Implementation Guide\n\n## Overview\n\nThis document provides Node/TypeScript-specific best practices and examples for implementing MCP servers using the MCP TypeScript SDK. It covers project structure, server setup, tool registration patterns, input validation with Zod, error handling, and complete working examples.\n\n---\n\n## Quick Reference\n\n### Key Imports\n```typescript\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport express from \"express\";\nimport { z } from \"zod\";\n```\n\n### Server Initialization\n```typescript\nconst server = new McpServer({\n  name: \"service-mcp-server\",\n  version: \"1.0.0\"\n});\n```\n\n### Tool Registration Pattern\n```typescript\nserver.registerTool(\n  \"tool_name\",\n  {\n    title: \"Tool Display Name\",\n    description: \"What the tool does\",\n    inputSchema: { param: z.string() },\n    outputSchema: { result: z.string() }\n  },\n  async ({ param }) => {\n    const output = { result: `Processed: ${param}` };\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(output) }],\n      structuredContent: output // Modern pattern for structured data\n    };\n  }\n);\n```\n\n---\n\n## MCP TypeScript SDK\n\nThe official MCP TypeScript SDK provides:\n- `McpServer` class for server initialization\n- `registerTool` method for tool registration\n- Zod schema integration for runtime input validation\n- Type-safe tool handler implementations\n\n**IMPORTANT - Use Modern APIs Only:**\n- **DO use**: `server.registerTool()`, `server.registerResource()`, `server.registerPrompt()`\n- **DO NOT use**: Old deprecated APIs such as `server.tool()`, `server.setRequestHandler(ListToolsRequestSchema, ...)`, or manual handler registration\n- The `register*` methods provide better type safety, automatic schema handling, and are the recommended approach\n\nSee the MCP SDK documentation in the references for complete details.\n\n## Server Naming Convention\n\nNode/TypeScript MCP servers must follow this naming pattern:\n- **Format**: `{service}-mcp-server` (lowercase with hyphens)\n- **Examples**: `github-mcp-server`, `jira-mcp-server`, `stripe-mcp-server`\n\nThe name should be:\n- General (not tied to specific features)\n- Descriptive of the service/API being integrated\n- Easy to infer from the task description\n- Without version numbers or dates\n\n## Project Structure\n\nCreate the following structure for Node/TypeScript MCP servers:\n\n```\n{service}-mcp-server/\n├── package.json\n├── tsconfig.json\n├── README.md\n├── src/\n│   ├── index.ts          # Main entry point with McpServer initialization\n│   ├── types.ts          # TypeScript type definitions and interfaces\n│   ├── tools/            # Tool implementations (one file per domain)\n│   ├── services/         # API clients and shared utilities\n│   ├── schemas/          # Zod validation schemas\n│   └── constants.ts      # Shared constants (API_URL, CHARACTER_LIMIT, etc.)\n└── dist/                 # Built JavaScript files (entry point: dist/index.js)\n```\n\n## Tool Implementation\n\n### Tool Naming\n\nUse snake_case for tool names (e.g., \"search_users\", \"create_project\", \"get_channel_info\") with clear, action-oriented names.\n\n**Avoid Naming Conflicts**: Include the service context to prevent overlaps:\n- Use \"slack_send_message\" instead of just \"send_message\"\n- Use \"github_create_issue\" instead of just \"create_issue\"\n- Use \"asana_list_tasks\" instead of just \"list_tasks\"\n\n### Tool Structure\n\nTools are registered using the `registerTool` method with the following requirements:\n- Use Zod schemas for runtime input validation and type safety\n- The `description` field must be explicitly provided - JSDoc comments are NOT automatically extracted\n- Explicitly provide `title`, `description`, `inputSchema`, and `annotations`\n- The `inputSchema` must be a Zod schema object (not a JSON schema)\n- Type all parameters and return values explicitly\n\n```typescript\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nconst server = new McpServer({\n  name: \"example-mcp\",\n  version: \"1.0.0\"\n});\n\n// Zod schema for input validation\nconst UserSearchInputSchema = z.object({\n  query: z.string()\n    .min(2, \"Query must be at least 2 characters\")\n    .max(200, \"Query must not exceed 200 characters\")\n    .describe(\"Search string to match against names/emails\"),\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip for pagination\"),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n}).strict();\n\n// Type definition from Zod schema\ntype UserSearchInput = z.infer<typeof UserSearchInputSchema>;\n\nserver.registerTool(\n  \"example_search_users\",\n  {\n    title: \"Search Example Users\",\n    description: `Search for users in the Example system by name, email, or team.\n\nThis tool searches across all user profiles in the Example platform, supporting partial matches and various search filters. It does NOT create or modify users, only searches existing ones.\n\nArgs:\n  - query (string): Search string to match against names/emails\n  - limit (number): Maximum results to return, between 1-100 (default: 20)\n  - offset (number): Number of results to skip for pagination (default: 0)\n  - response_format ('markdown' | 'json'): Output format (default: 'markdown')\n\nReturns:\n  For JSON format: Structured data with schema:\n  {\n    \"total\": number,           // Total number of matches found\n    \"count\": number,           // Number of results in this response\n    \"offset\": number,          // Current pagination offset\n    \"users\": [\n      {\n        \"id\": string,          // User ID (e.g., \"U123456789\")\n        \"name\": string,        // Full name (e.g., \"John Doe\")\n        \"email\": string,       // Email address\n        \"team\": string,        // Team name (optional)\n        \"active\": boolean      // Whether user is active\n      }\n    ],\n    \"has_more\": boolean,       // Whether more results are available\n    \"next_offset\": number      // Offset for next page (if has_more is true)\n  }\n\nExamples:\n  - Use when: \"Find all marketing team members\" -> params with query=\"team:marketing\"\n  - Use when: \"Search for John's account\" -> params with query=\"john\"\n  - Don't use when: You need to create a user (use example_create_user instead)\n\nError Handling:\n  - Returns \"Error: Rate limit exceeded\" if too many requests (429 status)\n  - Returns \"No users found matching '<query>'\" if search returns empty`,\n    inputSchema: UserSearchInputSchema,\n    annotations: {\n      readOnlyHint: true,\n      destructiveHint: false,\n      idempotentHint: true,\n      openWorldHint: true\n    }\n  },\n  async (params: UserSearchInput) => {\n    try {\n      // Input validation is handled by Zod schema\n      // Make API request using validated parameters\n      const data = await makeApiRequest<any>(\n        \"users/search\",\n        \"GET\",\n        undefined,\n        {\n          q: params.query,\n          limit: params.limit,\n          offset: params.offset\n        }\n      );\n\n      const users = data.users || [];\n      const total = data.total || 0;\n\n      if (!users.length) {\n        return {\n          content: [{\n            type: \"text\",\n            text: `No users found matching '${params.query}'`\n          }]\n        };\n      }\n\n      // Prepare structured output\n      const output = {\n        total,\n        count: users.length,\n        offset: params.offset,\n        users: users.map((user: any) => ({\n          id: user.id,\n          name: user.name,\n          email: user.email,\n          ...(user.team ? { team: user.team } : {}),\n          active: user.active ?? true\n        })),\n        has_more: total > params.offset + users.length,\n        ...(total > params.offset + users.length ? {\n          next_offset: params.offset + users.length\n        } : {})\n      };\n\n      // Format text representation based on requested format\n      let textContent: string;\n      if (params.response_format === ResponseFormat.MARKDOWN) {\n        const lines = [`# User Search Results: '${params.query}'`, \"\",\n          `Found ${total} users (showing ${users.length})`, \"\"];\n        for (const user of users) {\n          lines.push(`## ${user.name} (${user.id})`);\n          lines.push(`- **Email**: ${user.email}`);\n          if (user.team) lines.push(`- **Team**: ${user.team}`);\n          lines.push(\"\");\n        }\n        textContent = lines.join(\"\\n\");\n      } else {\n        textContent = JSON.stringify(output, null, 2);\n      }\n\n      return {\n        content: [{ type: \"text\", text: textContent }],\n        structuredContent: output // Modern pattern for structured data\n      };\n    } catch (error) {\n      return {\n        content: [{\n          type: \"text\",\n          text: handleApiError(error)\n        }]\n      };\n    }\n  }\n);\n```\n\n## Zod Schemas for Input Validation\n\nZod provides runtime type validation:\n\n```typescript\nimport { z } from \"zod\";\n\n// Basic schema with validation\nconst CreateUserSchema = z.object({\n  name: z.string()\n    .min(1, \"Name is required\")\n    .max(100, \"Name must not exceed 100 characters\"),\n  email: z.string()\n    .email(\"Invalid email format\"),\n  age: z.number()\n    .int(\"Age must be a whole number\")\n    .min(0, \"Age cannot be negative\")\n    .max(150, \"Age cannot be greater than 150\")\n}).strict();  // Use .strict() to forbid extra fields\n\n// Enums\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\nconst SearchSchema = z.object({\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format\")\n});\n\n// Optional fields with defaults\nconst PaginationSchema = z.object({\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip\")\n});\n```\n\n## Response Format Options\n\nSupport multiple output formats for flexibility:\n\n```typescript\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\nconst inputSchema = z.object({\n  query: z.string(),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n});\n```\n\n**Markdown format**:\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format\n- Show display names with IDs in parentheses\n- Omit verbose metadata\n- Group related information logically\n\n**JSON format**:\n- Return complete, structured data suitable for programmatic processing\n- Include all available fields and metadata\n- Use consistent field names and types\n\n## Pagination Implementation\n\nFor tools that list resources:\n\n```typescript\nconst ListSchema = z.object({\n  limit: z.number().int().min(1).max(100).default(20),\n  offset: z.number().int().min(0).default(0)\n});\n\nasync function listItems(params: z.infer<typeof ListSchema>) {\n  const data = await apiRequest(params.limit, params.offset);\n\n  const response = {\n    total: data.total,\n    count: data.items.length,\n    offset: params.offset,\n    items: data.items,\n    has_more: data.total > params.offset + data.items.length,\n    next_offset: data.total > params.offset + data.items.length\n      ? params.offset + data.items.length\n      : undefined\n  };\n\n  return JSON.stringify(response, null, 2);\n}\n```\n\n## Character Limits and Truncation\n\nAdd a CHARACTER_LIMIT constant to prevent overwhelming responses:\n\n```typescript\n// At module level in constants.ts\nexport const CHARACTER_LIMIT = 25000;  // Maximum response size in characters\n\nasync function searchTool(params: SearchInput) {\n  let result = generateResponse(data);\n\n  // Check character limit and truncate if needed\n  if (result.length > CHARACTER_LIMIT) {\n    const truncatedData = data.slice(0, Math.max(1, data.length / 2));\n    response.data = truncatedData;\n    response.truncated = true;\n    response.truncation_message =\n      `Response truncated from ${data.length} to ${truncatedData.length} items. ` +\n      `Use 'offset' parameter or add filters to see more results.`;\n    result = JSON.stringify(response, null, 2);\n  }\n\n  return result;\n}\n```\n\n## Error Handling\n\nProvide clear, actionable error messages:\n\n```typescript\nimport axios, { AxiosError } from \"axios\";\n\nfunction handleApiError(error: unknown): string {\n  if (error instanceof AxiosError) {\n    if (error.response) {\n      switch (error.response.status) {\n        case 404:\n          return \"Error: Resource not found. Please check the ID is correct.\";\n        case 403:\n          return \"Error: Permission denied. You don't have access to this resource.\";\n        case 429:\n          return \"Error: Rate limit exceeded. Please wait before making more requests.\";\n        default:\n          return `Error: API request failed with status ${error.response.status}`;\n      }\n    } else if (error.code === \"ECONNABORTED\") {\n      return \"Error: Request timed out. Please try again.\";\n    }\n  }\n  return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;\n}\n```\n\n## Shared Utilities\n\nExtract common functionality into reusable functions:\n\n```typescript\n// Shared API request function\nasync function makeApiRequest<T>(\n  endpoint: string,\n  method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" = \"GET\",\n  data?: any,\n  params?: any\n): Promise<T> {\n  try {\n    const response = await axios({\n      method,\n      url: `${API_BASE_URL}/${endpoint}`,\n      data,\n      params,\n      timeout: 30000,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Accept\": \"application/json\"\n      }\n    });\n    return response.data;\n  } catch (error) {\n    throw error;\n  }\n}\n```\n\n## Async/Await Best Practices\n\nAlways use async/await for network requests and I/O operations:\n\n```typescript\n// Good: Async network request\nasync function fetchData(resourceId: string): Promise<ResourceData> {\n  const response = await axios.get(`${API_URL}/resource/${resourceId}`);\n  return response.data;\n}\n\n// Bad: Promise chains\nfunction fetchData(resourceId: string): Promise<ResourceData> {\n  return axios.get(`${API_URL}/resource/${resourceId}`)\n    .then(response => response.data);  // Harder to read and maintain\n}\n```\n\n## TypeScript Best Practices\n\n1. **Use Strict TypeScript**: Enable strict mode in tsconfig.json\n2. **Define Interfaces**: Create clear interface definitions for all data structures\n3. **Avoid `any`**: Use proper types or `unknown` instead of `any`\n4. **Zod for Runtime Validation**: Use Zod schemas to validate external data\n5. **Type Guards**: Create type guard functions for complex type checking\n6. **Error Handling**: Always use try-catch with proper error type checking\n7. **Null Safety**: Use optional chaining (`?.`) and nullish coalescing (`??`)\n\n```typescript\n// Good: Type-safe with Zod and interfaces\ninterface UserResponse {\n  id: string;\n  name: string;\n  email: string;\n  team?: string;\n  active: boolean;\n}\n\nconst UserSchema = z.object({\n  id: z.string(),\n  name: z.string(),\n  email: z.string().email(),\n  team: z.string().optional(),\n  active: z.boolean()\n});\n\ntype User = z.infer<typeof UserSchema>;\n\nasync function getUser(id: string): Promise<User> {\n  const data = await apiCall(`/users/${id}`);\n  return UserSchema.parse(data);  // Runtime validation\n}\n\n// Bad: Using any\nasync function getUser(id: string): Promise<any> {\n  return await apiCall(`/users/${id}`);  // No type safety\n}\n```\n\n## Package Configuration\n\n### package.json\n\n```json\n{\n  \"name\": \"{service}-mcp-server\",\n  \"version\": \"1.0.0\",\n  \"description\": \"MCP server for {Service} API integration\",\n  \"type\": \"module\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"start\": \"node dist/index.js\",\n    \"dev\": \"tsx watch src/index.ts\",\n    \"build\": \"tsc\",\n    \"clean\": \"rm -rf dist\"\n  },\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"dependencies\": {\n    \"@modelcontextprotocol/sdk\": \"^1.6.1\",\n    \"axios\": \"^1.7.9\",\n    \"zod\": \"^3.23.8\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.10.0\",\n    \"tsx\": \"^4.19.2\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n```\n\n### tsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"lib\": [\"ES2022\"],\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true,\n    \"allowSyntheticDefaultImports\": true\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n## Complete Example\n\n```typescript\n#!/usr/bin/env node\n/**\n * MCP Server for Example Service.\n *\n * This server provides tools to interact with Example API, including user search,\n * project management, and data export capabilities.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport axios, { AxiosError } from \"axios\";\n\n// Constants\nconst API_BASE_URL = \"https://api.example.com/v1\";\nconst CHARACTER_LIMIT = 25000;\n\n// Enums\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\n// Zod schemas\nconst UserSearchInputSchema = z.object({\n  query: z.string()\n    .min(2, \"Query must be at least 2 characters\")\n    .max(200, \"Query must not exceed 200 characters\")\n    .describe(\"Search string to match against names/emails\"),\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip for pagination\"),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n}).strict();\n\ntype UserSearchInput = z.infer<typeof UserSearchInputSchema>;\n\n// Shared utility functions\nasync function makeApiRequest<T>(\n  endpoint: string,\n  method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" = \"GET\",\n  data?: any,\n  params?: any\n): Promise<T> {\n  try {\n    const response = await axios({\n      method,\n      url: `${API_BASE_URL}/${endpoint}`,\n      data,\n      params,\n      timeout: 30000,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Accept\": \"application/json\"\n      }\n    });\n    return response.data;\n  } catch (error) {\n    throw error;\n  }\n}\n\nfunction handleApiError(error: unknown): string {\n  if (error instanceof AxiosError) {\n    if (error.response) {\n      switch (error.response.status) {\n        case 404:\n          return \"Error: Resource not found. Please check the ID is correct.\";\n        case 403:\n          return \"Error: Permission denied. You don't have access to this resource.\";\n        case 429:\n          return \"Error: Rate limit exceeded. Please wait before making more requests.\";\n        default:\n          return `Error: API request failed with status ${error.response.status}`;\n      }\n    } else if (error.code === \"ECONNABORTED\") {\n      return \"Error: Request timed out. Please try again.\";\n    }\n  }\n  return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;\n}\n\n// Create MCP server instance\nconst server = new McpServer({\n  name: \"example-mcp\",\n  version: \"1.0.0\"\n});\n\n// Register tools\nserver.registerTool(\n  \"example_search_users\",\n  {\n    title: \"Search Example Users\",\n    description: `[Full description as shown above]`,\n    inputSchema: UserSearchInputSchema,\n    annotations: {\n      readOnlyHint: true,\n      destructiveHint: false,\n      idempotentHint: true,\n      openWorldHint: true\n    }\n  },\n  async (params: UserSearchInput) => {\n    // Implementation as shown above\n  }\n);\n\n// Main function\n// For stdio (local):\nasync function runStdio() {\n  if (!process.env.EXAMPLE_API_KEY) {\n    console.error(\"ERROR: EXAMPLE_API_KEY environment variable is required\");\n    process.exit(1);\n  }\n\n  const transport = new StdioServerTransport();\n  await server.connect(transport);\n  console.error(\"MCP server running via stdio\");\n}\n\n// For streamable HTTP (remote):\nasync function runHTTP() {\n  if (!process.env.EXAMPLE_API_KEY) {\n    console.error(\"ERROR: EXAMPLE_API_KEY environment variable is required\");\n    process.exit(1);\n  }\n\n  const app = express();\n  app.use(express.json());\n\n  app.post('/mcp', async (req, res) => {\n    const transport = new StreamableHTTPServerTransport({\n      sessionIdGenerator: undefined,\n      enableJsonResponse: true\n    });\n    res.on('close', () => transport.close());\n    await server.connect(transport);\n    await transport.handleRequest(req, res, req.body);\n  });\n\n  const port = parseInt(process.env.PORT || '3000');\n  app.listen(port, () => {\n    console.error(`MCP server running on http://localhost:${port}/mcp`);\n  });\n}\n\n// Choose transport based on environment\nconst transport = process.env.TRANSPORT || 'stdio';\nif (transport === 'http') {\n  runHTTP().catch(error => {\n    console.error(\"Server error:\", error);\n    process.exit(1);\n  });\n} else {\n  runStdio().catch(error => {\n    console.error(\"Server error:\", error);\n    process.exit(1);\n  });\n}\n```\n\n---\n\n## Advanced MCP Features\n\n### Resource Registration\n\nExpose data as resources for efficient, URI-based access:\n\n```typescript\nimport { ResourceTemplate } from \"@modelcontextprotocol/sdk/types.js\";\n\n// Register a resource with URI template\nserver.registerResource(\n  {\n    uri: \"file://documents/{name}\",\n    name: \"Document Resource\",\n    description: \"Access documents by name\",\n    mimeType: \"text/plain\"\n  },\n  async (uri: string) => {\n    // Extract parameter from URI\n    const match = uri.match(/^file:\\/\\/documents\\/(.+)$/);\n    if (!match) {\n      throw new Error(\"Invalid URI format\");\n    }\n\n    const documentName = match[1];\n    const content = await loadDocument(documentName);\n\n    return {\n      contents: [{\n        uri,\n        mimeType: \"text/plain\",\n        text: content\n      }]\n    };\n  }\n);\n\n// List available resources dynamically\nserver.registerResourceList(async () => {\n  const documents = await getAvailableDocuments();\n  return {\n    resources: documents.map(doc => ({\n      uri: `file://documents/${doc.name}`,\n      name: doc.name,\n      mimeType: \"text/plain\",\n      description: doc.description\n    }))\n  };\n});\n```\n\n**When to use Resources vs Tools:**\n- **Resources**: For data access with simple URI-based parameters\n- **Tools**: For complex operations requiring validation and business logic\n- **Resources**: When data is relatively static or template-based\n- **Tools**: When operations have side effects or complex workflows\n\n### Transport Options\n\nThe TypeScript SDK supports two main transport mechanisms:\n\n#### Streamable HTTP (Recommended for Remote Servers)\n\n```typescript\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport express from \"express\";\n\nconst app = express();\napp.use(express.json());\n\napp.post('/mcp', async (req, res) => {\n  // Create new transport for each request (stateless, prevents request ID collisions)\n  const transport = new StreamableHTTPServerTransport({\n    sessionIdGenerator: undefined,\n    enableJsonResponse: true\n  });\n\n  res.on('close', () => transport.close());\n\n  await server.connect(transport);\n  await transport.handleRequest(req, res, req.body);\n});\n\napp.listen(3000);\n```\n\n#### stdio (For Local Integrations)\n\n```typescript\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n```\n\n**Transport selection:**\n- **Streamable HTTP**: Web services, remote access, multiple clients\n- **stdio**: Command-line tools, local development, subprocess integration\n\n### Notification Support\n\nNotify clients when server state changes:\n\n```typescript\n// Notify when tools list changes\nserver.notification({\n  method: \"notifications/tools/list_changed\"\n});\n\n// Notify when resources change\nserver.notification({\n  method: \"notifications/resources/list_changed\"\n});\n```\n\nUse notifications sparingly - only when server capabilities genuinely change.\n\n---\n\n## Code Best Practices\n\n### Code Composability and Reusability\n\nYour implementation MUST prioritize composability and code reuse:\n\n1. **Extract Common Functionality**:\n   - Create reusable helper functions for operations used across multiple tools\n   - Build shared API clients for HTTP requests instead of duplicating code\n   - Centralize error handling logic in utility functions\n   - Extract business logic into dedicated functions that can be composed\n   - Extract shared markdown or JSON field selection & formatting functionality\n\n2. **Avoid Duplication**:\n   - NEVER copy-paste similar code between tools\n   - If you find yourself writing similar logic twice, extract it into a function\n   - Common operations like pagination, filtering, field selection, and formatting should be shared\n   - Authentication/authorization logic should be centralized\n\n## Building and Running\n\nAlways build your TypeScript code before running:\n\n```bash\n# Build the project\nnpm run build\n\n# Run the server\nnpm start\n\n# Development with auto-reload\nnpm run dev\n```\n\nAlways ensure `npm run build` completes successfully before considering the implementation complete.\n\n## Quality Checklist\n\nBefore finalizing your Node/TypeScript MCP server implementation, ensure:\n\n### Strategic Design\n- [ ] Tools enable complete workflows, not just API endpoint wrappers\n- [ ] Tool names reflect natural task subdivisions\n- [ ] Response formats optimize for agent context efficiency\n- [ ] Human-readable identifiers used where appropriate\n- [ ] Error messages guide agents toward correct usage\n\n### Implementation Quality\n- [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented\n- [ ] All tools registered using `registerTool` with complete configuration\n- [ ] All tools include `title`, `description`, `inputSchema`, and `annotations`\n- [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- [ ] All tools use Zod schemas for runtime input validation with `.strict()` enforcement\n- [ ] All Zod schemas have proper constraints and descriptive error messages\n- [ ] All tools have comprehensive descriptions with explicit input/output types\n- [ ] Descriptions include return value examples and complete schema documentation\n- [ ] Error messages are clear, actionable, and educational\n\n### TypeScript Quality\n- [ ] TypeScript interfaces are defined for all data structures\n- [ ] Strict TypeScript is enabled in tsconfig.json\n- [ ] No use of `any` type - use `unknown` or proper types instead\n- [ ] All async functions have explicit Promise<T> return types\n- [ ] Error handling uses proper type guards (e.g., `axios.isAxiosError`, `z.ZodError`)\n\n### Advanced Features (where applicable)\n- [ ] Resources registered for appropriate data endpoints\n- [ ] Appropriate transport configured (stdio or streamable HTTP)\n- [ ] Notifications implemented for dynamic server capabilities\n- [ ] Type-safe with SDK interfaces\n\n### Project Configuration\n- [ ] Package.json includes all necessary dependencies\n- [ ] Build script produces working JavaScript in dist/ directory\n- [ ] Main entry point is properly configured as dist/index.js\n- [ ] Server name follows format: `{service}-mcp-server`\n- [ ] tsconfig.json properly configured with strict mode\n\n### Code Quality\n- [ ] Pagination is properly implemented where applicable\n- [ ] Large responses check CHARACTER_LIMIT constant and truncate with clear messages\n- [ ] Filtering options are provided for potentially large result sets\n- [ ] All network operations handle timeouts and connection errors gracefully\n- [ ] Common functionality is extracted into reusable functions\n- [ ] Return types are consistent across similar operations\n\n### Testing and Build\n- [ ] `npm run build` completes successfully without errors\n- [ ] dist/index.js created and executable\n- [ ] Server runs: `node dist/index.js --help`\n- [ ] All imports resolve correctly\n- [ ] Sample tool calls work as expected"
  },
  {
    "path": "skills/mcp-builder/reference/python_mcp_server.md",
    "content": "# Python MCP Server Implementation Guide\n\n## Overview\n\nThis document provides Python-specific best practices and examples for implementing MCP servers using the MCP Python SDK. It covers server setup, tool registration patterns, input validation with Pydantic, error handling, and complete working examples.\n\n---\n\n## Quick Reference\n\n### Key Imports\n```python\nfrom mcp.server.fastmcp import FastMCP\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\nfrom typing import Optional, List, Dict, Any\nfrom enum import Enum\nimport httpx\n```\n\n### Server Initialization\n```python\nmcp = FastMCP(\"service_mcp\")\n```\n\n### Tool Registration Pattern\n```python\n@mcp.tool(name=\"tool_name\", annotations={...})\nasync def tool_function(params: InputModel) -> str:\n    # Implementation\n    pass\n```\n\n---\n\n## MCP Python SDK and FastMCP\n\nThe official MCP Python SDK provides FastMCP, a high-level framework for building MCP servers. It provides:\n- Automatic description and inputSchema generation from function signatures and docstrings\n- Pydantic model integration for input validation\n- Decorator-based tool registration with `@mcp.tool`\n\n**For complete SDK documentation, use WebFetch to load:**\n`https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n\n## Server Naming Convention\n\nPython MCP servers must follow this naming pattern:\n- **Format**: `{service}_mcp` (lowercase with underscores)\n- **Examples**: `github_mcp`, `jira_mcp`, `stripe_mcp`\n\nThe name should be:\n- General (not tied to specific features)\n- Descriptive of the service/API being integrated\n- Easy to infer from the task description\n- Without version numbers or dates\n\n## Tool Implementation\n\n### Tool Naming\n\nUse snake_case for tool names (e.g., \"search_users\", \"create_project\", \"get_channel_info\") with clear, action-oriented names.\n\n**Avoid Naming Conflicts**: Include the service context to prevent overlaps:\n- Use \"slack_send_message\" instead of just \"send_message\"\n- Use \"github_create_issue\" instead of just \"create_issue\"\n- Use \"asana_list_tasks\" instead of just \"list_tasks\"\n\n### Tool Structure with FastMCP\n\nTools are defined using the `@mcp.tool` decorator with Pydantic models for input validation:\n\n```python\nfrom pydantic import BaseModel, Field, ConfigDict\nfrom mcp.server.fastmcp import FastMCP\n\n# Initialize the MCP server\nmcp = FastMCP(\"example_mcp\")\n\n# Define Pydantic model for input validation\nclass ServiceToolInput(BaseModel):\n    '''Input model for service tool operation.'''\n    model_config = ConfigDict(\n        str_strip_whitespace=True,  # Auto-strip whitespace from strings\n        validate_assignment=True,    # Validate on assignment\n        extra='forbid'              # Forbid extra fields\n    )\n\n    param1: str = Field(..., description=\"First parameter description (e.g., 'user123', 'project-abc')\", min_length=1, max_length=100)\n    param2: Optional[int] = Field(default=None, description=\"Optional integer parameter with constraints\", ge=0, le=1000)\n    tags: Optional[List[str]] = Field(default_factory=list, description=\"List of tags to apply\", max_items=10)\n\n@mcp.tool(\n    name=\"service_tool_name\",\n    annotations={\n        \"title\": \"Human-Readable Tool Title\",\n        \"readOnlyHint\": True,     # Tool does not modify environment\n        \"destructiveHint\": False,  # Tool does not perform destructive operations\n        \"idempotentHint\": True,    # Repeated calls have no additional effect\n        \"openWorldHint\": False     # Tool does not interact with external entities\n    }\n)\nasync def service_tool_name(params: ServiceToolInput) -> str:\n    '''Tool description automatically becomes the 'description' field.\n\n    This tool performs a specific operation on the service. It validates all inputs\n    using the ServiceToolInput Pydantic model before processing.\n\n    Args:\n        params (ServiceToolInput): Validated input parameters containing:\n            - param1 (str): First parameter description\n            - param2 (Optional[int]): Optional parameter with default\n            - tags (Optional[List[str]]): List of tags\n\n    Returns:\n        str: JSON-formatted response containing operation results\n    '''\n    # Implementation here\n    pass\n```\n\n## Pydantic v2 Key Features\n\n- Use `model_config` instead of nested `Config` class\n- Use `field_validator` instead of deprecated `validator`\n- Use `model_dump()` instead of deprecated `dict()`\n- Validators require `@classmethod` decorator\n- Type hints are required for validator methods\n\n```python\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\n\nclass CreateUserInput(BaseModel):\n    model_config = ConfigDict(\n        str_strip_whitespace=True,\n        validate_assignment=True\n    )\n\n    name: str = Field(..., description=\"User's full name\", min_length=1, max_length=100)\n    email: str = Field(..., description=\"User's email address\", pattern=r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$')\n    age: int = Field(..., description=\"User's age\", ge=0, le=150)\n\n    @field_validator('email')\n    @classmethod\n    def validate_email(cls, v: str) -> str:\n        if not v.strip():\n            raise ValueError(\"Email cannot be empty\")\n        return v.lower()\n```\n\n## Response Format Options\n\nSupport multiple output formats for flexibility:\n\n```python\nfrom enum import Enum\n\nclass ResponseFormat(str, Enum):\n    '''Output format for tool responses.'''\n    MARKDOWN = \"markdown\"\n    JSON = \"json\"\n\nclass UserSearchInput(BaseModel):\n    query: str = Field(..., description=\"Search query\")\n    response_format: ResponseFormat = Field(\n        default=ResponseFormat.MARKDOWN,\n        description=\"Output format: 'markdown' for human-readable or 'json' for machine-readable\"\n    )\n```\n\n**Markdown format**:\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format (e.g., \"2024-01-15 10:30:00 UTC\" instead of epoch)\n- Show display names with IDs in parentheses (e.g., \"@john.doe (U123456)\")\n- Omit verbose metadata (e.g., show only one profile image URL, not all sizes)\n- Group related information logically\n\n**JSON format**:\n- Return complete, structured data suitable for programmatic processing\n- Include all available fields and metadata\n- Use consistent field names and types\n\n## Pagination Implementation\n\nFor tools that list resources:\n\n```python\nclass ListInput(BaseModel):\n    limit: Optional[int] = Field(default=20, description=\"Maximum results to return\", ge=1, le=100)\n    offset: Optional[int] = Field(default=0, description=\"Number of results to skip for pagination\", ge=0)\n\nasync def list_items(params: ListInput) -> str:\n    # Make API request with pagination\n    data = await api_request(limit=params.limit, offset=params.offset)\n\n    # Return pagination info\n    response = {\n        \"total\": data[\"total\"],\n        \"count\": len(data[\"items\"]),\n        \"offset\": params.offset,\n        \"items\": data[\"items\"],\n        \"has_more\": data[\"total\"] > params.offset + len(data[\"items\"]),\n        \"next_offset\": params.offset + len(data[\"items\"]) if data[\"total\"] > params.offset + len(data[\"items\"]) else None\n    }\n    return json.dumps(response, indent=2)\n```\n\n## Error Handling\n\nProvide clear, actionable error messages:\n\n```python\ndef _handle_api_error(e: Exception) -> str:\n    '''Consistent error formatting across all tools.'''\n    if isinstance(e, httpx.HTTPStatusError):\n        if e.response.status_code == 404:\n            return \"Error: Resource not found. Please check the ID is correct.\"\n        elif e.response.status_code == 403:\n            return \"Error: Permission denied. You don't have access to this resource.\"\n        elif e.response.status_code == 429:\n            return \"Error: Rate limit exceeded. Please wait before making more requests.\"\n        return f\"Error: API request failed with status {e.response.status_code}\"\n    elif isinstance(e, httpx.TimeoutException):\n        return \"Error: Request timed out. Please try again.\"\n    return f\"Error: Unexpected error occurred: {type(e).__name__}\"\n```\n\n## Shared Utilities\n\nExtract common functionality into reusable functions:\n\n```python\n# Shared API request function\nasync def _make_api_request(endpoint: str, method: str = \"GET\", **kwargs) -> dict:\n    '''Reusable function for all API calls.'''\n    async with httpx.AsyncClient() as client:\n        response = await client.request(\n            method,\n            f\"{API_BASE_URL}/{endpoint}\",\n            timeout=30.0,\n            **kwargs\n        )\n        response.raise_for_status()\n        return response.json()\n```\n\n## Async/Await Best Practices\n\nAlways use async/await for network requests and I/O operations:\n\n```python\n# Good: Async network request\nasync def fetch_data(resource_id: str) -> dict:\n    async with httpx.AsyncClient() as client:\n        response = await client.get(f\"{API_URL}/resource/{resource_id}\")\n        response.raise_for_status()\n        return response.json()\n\n# Bad: Synchronous request\ndef fetch_data(resource_id: str) -> dict:\n    response = requests.get(f\"{API_URL}/resource/{resource_id}\")  # Blocks\n    return response.json()\n```\n\n## Type Hints\n\nUse type hints throughout:\n\n```python\nfrom typing import Optional, List, Dict, Any\n\nasync def get_user(user_id: str) -> Dict[str, Any]:\n    data = await fetch_user(user_id)\n    return {\"id\": data[\"id\"], \"name\": data[\"name\"]}\n```\n\n## Tool Docstrings\n\nEvery tool must have comprehensive docstrings with explicit type information:\n\n```python\nasync def search_users(params: UserSearchInput) -> str:\n    '''\n    Search for users in the Example system by name, email, or team.\n\n    This tool searches across all user profiles in the Example platform,\n    supporting partial matches and various search filters. It does NOT\n    create or modify users, only searches existing ones.\n\n    Args:\n        params (UserSearchInput): Validated input parameters containing:\n            - query (str): Search string to match against names/emails (e.g., \"john\", \"@example.com\", \"team:marketing\")\n            - limit (Optional[int]): Maximum results to return, between 1-100 (default: 20)\n            - offset (Optional[int]): Number of results to skip for pagination (default: 0)\n\n    Returns:\n        str: JSON-formatted string containing search results with the following schema:\n\n        Success response:\n        {\n            \"total\": int,           # Total number of matches found\n            \"count\": int,           # Number of results in this response\n            \"offset\": int,          # Current pagination offset\n            \"users\": [\n                {\n                    \"id\": str,      # User ID (e.g., \"U123456789\")\n                    \"name\": str,    # Full name (e.g., \"John Doe\")\n                    \"email\": str,   # Email address (e.g., \"john@example.com\")\n                    \"team\": str     # Team name (e.g., \"Marketing\") - optional\n                }\n            ]\n        }\n\n        Error response:\n        \"Error: <error message>\" or \"No users found matching '<query>'\"\n\n    Examples:\n        - Use when: \"Find all marketing team members\" -> params with query=\"team:marketing\"\n        - Use when: \"Search for John's account\" -> params with query=\"john\"\n        - Don't use when: You need to create a user (use example_create_user instead)\n        - Don't use when: You have a user ID and need full details (use example_get_user instead)\n\n    Error Handling:\n        - Input validation errors are handled by Pydantic model\n        - Returns \"Error: Rate limit exceeded\" if too many requests (429 status)\n        - Returns \"Error: Invalid API authentication\" if API key is invalid (401 status)\n        - Returns formatted list of results or \"No users found matching 'query'\"\n    '''\n```\n\n## Complete Example\n\nSee below for a complete Python MCP server example:\n\n```python\n#!/usr/bin/env python3\n'''\nMCP Server for Example Service.\n\nThis server provides tools to interact with Example API, including user search,\nproject management, and data export capabilities.\n'''\n\nfrom typing import Optional, List, Dict, Any\nfrom enum import Enum\nimport httpx\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\nfrom mcp.server.fastmcp import FastMCP\n\n# Initialize the MCP server\nmcp = FastMCP(\"example_mcp\")\n\n# Constants\nAPI_BASE_URL = \"https://api.example.com/v1\"\n\n# Enums\nclass ResponseFormat(str, Enum):\n    '''Output format for tool responses.'''\n    MARKDOWN = \"markdown\"\n    JSON = \"json\"\n\n# Pydantic Models for Input Validation\nclass UserSearchInput(BaseModel):\n    '''Input model for user search operations.'''\n    model_config = ConfigDict(\n        str_strip_whitespace=True,\n        validate_assignment=True\n    )\n\n    query: str = Field(..., description=\"Search string to match against names/emails\", min_length=2, max_length=200)\n    limit: Optional[int] = Field(default=20, description=\"Maximum results to return\", ge=1, le=100)\n    offset: Optional[int] = Field(default=0, description=\"Number of results to skip for pagination\", ge=0)\n    response_format: ResponseFormat = Field(default=ResponseFormat.MARKDOWN, description=\"Output format\")\n\n    @field_validator('query')\n    @classmethod\n    def validate_query(cls, v: str) -> str:\n        if not v.strip():\n            raise ValueError(\"Query cannot be empty or whitespace only\")\n        return v.strip()\n\n# Shared utility functions\nasync def _make_api_request(endpoint: str, method: str = \"GET\", **kwargs) -> dict:\n    '''Reusable function for all API calls.'''\n    async with httpx.AsyncClient() as client:\n        response = await client.request(\n            method,\n            f\"{API_BASE_URL}/{endpoint}\",\n            timeout=30.0,\n            **kwargs\n        )\n        response.raise_for_status()\n        return response.json()\n\ndef _handle_api_error(e: Exception) -> str:\n    '''Consistent error formatting across all tools.'''\n    if isinstance(e, httpx.HTTPStatusError):\n        if e.response.status_code == 404:\n            return \"Error: Resource not found. Please check the ID is correct.\"\n        elif e.response.status_code == 403:\n            return \"Error: Permission denied. You don't have access to this resource.\"\n        elif e.response.status_code == 429:\n            return \"Error: Rate limit exceeded. Please wait before making more requests.\"\n        return f\"Error: API request failed with status {e.response.status_code}\"\n    elif isinstance(e, httpx.TimeoutException):\n        return \"Error: Request timed out. Please try again.\"\n    return f\"Error: Unexpected error occurred: {type(e).__name__}\"\n\n# Tool definitions\n@mcp.tool(\n    name=\"example_search_users\",\n    annotations={\n        \"title\": \"Search Example Users\",\n        \"readOnlyHint\": True,\n        \"destructiveHint\": False,\n        \"idempotentHint\": True,\n        \"openWorldHint\": True\n    }\n)\nasync def example_search_users(params: UserSearchInput) -> str:\n    '''Search for users in the Example system by name, email, or team.\n\n    [Full docstring as shown above]\n    '''\n    try:\n        # Make API request using validated parameters\n        data = await _make_api_request(\n            \"users/search\",\n            params={\n                \"q\": params.query,\n                \"limit\": params.limit,\n                \"offset\": params.offset\n            }\n        )\n\n        users = data.get(\"users\", [])\n        total = data.get(\"total\", 0)\n\n        if not users:\n            return f\"No users found matching '{params.query}'\"\n\n        # Format response based on requested format\n        if params.response_format == ResponseFormat.MARKDOWN:\n            lines = [f\"# User Search Results: '{params.query}'\", \"\"]\n            lines.append(f\"Found {total} users (showing {len(users)})\")\n            lines.append(\"\")\n\n            for user in users:\n                lines.append(f\"## {user['name']} ({user['id']})\")\n                lines.append(f\"- **Email**: {user['email']}\")\n                if user.get('team'):\n                    lines.append(f\"- **Team**: {user['team']}\")\n                lines.append(\"\")\n\n            return \"\\n\".join(lines)\n\n        else:\n            # Machine-readable JSON format\n            import json\n            response = {\n                \"total\": total,\n                \"count\": len(users),\n                \"offset\": params.offset,\n                \"users\": users\n            }\n            return json.dumps(response, indent=2)\n\n    except Exception as e:\n        return _handle_api_error(e)\n\nif __name__ == \"__main__\":\n    mcp.run()\n```\n\n---\n\n## Advanced FastMCP Features\n\n### Context Parameter Injection\n\nFastMCP can automatically inject a `Context` parameter into tools for advanced capabilities like logging, progress reporting, resource reading, and user interaction:\n\n```python\nfrom mcp.server.fastmcp import FastMCP, Context\n\nmcp = FastMCP(\"example_mcp\")\n\n@mcp.tool()\nasync def advanced_search(query: str, ctx: Context) -> str:\n    '''Advanced tool with context access for logging and progress.'''\n\n    # Report progress for long operations\n    await ctx.report_progress(0.25, \"Starting search...\")\n\n    # Log information for debugging\n    await ctx.log_info(\"Processing query\", {\"query\": query, \"timestamp\": datetime.now()})\n\n    # Perform search\n    results = await search_api(query)\n    await ctx.report_progress(0.75, \"Formatting results...\")\n\n    # Access server configuration\n    server_name = ctx.fastmcp.name\n\n    return format_results(results)\n\n@mcp.tool()\nasync def interactive_tool(resource_id: str, ctx: Context) -> str:\n    '''Tool that can request additional input from users.'''\n\n    # Request sensitive information when needed\n    api_key = await ctx.elicit(\n        prompt=\"Please provide your API key:\",\n        input_type=\"password\"\n    )\n\n    # Use the provided key\n    return await api_call(resource_id, api_key)\n```\n\n**Context capabilities:**\n- `ctx.report_progress(progress, message)` - Report progress for long operations\n- `ctx.log_info(message, data)` / `ctx.log_error()` / `ctx.log_debug()` - Logging\n- `ctx.elicit(prompt, input_type)` - Request input from users\n- `ctx.fastmcp.name` - Access server configuration\n- `ctx.read_resource(uri)` - Read MCP resources\n\n### Resource Registration\n\nExpose data as resources for efficient, template-based access:\n\n```python\n@mcp.resource(\"file://documents/{name}\")\nasync def get_document(name: str) -> str:\n    '''Expose documents as MCP resources.\n\n    Resources are useful for static or semi-static data that doesn't\n    require complex parameters. They use URI templates for flexible access.\n    '''\n    document_path = f\"./docs/{name}\"\n    with open(document_path, \"r\") as f:\n        return f.read()\n\n@mcp.resource(\"config://settings/{key}\")\nasync def get_setting(key: str, ctx: Context) -> str:\n    '''Expose configuration as resources with context.'''\n    settings = await load_settings()\n    return json.dumps(settings.get(key, {}))\n```\n\n**When to use Resources vs Tools:**\n- **Resources**: For data access with simple parameters (URI templates)\n- **Tools**: For complex operations with validation and business logic\n\n### Structured Output Types\n\nFastMCP supports multiple return types beyond strings:\n\n```python\nfrom typing import TypedDict\nfrom dataclasses import dataclass\nfrom pydantic import BaseModel\n\n# TypedDict for structured returns\nclass UserData(TypedDict):\n    id: str\n    name: str\n    email: str\n\n@mcp.tool()\nasync def get_user_typed(user_id: str) -> UserData:\n    '''Returns structured data - FastMCP handles serialization.'''\n    return {\"id\": user_id, \"name\": \"John Doe\", \"email\": \"john@example.com\"}\n\n# Pydantic models for complex validation\nclass DetailedUser(BaseModel):\n    id: str\n    name: str\n    email: str\n    created_at: datetime\n    metadata: Dict[str, Any]\n\n@mcp.tool()\nasync def get_user_detailed(user_id: str) -> DetailedUser:\n    '''Returns Pydantic model - automatically generates schema.'''\n    user = await fetch_user(user_id)\n    return DetailedUser(**user)\n```\n\n### Lifespan Management\n\nInitialize resources that persist across requests:\n\n```python\nfrom contextlib import asynccontextmanager\n\n@asynccontextmanager\nasync def app_lifespan():\n    '''Manage resources that live for the server's lifetime.'''\n    # Initialize connections, load config, etc.\n    db = await connect_to_database()\n    config = load_configuration()\n\n    # Make available to all tools\n    yield {\"db\": db, \"config\": config}\n\n    # Cleanup on shutdown\n    await db.close()\n\nmcp = FastMCP(\"example_mcp\", lifespan=app_lifespan)\n\n@mcp.tool()\nasync def query_data(query: str, ctx: Context) -> str:\n    '''Access lifespan resources through context.'''\n    db = ctx.request_context.lifespan_state[\"db\"]\n    results = await db.query(query)\n    return format_results(results)\n```\n\n### Transport Options\n\nFastMCP supports two main transport mechanisms:\n\n```python\n# stdio transport (for local tools) - default\nif __name__ == \"__main__\":\n    mcp.run()\n\n# Streamable HTTP transport (for remote servers)\nif __name__ == \"__main__\":\n    mcp.run(transport=\"streamable_http\", port=8000)\n```\n\n**Transport selection:**\n- **stdio**: Command-line tools, local integrations, subprocess execution\n- **Streamable HTTP**: Web services, remote access, multiple clients\n\n---\n\n## Code Best Practices\n\n### Code Composability and Reusability\n\nYour implementation MUST prioritize composability and code reuse:\n\n1. **Extract Common Functionality**:\n   - Create reusable helper functions for operations used across multiple tools\n   - Build shared API clients for HTTP requests instead of duplicating code\n   - Centralize error handling logic in utility functions\n   - Extract business logic into dedicated functions that can be composed\n   - Extract shared markdown or JSON field selection & formatting functionality\n\n2. **Avoid Duplication**:\n   - NEVER copy-paste similar code between tools\n   - If you find yourself writing similar logic twice, extract it into a function\n   - Common operations like pagination, filtering, field selection, and formatting should be shared\n   - Authentication/authorization logic should be centralized\n\n### Python-Specific Best Practices\n\n1. **Use Type Hints**: Always include type annotations for function parameters and return values\n2. **Pydantic Models**: Define clear Pydantic models for all input validation\n3. **Avoid Manual Validation**: Let Pydantic handle input validation with constraints\n4. **Proper Imports**: Group imports (standard library, third-party, local)\n5. **Error Handling**: Use specific exception types (httpx.HTTPStatusError, not generic Exception)\n6. **Async Context Managers**: Use `async with` for resources that need cleanup\n7. **Constants**: Define module-level constants in UPPER_CASE\n\n## Quality Checklist\n\nBefore finalizing your Python MCP server implementation, ensure:\n\n### Strategic Design\n- [ ] Tools enable complete workflows, not just API endpoint wrappers\n- [ ] Tool names reflect natural task subdivisions\n- [ ] Response formats optimize for agent context efficiency\n- [ ] Human-readable identifiers used where appropriate\n- [ ] Error messages guide agents toward correct usage\n\n### Implementation Quality\n- [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented\n- [ ] All tools have descriptive names and documentation\n- [ ] Return types are consistent across similar operations\n- [ ] Error handling is implemented for all external calls\n- [ ] Server name follows format: `{service}_mcp`\n- [ ] All network operations use async/await\n- [ ] Common functionality is extracted into reusable functions\n- [ ] Error messages are clear, actionable, and educational\n- [ ] Outputs are properly validated and formatted\n\n### Tool Configuration\n- [ ] All tools implement 'name' and 'annotations' in the decorator\n- [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- [ ] All tools use Pydantic BaseModel for input validation with Field() definitions\n- [ ] All Pydantic Fields have explicit types and descriptions with constraints\n- [ ] All tools have comprehensive docstrings with explicit input/output types\n- [ ] Docstrings include complete schema structure for dict/JSON returns\n- [ ] Pydantic models handle input validation (no manual validation needed)\n\n### Advanced Features (where applicable)\n- [ ] Context injection used for logging, progress, or elicitation\n- [ ] Resources registered for appropriate data endpoints\n- [ ] Lifespan management implemented for persistent connections\n- [ ] Structured output types used (TypedDict, Pydantic models)\n- [ ] Appropriate transport configured (stdio or streamable HTTP)\n\n### Code Quality\n- [ ] File includes proper imports including Pydantic imports\n- [ ] Pagination is properly implemented where applicable\n- [ ] Filtering options are provided for potentially large result sets\n- [ ] All async functions are properly defined with `async def`\n- [ ] HTTP client usage follows async patterns with proper context managers\n- [ ] Type hints are used throughout the code\n- [ ] Constants are defined at module level in UPPER_CASE\n\n### Testing\n- [ ] Server runs successfully: `python your_server.py --help`\n- [ ] All imports resolve correctly\n- [ ] Sample tool calls work as expected\n- [ ] Error scenarios handled gracefully"
  },
  {
    "path": "skills/mcp-builder/scripts/connections.py",
    "content": "\"\"\"Lightweight connection handling for MCP servers.\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom contextlib import AsyncExitStack\nfrom typing import Any\n\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.sse import sse_client\nfrom mcp.client.stdio import stdio_client\nfrom mcp.client.streamable_http import streamablehttp_client\n\n\nclass MCPConnection(ABC):\n    \"\"\"Base class for MCP server connections.\"\"\"\n\n    def __init__(self):\n        self.session = None\n        self._stack = None\n\n    @abstractmethod\n    def _create_context(self):\n        \"\"\"Create the connection context based on connection type.\"\"\"\n\n    async def __aenter__(self):\n        \"\"\"Initialize MCP server connection.\"\"\"\n        self._stack = AsyncExitStack()\n        await self._stack.__aenter__()\n\n        try:\n            ctx = self._create_context()\n            result = await self._stack.enter_async_context(ctx)\n\n            if len(result) == 2:\n                read, write = result\n            elif len(result) == 3:\n                read, write, _ = result\n            else:\n                raise ValueError(f\"Unexpected context result: {result}\")\n\n            session_ctx = ClientSession(read, write)\n            self.session = await self._stack.enter_async_context(session_ctx)\n            await self.session.initialize()\n            return self\n        except BaseException:\n            await self._stack.__aexit__(None, None, None)\n            raise\n\n    async def __aexit__(self, exc_type, exc_val, exc_tb):\n        \"\"\"Clean up MCP server connection resources.\"\"\"\n        if self._stack:\n            await self._stack.__aexit__(exc_type, exc_val, exc_tb)\n        self.session = None\n        self._stack = None\n\n    async def list_tools(self) -> list[dict[str, Any]]:\n        \"\"\"Retrieve available tools from the MCP server.\"\"\"\n        response = await self.session.list_tools()\n        return [\n            {\n                \"name\": tool.name,\n                \"description\": tool.description,\n                \"input_schema\": tool.inputSchema,\n            }\n            for tool in response.tools\n        ]\n\n    async def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any:\n        \"\"\"Call a tool on the MCP server with provided arguments.\"\"\"\n        result = await self.session.call_tool(tool_name, arguments=arguments)\n        return result.content\n\n\nclass MCPConnectionStdio(MCPConnection):\n    \"\"\"MCP connection using standard input/output.\"\"\"\n\n    def __init__(self, command: str, args: list[str] = None, env: dict[str, str] = None):\n        super().__init__()\n        self.command = command\n        self.args = args or []\n        self.env = env\n\n    def _create_context(self):\n        return stdio_client(\n            StdioServerParameters(command=self.command, args=self.args, env=self.env)\n        )\n\n\nclass MCPConnectionSSE(MCPConnection):\n    \"\"\"MCP connection using Server-Sent Events.\"\"\"\n\n    def __init__(self, url: str, headers: dict[str, str] = None):\n        super().__init__()\n        self.url = url\n        self.headers = headers or {}\n\n    def _create_context(self):\n        return sse_client(url=self.url, headers=self.headers)\n\n\nclass MCPConnectionHTTP(MCPConnection):\n    \"\"\"MCP connection using Streamable HTTP.\"\"\"\n\n    def __init__(self, url: str, headers: dict[str, str] = None):\n        super().__init__()\n        self.url = url\n        self.headers = headers or {}\n\n    def _create_context(self):\n        return streamablehttp_client(url=self.url, headers=self.headers)\n\n\ndef create_connection(\n    transport: str,\n    command: str = None,\n    args: list[str] = None,\n    env: dict[str, str] = None,\n    url: str = None,\n    headers: dict[str, str] = None,\n) -> MCPConnection:\n    \"\"\"Factory function to create the appropriate MCP connection.\n\n    Args:\n        transport: Connection type (\"stdio\", \"sse\", or \"http\")\n        command: Command to run (stdio only)\n        args: Command arguments (stdio only)\n        env: Environment variables (stdio only)\n        url: Server URL (sse and http only)\n        headers: HTTP headers (sse and http only)\n\n    Returns:\n        MCPConnection instance\n    \"\"\"\n    transport = transport.lower()\n\n    if transport == \"stdio\":\n        if not command:\n            raise ValueError(\"Command is required for stdio transport\")\n        return MCPConnectionStdio(command=command, args=args, env=env)\n\n    elif transport == \"sse\":\n        if not url:\n            raise ValueError(\"URL is required for sse transport\")\n        return MCPConnectionSSE(url=url, headers=headers)\n\n    elif transport in [\"http\", \"streamable_http\", \"streamable-http\"]:\n        if not url:\n            raise ValueError(\"URL is required for http transport\")\n        return MCPConnectionHTTP(url=url, headers=headers)\n\n    else:\n        raise ValueError(f\"Unsupported transport type: {transport}. Use 'stdio', 'sse', or 'http'\")\n"
  },
  {
    "path": "skills/mcp-builder/scripts/evaluation.py",
    "content": "\"\"\"MCP Server Evaluation Harness\n\nThis script evaluates MCP servers by running test questions against them using Claude.\n\"\"\"\n\nimport argparse\nimport asyncio\nimport json\nimport re\nimport sys\nimport time\nimport traceback\nimport xml.etree.ElementTree as ET\nfrom pathlib import Path\nfrom typing import Any\n\nfrom anthropic import Anthropic\n\nfrom connections import create_connection\n\nEVALUATION_PROMPT = \"\"\"You are an AI assistant with access to tools.\n\nWhen given a task, you MUST:\n1. Use the available tools to complete the task\n2. Provide summary of each step in your approach, wrapped in <summary> tags\n3. Provide feedback on the tools provided, wrapped in <feedback> tags\n4. Provide your final response, wrapped in <response> tags\n\nSummary Requirements:\n- In your <summary> tags, you must explain:\n  - The steps you took to complete the task\n  - Which tools you used, in what order, and why\n  - The inputs you provided to each tool\n  - The outputs you received from each tool\n  - A summary for how you arrived at the response\n\nFeedback Requirements:\n- In your <feedback> tags, provide constructive feedback on the tools:\n  - Comment on tool names: Are they clear and descriptive?\n  - Comment on input parameters: Are they well-documented? Are required vs optional parameters clear?\n  - Comment on descriptions: Do they accurately describe what the tool does?\n  - Comment on any errors encountered during tool usage: Did the tool fail to execute? Did the tool return too many tokens?\n  - Identify specific areas for improvement and explain WHY they would help\n  - Be specific and actionable in your suggestions\n\nResponse Requirements:\n- Your response should be concise and directly address what was asked\n- Always wrap your final response in <response> tags\n- If you cannot solve the task return <response>NOT_FOUND</response>\n- For numeric responses, provide just the number\n- For IDs, provide just the ID\n- For names or text, provide the exact text requested\n- Your response should go last\"\"\"\n\n\ndef parse_evaluation_file(file_path: Path) -> list[dict[str, Any]]:\n    \"\"\"Parse XML evaluation file with qa_pair elements.\"\"\"\n    try:\n        tree = ET.parse(file_path)\n        root = tree.getroot()\n        evaluations = []\n\n        for qa_pair in root.findall(\".//qa_pair\"):\n            question_elem = qa_pair.find(\"question\")\n            answer_elem = qa_pair.find(\"answer\")\n\n            if question_elem is not None and answer_elem is not None:\n                evaluations.append({\n                    \"question\": (question_elem.text or \"\").strip(),\n                    \"answer\": (answer_elem.text or \"\").strip(),\n                })\n\n        return evaluations\n    except Exception as e:\n        print(f\"Error parsing evaluation file {file_path}: {e}\")\n        return []\n\n\ndef extract_xml_content(text: str, tag: str) -> str | None:\n    \"\"\"Extract content from XML tags.\"\"\"\n    pattern = rf\"<{tag}>(.*?)</{tag}>\"\n    matches = re.findall(pattern, text, re.DOTALL)\n    return matches[-1].strip() if matches else None\n\n\nasync def agent_loop(\n    client: Anthropic,\n    model: str,\n    question: str,\n    tools: list[dict[str, Any]],\n    connection: Any,\n) -> tuple[str, dict[str, Any]]:\n    \"\"\"Run the agent loop with MCP tools.\"\"\"\n    messages = [{\"role\": \"user\", \"content\": question}]\n\n    response = await asyncio.to_thread(\n        client.messages.create,\n        model=model,\n        max_tokens=4096,\n        system=EVALUATION_PROMPT,\n        messages=messages,\n        tools=tools,\n    )\n\n    messages.append({\"role\": \"assistant\", \"content\": response.content})\n\n    tool_metrics = {}\n\n    while response.stop_reason == \"tool_use\":\n        tool_use = next(block for block in response.content if block.type == \"tool_use\")\n        tool_name = tool_use.name\n        tool_input = tool_use.input\n\n        tool_start_ts = time.time()\n        try:\n            tool_result = await connection.call_tool(tool_name, tool_input)\n            tool_response = json.dumps(tool_result) if isinstance(tool_result, (dict, list)) else str(tool_result)\n        except Exception as e:\n            tool_response = f\"Error executing tool {tool_name}: {str(e)}\\n\"\n            tool_response += traceback.format_exc()\n        tool_duration = time.time() - tool_start_ts\n\n        if tool_name not in tool_metrics:\n            tool_metrics[tool_name] = {\"count\": 0, \"durations\": []}\n        tool_metrics[tool_name][\"count\"] += 1\n        tool_metrics[tool_name][\"durations\"].append(tool_duration)\n\n        messages.append({\n            \"role\": \"user\",\n            \"content\": [{\n                \"type\": \"tool_result\",\n                \"tool_use_id\": tool_use.id,\n                \"content\": tool_response,\n            }]\n        })\n\n        response = await asyncio.to_thread(\n            client.messages.create,\n            model=model,\n            max_tokens=4096,\n            system=EVALUATION_PROMPT,\n            messages=messages,\n            tools=tools,\n        )\n        messages.append({\"role\": \"assistant\", \"content\": response.content})\n\n    response_text = next(\n        (block.text for block in response.content if hasattr(block, \"text\")),\n        None,\n    )\n    return response_text, tool_metrics\n\n\nasync def evaluate_single_task(\n    client: Anthropic,\n    model: str,\n    qa_pair: dict[str, Any],\n    tools: list[dict[str, Any]],\n    connection: Any,\n    task_index: int,\n) -> dict[str, Any]:\n    \"\"\"Evaluate a single QA pair with the given tools.\"\"\"\n    start_time = time.time()\n\n    print(f\"Task {task_index + 1}: Running task with question: {qa_pair['question']}\")\n    response, tool_metrics = await agent_loop(client, model, qa_pair[\"question\"], tools, connection)\n\n    response_value = extract_xml_content(response, \"response\")\n    summary = extract_xml_content(response, \"summary\")\n    feedback = extract_xml_content(response, \"feedback\")\n\n    duration_seconds = time.time() - start_time\n\n    return {\n        \"question\": qa_pair[\"question\"],\n        \"expected\": qa_pair[\"answer\"],\n        \"actual\": response_value,\n        \"score\": int(response_value == qa_pair[\"answer\"]) if response_value else 0,\n        \"total_duration\": duration_seconds,\n        \"tool_calls\": tool_metrics,\n        \"num_tool_calls\": sum(len(metrics[\"durations\"]) for metrics in tool_metrics.values()),\n        \"summary\": summary,\n        \"feedback\": feedback,\n    }\n\n\nREPORT_HEADER = \"\"\"\n# Evaluation Report\n\n## Summary\n\n- **Accuracy**: {correct}/{total} ({accuracy:.1f}%)\n- **Average Task Duration**: {average_duration_s:.2f}s\n- **Average Tool Calls per Task**: {average_tool_calls:.2f}\n- **Total Tool Calls**: {total_tool_calls}\n\n---\n\"\"\"\n\nTASK_TEMPLATE = \"\"\"\n### Task {task_num}\n\n**Question**: {question}\n**Ground Truth Answer**: `{expected_answer}`\n**Actual Answer**: `{actual_answer}`\n**Correct**: {correct_indicator}\n**Duration**: {total_duration:.2f}s\n**Tool Calls**: {tool_calls}\n\n**Summary**\n{summary}\n\n**Feedback**\n{feedback}\n\n---\n\"\"\"\n\n\nasync def run_evaluation(\n    eval_path: Path,\n    connection: Any,\n    model: str = \"claude-3-7-sonnet-20250219\",\n) -> str:\n    \"\"\"Run evaluation with MCP server tools.\"\"\"\n    print(\"🚀 Starting Evaluation\")\n\n    client = Anthropic()\n\n    tools = await connection.list_tools()\n    print(f\"📋 Loaded {len(tools)} tools from MCP server\")\n\n    qa_pairs = parse_evaluation_file(eval_path)\n    print(f\"📋 Loaded {len(qa_pairs)} evaluation tasks\")\n\n    results = []\n    for i, qa_pair in enumerate(qa_pairs):\n        print(f\"Processing task {i + 1}/{len(qa_pairs)}\")\n        result = await evaluate_single_task(client, model, qa_pair, tools, connection, i)\n        results.append(result)\n\n    correct = sum(r[\"score\"] for r in results)\n    accuracy = (correct / len(results)) * 100 if results else 0\n    average_duration_s = sum(r[\"total_duration\"] for r in results) / len(results) if results else 0\n    average_tool_calls = sum(r[\"num_tool_calls\"] for r in results) / len(results) if results else 0\n    total_tool_calls = sum(r[\"num_tool_calls\"] for r in results)\n\n    report = REPORT_HEADER.format(\n        correct=correct,\n        total=len(results),\n        accuracy=accuracy,\n        average_duration_s=average_duration_s,\n        average_tool_calls=average_tool_calls,\n        total_tool_calls=total_tool_calls,\n    )\n\n    report += \"\".join([\n        TASK_TEMPLATE.format(\n            task_num=i + 1,\n            question=qa_pair[\"question\"],\n            expected_answer=qa_pair[\"answer\"],\n            actual_answer=result[\"actual\"] or \"N/A\",\n            correct_indicator=\"✅\" if result[\"score\"] else \"❌\",\n            total_duration=result[\"total_duration\"],\n            tool_calls=json.dumps(result[\"tool_calls\"], indent=2),\n            summary=result[\"summary\"] or \"N/A\",\n            feedback=result[\"feedback\"] or \"N/A\",\n        )\n        for i, (qa_pair, result) in enumerate(zip(qa_pairs, results))\n    ])\n\n    return report\n\n\ndef parse_headers(header_list: list[str]) -> dict[str, str]:\n    \"\"\"Parse header strings in format 'Key: Value' into a dictionary.\"\"\"\n    headers = {}\n    if not header_list:\n        return headers\n\n    for header in header_list:\n        if \":\" in header:\n            key, value = header.split(\":\", 1)\n            headers[key.strip()] = value.strip()\n        else:\n            print(f\"Warning: Ignoring malformed header: {header}\")\n    return headers\n\n\ndef parse_env_vars(env_list: list[str]) -> dict[str, str]:\n    \"\"\"Parse environment variable strings in format 'KEY=VALUE' into a dictionary.\"\"\"\n    env = {}\n    if not env_list:\n        return env\n\n    for env_var in env_list:\n        if \"=\" in env_var:\n            key, value = env_var.split(\"=\", 1)\n            env[key.strip()] = value.strip()\n        else:\n            print(f\"Warning: Ignoring malformed environment variable: {env_var}\")\n    return env\n\n\nasync def main():\n    parser = argparse.ArgumentParser(\n        description=\"Evaluate MCP servers using test questions\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  # Evaluate a local stdio MCP server\n  python evaluation.py -t stdio -c python -a my_server.py eval.xml\n\n  # Evaluate an SSE MCP server\n  python evaluation.py -t sse -u https://example.com/mcp -H \"Authorization: Bearer token\" eval.xml\n\n  # Evaluate an HTTP MCP server with custom model\n  python evaluation.py -t http -u https://example.com/mcp -m claude-3-5-sonnet-20241022 eval.xml\n        \"\"\",\n    )\n\n    parser.add_argument(\"eval_file\", type=Path, help=\"Path to evaluation XML file\")\n    parser.add_argument(\"-t\", \"--transport\", choices=[\"stdio\", \"sse\", \"http\"], default=\"stdio\", help=\"Transport type (default: stdio)\")\n    parser.add_argument(\"-m\", \"--model\", default=\"claude-3-7-sonnet-20250219\", help=\"Claude model to use (default: claude-3-7-sonnet-20250219)\")\n\n    stdio_group = parser.add_argument_group(\"stdio options\")\n    stdio_group.add_argument(\"-c\", \"--command\", help=\"Command to run MCP server (stdio only)\")\n    stdio_group.add_argument(\"-a\", \"--args\", nargs=\"+\", help=\"Arguments for the command (stdio only)\")\n    stdio_group.add_argument(\"-e\", \"--env\", nargs=\"+\", help=\"Environment variables in KEY=VALUE format (stdio only)\")\n\n    remote_group = parser.add_argument_group(\"sse/http options\")\n    remote_group.add_argument(\"-u\", \"--url\", help=\"MCP server URL (sse/http only)\")\n    remote_group.add_argument(\"-H\", \"--header\", nargs=\"+\", dest=\"headers\", help=\"HTTP headers in 'Key: Value' format (sse/http only)\")\n\n    parser.add_argument(\"-o\", \"--output\", type=Path, help=\"Output file for evaluation report (default: stdout)\")\n\n    args = parser.parse_args()\n\n    if not args.eval_file.exists():\n        print(f\"Error: Evaluation file not found: {args.eval_file}\")\n        sys.exit(1)\n\n    headers = parse_headers(args.headers) if args.headers else None\n    env_vars = parse_env_vars(args.env) if args.env else None\n\n    try:\n        connection = create_connection(\n            transport=args.transport,\n            command=args.command,\n            args=args.args,\n            env=env_vars,\n            url=args.url,\n            headers=headers,\n        )\n    except ValueError as e:\n        print(f\"Error: {e}\")\n        sys.exit(1)\n\n    print(f\"🔗 Connecting to MCP server via {args.transport}...\")\n\n    async with connection:\n        print(\"✅ Connected successfully\")\n        report = await run_evaluation(args.eval_file, connection, args.model)\n\n        if args.output:\n            args.output.write_text(report)\n            print(f\"\\n✅ Report saved to {args.output}\")\n        else:\n            print(\"\\n\" + report)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "skills/mcp-builder/scripts/example_evaluation.xml",
    "content": "<evaluation>\n   <qa_pair>\n      <question>Calculate the compound interest on $10,000 invested at 5% annual interest rate, compounded monthly for 3 years. What is the final amount in dollars (rounded to 2 decimal places)?</question>\n      <answer>11614.72</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>A projectile is launched at a 45-degree angle with an initial velocity of 50 m/s. Calculate the total distance (in meters) it has traveled from the launch point after 2 seconds, assuming g=9.8 m/s². Round to 2 decimal places.</question>\n      <answer>87.25</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>A sphere has a volume of 500 cubic meters. Calculate its surface area in square meters. Round to 2 decimal places.</question>\n      <answer>304.65</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Calculate the population standard deviation of this dataset: [12, 15, 18, 22, 25, 30, 35]. Round to 2 decimal places.</question>\n      <answer>7.61</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Calculate the pH of a solution with a hydrogen ion concentration of 3.5 × 10^-5 M. Round to 2 decimal places.</question>\n      <answer>4.46</answer>\n   </qa_pair>\n</evaluation>\n"
  },
  {
    "path": "skills/mcp-builder/scripts/requirements.txt",
    "content": "anthropic>=0.39.0\nmcp>=1.1.0\n"
  },
  {
    "path": "skills/pdf/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "skills/pdf/SKILL.md",
    "content": "---\nname: pdf\ndescription: Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting/decrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# PDF Processing Guide\n\n## Overview\n\nThis guide covers essential PDF processing operations using Python libraries and command-line tools. For advanced features, JavaScript libraries, and detailed examples, see REFERENCE.md. If you need to fill out a PDF form, read FORMS.md and follow its instructions.\n\n## Quick Start\n\n```python\nfrom pypdf import PdfReader, PdfWriter\n\n# Read a PDF\nreader = PdfReader(\"document.pdf\")\nprint(f\"Pages: {len(reader.pages)}\")\n\n# Extract text\ntext = \"\"\nfor page in reader.pages:\n    text += page.extract_text()\n```\n\n## Python Libraries\n\n### pypdf - Basic Operations\n\n#### Merge PDFs\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nwriter = PdfWriter()\nfor pdf_file in [\"doc1.pdf\", \"doc2.pdf\", \"doc3.pdf\"]:\n    reader = PdfReader(pdf_file)\n    for page in reader.pages:\n        writer.add_page(page)\n\nwith open(\"merged.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n#### Split PDF\n```python\nreader = PdfReader(\"input.pdf\")\nfor i, page in enumerate(reader.pages):\n    writer = PdfWriter()\n    writer.add_page(page)\n    with open(f\"page_{i+1}.pdf\", \"wb\") as output:\n        writer.write(output)\n```\n\n#### Extract Metadata\n```python\nreader = PdfReader(\"document.pdf\")\nmeta = reader.metadata\nprint(f\"Title: {meta.title}\")\nprint(f\"Author: {meta.author}\")\nprint(f\"Subject: {meta.subject}\")\nprint(f\"Creator: {meta.creator}\")\n```\n\n#### Rotate Pages\n```python\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\npage = reader.pages[0]\npage.rotate(90)  # Rotate 90 degrees clockwise\nwriter.add_page(page)\n\nwith open(\"rotated.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### pdfplumber - Text and Table Extraction\n\n#### Extract Text with Layout\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for page in pdf.pages:\n        text = page.extract_text()\n        print(text)\n```\n\n#### Extract Tables\n```python\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for i, page in enumerate(pdf.pages):\n        tables = page.extract_tables()\n        for j, table in enumerate(tables):\n            print(f\"Table {j+1} on page {i+1}:\")\n            for row in table:\n                print(row)\n```\n\n#### Advanced Table Extraction\n```python\nimport pandas as pd\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    all_tables = []\n    for page in pdf.pages:\n        tables = page.extract_tables()\n        for table in tables:\n            if table:  # Check if table is not empty\n                df = pd.DataFrame(table[1:], columns=table[0])\n                all_tables.append(df)\n\n# Combine all tables\nif all_tables:\n    combined_df = pd.concat(all_tables, ignore_index=True)\n    combined_df.to_excel(\"extracted_tables.xlsx\", index=False)\n```\n\n### reportlab - Create PDFs\n\n#### Basic PDF Creation\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.pdfgen import canvas\n\nc = canvas.Canvas(\"hello.pdf\", pagesize=letter)\nwidth, height = letter\n\n# Add text\nc.drawString(100, height - 100, \"Hello World!\")\nc.drawString(100, height - 120, \"This is a PDF created with reportlab\")\n\n# Add a line\nc.line(100, height - 140, 400, height - 140)\n\n# Save\nc.save()\n```\n\n#### Create PDF with Multiple Pages\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak\nfrom reportlab.lib.styles import getSampleStyleSheet\n\ndoc = SimpleDocTemplate(\"report.pdf\", pagesize=letter)\nstyles = getSampleStyleSheet()\nstory = []\n\n# Add content\ntitle = Paragraph(\"Report Title\", styles['Title'])\nstory.append(title)\nstory.append(Spacer(1, 12))\n\nbody = Paragraph(\"This is the body of the report. \" * 20, styles['Normal'])\nstory.append(body)\nstory.append(PageBreak())\n\n# Page 2\nstory.append(Paragraph(\"Page 2\", styles['Heading1']))\nstory.append(Paragraph(\"Content for page 2\", styles['Normal']))\n\n# Build PDF\ndoc.build(story)\n```\n\n#### Subscripts and Superscripts\n\n**IMPORTANT**: Never use Unicode subscript/superscript characters (₀₁₂₃₄₅₆₇₈₉, ⁰¹²³⁴⁵⁶⁷⁸⁹) in ReportLab PDFs. The built-in fonts do not include these glyphs, causing them to render as solid black boxes.\n\nInstead, use ReportLab's XML markup tags in Paragraph objects:\n```python\nfrom reportlab.platypus import Paragraph\nfrom reportlab.lib.styles import getSampleStyleSheet\n\nstyles = getSampleStyleSheet()\n\n# Subscripts: use <sub> tag\nchemical = Paragraph(\"H<sub>2</sub>O\", styles['Normal'])\n\n# Superscripts: use <super> tag\nsquared = Paragraph(\"x<super>2</super> + y<super>2</super>\", styles['Normal'])\n```\n\nFor canvas-drawn text (not Paragraph objects), manually adjust font the size and position rather than using Unicode subscripts/superscripts.\n\n## Command-Line Tools\n\n### pdftotext (poppler-utils)\n```bash\n# Extract text\npdftotext input.pdf output.txt\n\n# Extract text preserving layout\npdftotext -layout input.pdf output.txt\n\n# Extract specific pages\npdftotext -f 1 -l 5 input.pdf output.txt  # Pages 1-5\n```\n\n### qpdf\n```bash\n# Merge PDFs\nqpdf --empty --pages file1.pdf file2.pdf -- merged.pdf\n\n# Split pages\nqpdf input.pdf --pages . 1-5 -- pages1-5.pdf\nqpdf input.pdf --pages . 6-10 -- pages6-10.pdf\n\n# Rotate pages\nqpdf input.pdf output.pdf --rotate=+90:1  # Rotate page 1 by 90 degrees\n\n# Remove password\nqpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf\n```\n\n### pdftk (if available)\n```bash\n# Merge\npdftk file1.pdf file2.pdf cat output merged.pdf\n\n# Split\npdftk input.pdf burst\n\n# Rotate\npdftk input.pdf rotate 1east output rotated.pdf\n```\n\n## Common Tasks\n\n### Extract Text from Scanned PDFs\n```python\n# Requires: pip install pytesseract pdf2image\nimport pytesseract\nfrom pdf2image import convert_from_path\n\n# Convert PDF to images\nimages = convert_from_path('scanned.pdf')\n\n# OCR each page\ntext = \"\"\nfor i, image in enumerate(images):\n    text += f\"Page {i+1}:\\n\"\n    text += pytesseract.image_to_string(image)\n    text += \"\\n\\n\"\n\nprint(text)\n```\n\n### Add Watermark\n```python\nfrom pypdf import PdfReader, PdfWriter\n\n# Create watermark (or load existing)\nwatermark = PdfReader(\"watermark.pdf\").pages[0]\n\n# Apply to all pages\nreader = PdfReader(\"document.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    page.merge_page(watermark)\n    writer.add_page(page)\n\nwith open(\"watermarked.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### Extract Images\n```bash\n# Using pdfimages (poppler-utils)\npdfimages -j input.pdf output_prefix\n\n# This extracts all images as output_prefix-000.jpg, output_prefix-001.jpg, etc.\n```\n\n### Password Protection\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    writer.add_page(page)\n\n# Add password\nwriter.encrypt(\"userpassword\", \"ownerpassword\")\n\nwith open(\"encrypted.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Quick Reference\n\n| Task | Best Tool | Command/Code |\n|------|-----------|--------------|\n| Merge PDFs | pypdf | `writer.add_page(page)` |\n| Split PDFs | pypdf | One page per file |\n| Extract text | pdfplumber | `page.extract_text()` |\n| Extract tables | pdfplumber | `page.extract_tables()` |\n| Create PDFs | reportlab | Canvas or Platypus |\n| Command line merge | qpdf | `qpdf --empty --pages ...` |\n| OCR scanned PDFs | pytesseract | Convert to image first |\n| Fill PDF forms | pdf-lib or pypdf (see FORMS.md) | See FORMS.md |\n\n## Next Steps\n\n- For advanced pypdfium2 usage, see REFERENCE.md\n- For JavaScript libraries (pdf-lib), see REFERENCE.md\n- If you need to fill out a PDF form, follow the instructions in FORMS.md\n- For troubleshooting guides, see REFERENCE.md\n"
  },
  {
    "path": "skills/pdf/forms.md",
    "content": "**CRITICAL: You MUST complete these steps in order. Do not skip ahead to writing code.**\n\nIf you need to fill out a PDF form, first check to see if the PDF has fillable form fields. Run this script from this file's directory:\n `python scripts/check_fillable_fields <file.pdf>`, and depending on the result go to either the \"Fillable fields\" or \"Non-fillable fields\" and follow those instructions.\n\n# Fillable fields\nIf the PDF has fillable form fields:\n- Run this script from this file's directory: `python scripts/extract_form_field_info.py <input.pdf> <field_info.json>`. It will create a JSON file with a list of fields in this format:\n```\n[\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"rect\": ([left, bottom, right, top] bounding box in PDF coordinates, y=0 is the bottom of the page),\n    \"type\": (\"text\", \"checkbox\", \"radio_group\", or \"choice\"),\n  },\n  // Checkboxes have \"checked_value\" and \"unchecked_value\" properties:\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"checkbox\",\n    \"checked_value\": (Set the field to this value to check the checkbox),\n    \"unchecked_value\": (Set the field to this value to uncheck the checkbox),\n  },\n  // Radio groups have a \"radio_options\" list with the possible choices.\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"radio_group\",\n    \"radio_options\": [\n      {\n        \"value\": (set the field to this value to select this radio option),\n        \"rect\": (bounding box for the radio button for this option)\n      },\n      // Other radio options\n    ]\n  },\n  // Multiple choice fields have a \"choice_options\" list with the possible choices:\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"choice\",\n    \"choice_options\": [\n      {\n        \"value\": (set the field to this value to select this option),\n        \"text\": (display text of the option)\n      },\n      // Other choice options\n    ],\n  }\n]\n```\n- Convert the PDF to PNGs (one image for each page) with this script (run from this file's directory):\n`python scripts/convert_pdf_to_images.py <file.pdf> <output_directory>`\nThen analyze the images to determine the purpose of each form field (make sure to convert the bounding box PDF coordinates to image coordinates).\n- Create a `field_values.json` file in this format with the values to be entered for each field:\n```\n[\n  {\n    \"field_id\": \"last_name\", // Must match the field_id from `extract_form_field_info.py`\n    \"description\": \"The user's last name\",\n    \"page\": 1, // Must match the \"page\" value in field_info.json\n    \"value\": \"Simpson\"\n  },\n  {\n    \"field_id\": \"Checkbox12\",\n    \"description\": \"Checkbox to be checked if the user is 18 or over\",\n    \"page\": 1,\n    \"value\": \"/On\" // If this is a checkbox, use its \"checked_value\" value to check it. If it's a radio button group, use one of the \"value\" values in \"radio_options\".\n  },\n  // more fields\n]\n```\n- Run the `fill_fillable_fields.py` script from this file's directory to create a filled-in PDF:\n`python scripts/fill_fillable_fields.py <input pdf> <field_values.json> <output pdf>`\nThis script will verify that the field IDs and values you provide are valid; if it prints error messages, correct the appropriate fields and try again.\n\n# Non-fillable fields\nIf the PDF doesn't have fillable form fields, you'll add text annotations. First try to extract coordinates from the PDF structure (more accurate), then fall back to visual estimation if needed.\n\n## Step 1: Try Structure Extraction First\n\nRun this script to extract text labels, lines, and checkboxes with their exact PDF coordinates:\n`python scripts/extract_form_structure.py <input.pdf> form_structure.json`\n\nThis creates a JSON file containing:\n- **labels**: Every text element with exact coordinates (x0, top, x1, bottom in PDF points)\n- **lines**: Horizontal lines that define row boundaries\n- **checkboxes**: Small square rectangles that are checkboxes (with center coordinates)\n- **row_boundaries**: Row top/bottom positions calculated from horizontal lines\n\n**Check the results**: If `form_structure.json` has meaningful labels (text elements that correspond to form fields), use **Approach A: Structure-Based Coordinates**. If the PDF is scanned/image-based and has few or no labels, use **Approach B: Visual Estimation**.\n\n---\n\n## Approach A: Structure-Based Coordinates (Preferred)\n\nUse this when `extract_form_structure.py` found text labels in the PDF.\n\n### A.1: Analyze the Structure\n\nRead form_structure.json and identify:\n\n1. **Label groups**: Adjacent text elements that form a single label (e.g., \"Last\" + \"Name\")\n2. **Row structure**: Labels with similar `top` values are in the same row\n3. **Field columns**: Entry areas start after label ends (x0 = label.x1 + gap)\n4. **Checkboxes**: Use the checkbox coordinates directly from the structure\n\n**Coordinate system**: PDF coordinates where y=0 is at TOP of page, y increases downward.\n\n### A.2: Check for Missing Elements\n\nThe structure extraction may not detect all form elements. Common cases:\n- **Circular checkboxes**: Only square rectangles are detected as checkboxes\n- **Complex graphics**: Decorative elements or non-standard form controls\n- **Faded or light-colored elements**: May not be extracted\n\nIf you see form fields in the PDF images that aren't in form_structure.json, you'll need to use **visual analysis** for those specific fields (see \"Hybrid Approach\" below).\n\n### A.3: Create fields.json with PDF Coordinates\n\nFor each field, calculate entry coordinates from the extracted structure:\n\n**Text fields:**\n- entry x0 = label x1 + 5 (small gap after label)\n- entry x1 = next label's x0, or row boundary\n- entry top = same as label top\n- entry bottom = row boundary line below, or label bottom + row_height\n\n**Checkboxes:**\n- Use the checkbox rectangle coordinates directly from form_structure.json\n- entry_bounding_box = [checkbox.x0, checkbox.top, checkbox.x1, checkbox.bottom]\n\nCreate fields.json using `pdf_width` and `pdf_height` (signals PDF coordinates):\n```json\n{\n  \"pages\": [\n    {\"page_number\": 1, \"pdf_width\": 612, \"pdf_height\": 792}\n  ],\n  \"form_fields\": [\n    {\n      \"page_number\": 1,\n      \"description\": \"Last name entry field\",\n      \"field_label\": \"Last Name\",\n      \"label_bounding_box\": [43, 63, 87, 73],\n      \"entry_bounding_box\": [92, 63, 260, 79],\n      \"entry_text\": {\"text\": \"Smith\", \"font_size\": 10}\n    },\n    {\n      \"page_number\": 1,\n      \"description\": \"US Citizen Yes checkbox\",\n      \"field_label\": \"Yes\",\n      \"label_bounding_box\": [260, 200, 280, 210],\n      \"entry_bounding_box\": [285, 197, 292, 205],\n      \"entry_text\": {\"text\": \"X\"}\n    }\n  ]\n}\n```\n\n**Important**: Use `pdf_width`/`pdf_height` and coordinates directly from form_structure.json.\n\n### A.4: Validate Bounding Boxes\n\nBefore filling, check your bounding boxes for errors:\n`python scripts/check_bounding_boxes.py fields.json`\n\nThis checks for intersecting bounding boxes and entry boxes that are too small for the font size. Fix any reported errors before filling.\n\n---\n\n## Approach B: Visual Estimation (Fallback)\n\nUse this when the PDF is scanned/image-based and structure extraction found no usable text labels (e.g., all text shows as \"(cid:X)\" patterns).\n\n### B.1: Convert PDF to Images\n\n`python scripts/convert_pdf_to_images.py <input.pdf> <images_dir/>`\n\n### B.2: Initial Field Identification\n\nExamine each page image to identify form sections and get **rough estimates** of field locations:\n- Form field labels and their approximate positions\n- Entry areas (lines, boxes, or blank spaces for text input)\n- Checkboxes and their approximate locations\n\nFor each field, note approximate pixel coordinates (they don't need to be precise yet).\n\n### B.3: Zoom Refinement (CRITICAL for accuracy)\n\nFor each field, crop a region around the estimated position to refine coordinates precisely.\n\n**Create a zoomed crop using ImageMagick:**\n```bash\nmagick <page_image> -crop <width>x<height>+<x>+<y> +repage <crop_output.png>\n```\n\nWhere:\n- `<x>, <y>` = top-left corner of crop region (use your rough estimate minus padding)\n- `<width>, <height>` = size of crop region (field area plus ~50px padding on each side)\n\n**Example:** To refine a \"Name\" field estimated around (100, 150):\n```bash\nmagick images_dir/page_1.png -crop 300x80+50+120 +repage crops/name_field.png\n```\n\n(Note: if the `magick` command isn't available, try `convert` with the same arguments).\n\n**Examine the cropped image** to determine precise coordinates:\n1. Identify the exact pixel where the entry area begins (after the label)\n2. Identify where the entry area ends (before next field or edge)\n3. Identify the top and bottom of the entry line/box\n\n**Convert crop coordinates back to full image coordinates:**\n- full_x = crop_x + crop_offset_x\n- full_y = crop_y + crop_offset_y\n\nExample: If the crop started at (50, 120) and the entry box starts at (52, 18) within the crop:\n- entry_x0 = 52 + 50 = 102\n- entry_top = 18 + 120 = 138\n\n**Repeat for each field**, grouping nearby fields into single crops when possible.\n\n### B.4: Create fields.json with Refined Coordinates\n\nCreate fields.json using `image_width` and `image_height` (signals image coordinates):\n```json\n{\n  \"pages\": [\n    {\"page_number\": 1, \"image_width\": 1700, \"image_height\": 2200}\n  ],\n  \"form_fields\": [\n    {\n      \"page_number\": 1,\n      \"description\": \"Last name entry field\",\n      \"field_label\": \"Last Name\",\n      \"label_bounding_box\": [120, 175, 242, 198],\n      \"entry_bounding_box\": [255, 175, 720, 218],\n      \"entry_text\": {\"text\": \"Smith\", \"font_size\": 10}\n    }\n  ]\n}\n```\n\n**Important**: Use `image_width`/`image_height` and the refined pixel coordinates from the zoom analysis.\n\n### B.5: Validate Bounding Boxes\n\nBefore filling, check your bounding boxes for errors:\n`python scripts/check_bounding_boxes.py fields.json`\n\nThis checks for intersecting bounding boxes and entry boxes that are too small for the font size. Fix any reported errors before filling.\n\n---\n\n## Hybrid Approach: Structure + Visual\n\nUse this when structure extraction works for most fields but misses some elements (e.g., circular checkboxes, unusual form controls).\n\n1. **Use Approach A** for fields that were detected in form_structure.json\n2. **Convert PDF to images** for visual analysis of missing fields\n3. **Use zoom refinement** (from Approach B) for the missing fields\n4. **Combine coordinates**: For fields from structure extraction, use `pdf_width`/`pdf_height`. For visually-estimated fields, you must convert image coordinates to PDF coordinates:\n   - pdf_x = image_x * (pdf_width / image_width)\n   - pdf_y = image_y * (pdf_height / image_height)\n5. **Use a single coordinate system** in fields.json - convert all to PDF coordinates with `pdf_width`/`pdf_height`\n\n---\n\n## Step 2: Validate Before Filling\n\n**Always validate bounding boxes before filling:**\n`python scripts/check_bounding_boxes.py fields.json`\n\nThis checks for:\n- Intersecting bounding boxes (which would cause overlapping text)\n- Entry boxes that are too small for the specified font size\n\nFix any reported errors in fields.json before proceeding.\n\n## Step 3: Fill the Form\n\nThe fill script auto-detects the coordinate system and handles conversion:\n`python scripts/fill_pdf_form_with_annotations.py <input.pdf> fields.json <output.pdf>`\n\n## Step 4: Verify Output\n\nConvert the filled PDF to images and verify text placement:\n`python scripts/convert_pdf_to_images.py <output.pdf> <verify_images/>`\n\nIf text is mispositioned:\n- **Approach A**: Check that you're using PDF coordinates from form_structure.json with `pdf_width`/`pdf_height`\n- **Approach B**: Check that image dimensions match and coordinates are accurate pixels\n- **Hybrid**: Ensure coordinate conversions are correct for visually-estimated fields\n"
  },
  {
    "path": "skills/pdf/reference.md",
    "content": "# PDF Processing Advanced Reference\n\nThis document contains advanced PDF processing features, detailed examples, and additional libraries not covered in the main skill instructions.\n\n## pypdfium2 Library (Apache/BSD License)\n\n### Overview\npypdfium2 is a Python binding for PDFium (Chromium's PDF library). It's excellent for fast PDF rendering, image generation, and serves as a PyMuPDF replacement.\n\n### Render PDF to Images\n```python\nimport pypdfium2 as pdfium\nfrom PIL import Image\n\n# Load PDF\npdf = pdfium.PdfDocument(\"document.pdf\")\n\n# Render page to image\npage = pdf[0]  # First page\nbitmap = page.render(\n    scale=2.0,  # Higher resolution\n    rotation=0  # No rotation\n)\n\n# Convert to PIL Image\nimg = bitmap.to_pil()\nimg.save(\"page_1.png\", \"PNG\")\n\n# Process multiple pages\nfor i, page in enumerate(pdf):\n    bitmap = page.render(scale=1.5)\n    img = bitmap.to_pil()\n    img.save(f\"page_{i+1}.jpg\", \"JPEG\", quality=90)\n```\n\n### Extract Text with pypdfium2\n```python\nimport pypdfium2 as pdfium\n\npdf = pdfium.PdfDocument(\"document.pdf\")\nfor i, page in enumerate(pdf):\n    text = page.get_text()\n    print(f\"Page {i+1} text length: {len(text)} chars\")\n```\n\n## JavaScript Libraries\n\n### pdf-lib (MIT License)\n\npdf-lib is a powerful JavaScript library for creating and modifying PDF documents in any JavaScript environment.\n\n#### Load and Manipulate Existing PDF\n```javascript\nimport { PDFDocument } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function manipulatePDF() {\n    // Load existing PDF\n    const existingPdfBytes = fs.readFileSync('input.pdf');\n    const pdfDoc = await PDFDocument.load(existingPdfBytes);\n\n    // Get page count\n    const pageCount = pdfDoc.getPageCount();\n    console.log(`Document has ${pageCount} pages`);\n\n    // Add new page\n    const newPage = pdfDoc.addPage([600, 400]);\n    newPage.drawText('Added by pdf-lib', {\n        x: 100,\n        y: 300,\n        size: 16\n    });\n\n    // Save modified PDF\n    const pdfBytes = await pdfDoc.save();\n    fs.writeFileSync('modified.pdf', pdfBytes);\n}\n```\n\n#### Create Complex PDFs from Scratch\n```javascript\nimport { PDFDocument, rgb, StandardFonts } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function createPDF() {\n    const pdfDoc = await PDFDocument.create();\n\n    // Add fonts\n    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);\n    const helveticaBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\n\n    // Add page\n    const page = pdfDoc.addPage([595, 842]); // A4 size\n    const { width, height } = page.getSize();\n\n    // Add text with styling\n    page.drawText('Invoice #12345', {\n        x: 50,\n        y: height - 50,\n        size: 18,\n        font: helveticaBold,\n        color: rgb(0.2, 0.2, 0.8)\n    });\n\n    // Add rectangle (header background)\n    page.drawRectangle({\n        x: 40,\n        y: height - 100,\n        width: width - 80,\n        height: 30,\n        color: rgb(0.9, 0.9, 0.9)\n    });\n\n    // Add table-like content\n    const items = [\n        ['Item', 'Qty', 'Price', 'Total'],\n        ['Widget', '2', '$50', '$100'],\n        ['Gadget', '1', '$75', '$75']\n    ];\n\n    let yPos = height - 150;\n    items.forEach(row => {\n        let xPos = 50;\n        row.forEach(cell => {\n            page.drawText(cell, {\n                x: xPos,\n                y: yPos,\n                size: 12,\n                font: helveticaFont\n            });\n            xPos += 120;\n        });\n        yPos -= 25;\n    });\n\n    const pdfBytes = await pdfDoc.save();\n    fs.writeFileSync('created.pdf', pdfBytes);\n}\n```\n\n#### Advanced Merge and Split Operations\n```javascript\nimport { PDFDocument } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function mergePDFs() {\n    // Create new document\n    const mergedPdf = await PDFDocument.create();\n\n    // Load source PDFs\n    const pdf1Bytes = fs.readFileSync('doc1.pdf');\n    const pdf2Bytes = fs.readFileSync('doc2.pdf');\n\n    const pdf1 = await PDFDocument.load(pdf1Bytes);\n    const pdf2 = await PDFDocument.load(pdf2Bytes);\n\n    // Copy pages from first PDF\n    const pdf1Pages = await mergedPdf.copyPages(pdf1, pdf1.getPageIndices());\n    pdf1Pages.forEach(page => mergedPdf.addPage(page));\n\n    // Copy specific pages from second PDF (pages 0, 2, 4)\n    const pdf2Pages = await mergedPdf.copyPages(pdf2, [0, 2, 4]);\n    pdf2Pages.forEach(page => mergedPdf.addPage(page));\n\n    const mergedPdfBytes = await mergedPdf.save();\n    fs.writeFileSync('merged.pdf', mergedPdfBytes);\n}\n```\n\n### pdfjs-dist (Apache License)\n\nPDF.js is Mozilla's JavaScript library for rendering PDFs in the browser.\n\n#### Basic PDF Loading and Rendering\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\n// Configure worker (important for performance)\npdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.js';\n\nasync function renderPDF() {\n    // Load PDF\n    const loadingTask = pdfjsLib.getDocument('document.pdf');\n    const pdf = await loadingTask.promise;\n\n    console.log(`Loaded PDF with ${pdf.numPages} pages`);\n\n    // Get first page\n    const page = await pdf.getPage(1);\n    const viewport = page.getViewport({ scale: 1.5 });\n\n    // Render to canvas\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    canvas.height = viewport.height;\n    canvas.width = viewport.width;\n\n    const renderContext = {\n        canvasContext: context,\n        viewport: viewport\n    };\n\n    await page.render(renderContext).promise;\n    document.body.appendChild(canvas);\n}\n```\n\n#### Extract Text with Coordinates\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\nasync function extractText() {\n    const loadingTask = pdfjsLib.getDocument('document.pdf');\n    const pdf = await loadingTask.promise;\n\n    let fullText = '';\n\n    // Extract text from all pages\n    for (let i = 1; i <= pdf.numPages; i++) {\n        const page = await pdf.getPage(i);\n        const textContent = await page.getTextContent();\n\n        const pageText = textContent.items\n            .map(item => item.str)\n            .join(' ');\n\n        fullText += `\\n--- Page ${i} ---\\n${pageText}`;\n\n        // Get text with coordinates for advanced processing\n        const textWithCoords = textContent.items.map(item => ({\n            text: item.str,\n            x: item.transform[4],\n            y: item.transform[5],\n            width: item.width,\n            height: item.height\n        }));\n    }\n\n    console.log(fullText);\n    return fullText;\n}\n```\n\n#### Extract Annotations and Forms\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\nasync function extractAnnotations() {\n    const loadingTask = pdfjsLib.getDocument('annotated.pdf');\n    const pdf = await loadingTask.promise;\n\n    for (let i = 1; i <= pdf.numPages; i++) {\n        const page = await pdf.getPage(i);\n        const annotations = await page.getAnnotations();\n\n        annotations.forEach(annotation => {\n            console.log(`Annotation type: ${annotation.subtype}`);\n            console.log(`Content: ${annotation.contents}`);\n            console.log(`Coordinates: ${JSON.stringify(annotation.rect)}`);\n        });\n    }\n}\n```\n\n## Advanced Command-Line Operations\n\n### poppler-utils Advanced Features\n\n#### Extract Text with Bounding Box Coordinates\n```bash\n# Extract text with bounding box coordinates (essential for structured data)\npdftotext -bbox-layout document.pdf output.xml\n\n# The XML output contains precise coordinates for each text element\n```\n\n#### Advanced Image Conversion\n```bash\n# Convert to PNG images with specific resolution\npdftoppm -png -r 300 document.pdf output_prefix\n\n# Convert specific page range with high resolution\npdftoppm -png -r 600 -f 1 -l 3 document.pdf high_res_pages\n\n# Convert to JPEG with quality setting\npdftoppm -jpeg -jpegopt quality=85 -r 200 document.pdf jpeg_output\n```\n\n#### Extract Embedded Images\n```bash\n# Extract all embedded images with metadata\npdfimages -j -p document.pdf page_images\n\n# List image info without extracting\npdfimages -list document.pdf\n\n# Extract images in their original format\npdfimages -all document.pdf images/img\n```\n\n### qpdf Advanced Features\n\n#### Complex Page Manipulation\n```bash\n# Split PDF into groups of pages\nqpdf --split-pages=3 input.pdf output_group_%02d.pdf\n\n# Extract specific pages with complex ranges\nqpdf input.pdf --pages input.pdf 1,3-5,8,10-end -- extracted.pdf\n\n# Merge specific pages from multiple PDFs\nqpdf --empty --pages doc1.pdf 1-3 doc2.pdf 5-7 doc3.pdf 2,4 -- combined.pdf\n```\n\n#### PDF Optimization and Repair\n```bash\n# Optimize PDF for web (linearize for streaming)\nqpdf --linearize input.pdf optimized.pdf\n\n# Remove unused objects and compress\nqpdf --optimize-level=all input.pdf compressed.pdf\n\n# Attempt to repair corrupted PDF structure\nqpdf --check input.pdf\nqpdf --fix-qdf damaged.pdf repaired.pdf\n\n# Show detailed PDF structure for debugging\nqpdf --show-all-pages input.pdf > structure.txt\n```\n\n#### Advanced Encryption\n```bash\n# Add password protection with specific permissions\nqpdf --encrypt user_pass owner_pass 256 --print=none --modify=none -- input.pdf encrypted.pdf\n\n# Check encryption status\nqpdf --show-encryption encrypted.pdf\n\n# Remove password protection (requires password)\nqpdf --password=secret123 --decrypt encrypted.pdf decrypted.pdf\n```\n\n## Advanced Python Techniques\n\n### pdfplumber Advanced Features\n\n#### Extract Text with Precise Coordinates\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    page = pdf.pages[0]\n    \n    # Extract all text with coordinates\n    chars = page.chars\n    for char in chars[:10]:  # First 10 characters\n        print(f\"Char: '{char['text']}' at x:{char['x0']:.1f} y:{char['y0']:.1f}\")\n    \n    # Extract text by bounding box (left, top, right, bottom)\n    bbox_text = page.within_bbox((100, 100, 400, 200)).extract_text()\n```\n\n#### Advanced Table Extraction with Custom Settings\n```python\nimport pdfplumber\nimport pandas as pd\n\nwith pdfplumber.open(\"complex_table.pdf\") as pdf:\n    page = pdf.pages[0]\n    \n    # Extract tables with custom settings for complex layouts\n    table_settings = {\n        \"vertical_strategy\": \"lines\",\n        \"horizontal_strategy\": \"lines\",\n        \"snap_tolerance\": 3,\n        \"intersection_tolerance\": 15\n    }\n    tables = page.extract_tables(table_settings)\n    \n    # Visual debugging for table extraction\n    img = page.to_image(resolution=150)\n    img.save(\"debug_layout.png\")\n```\n\n### reportlab Advanced Features\n\n#### Create Professional Reports with Tables\n```python\nfrom reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph\nfrom reportlab.lib.styles import getSampleStyleSheet\nfrom reportlab.lib import colors\n\n# Sample data\ndata = [\n    ['Product', 'Q1', 'Q2', 'Q3', 'Q4'],\n    ['Widgets', '120', '135', '142', '158'],\n    ['Gadgets', '85', '92', '98', '105']\n]\n\n# Create PDF with table\ndoc = SimpleDocTemplate(\"report.pdf\")\nelements = []\n\n# Add title\nstyles = getSampleStyleSheet()\ntitle = Paragraph(\"Quarterly Sales Report\", styles['Title'])\nelements.append(title)\n\n# Add table with advanced styling\ntable = Table(data)\ntable.setStyle(TableStyle([\n    ('BACKGROUND', (0, 0), (-1, 0), colors.grey),\n    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),\n    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),\n    ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),\n    ('FONTSIZE', (0, 0), (-1, 0), 14),\n    ('BOTTOMPADDING', (0, 0), (-1, 0), 12),\n    ('BACKGROUND', (0, 1), (-1, -1), colors.beige),\n    ('GRID', (0, 0), (-1, -1), 1, colors.black)\n]))\nelements.append(table)\n\ndoc.build(elements)\n```\n\n## Complex Workflows\n\n### Extract Figures/Images from PDF\n\n#### Method 1: Using pdfimages (fastest)\n```bash\n# Extract all images with original quality\npdfimages -all document.pdf images/img\n```\n\n#### Method 2: Using pypdfium2 + Image Processing\n```python\nimport pypdfium2 as pdfium\nfrom PIL import Image\nimport numpy as np\n\ndef extract_figures(pdf_path, output_dir):\n    pdf = pdfium.PdfDocument(pdf_path)\n    \n    for page_num, page in enumerate(pdf):\n        # Render high-resolution page\n        bitmap = page.render(scale=3.0)\n        img = bitmap.to_pil()\n        \n        # Convert to numpy for processing\n        img_array = np.array(img)\n        \n        # Simple figure detection (non-white regions)\n        mask = np.any(img_array != [255, 255, 255], axis=2)\n        \n        # Find contours and extract bounding boxes\n        # (This is simplified - real implementation would need more sophisticated detection)\n        \n        # Save detected figures\n        # ... implementation depends on specific needs\n```\n\n### Batch PDF Processing with Error Handling\n```python\nimport os\nimport glob\nfrom pypdf import PdfReader, PdfWriter\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\ndef batch_process_pdfs(input_dir, operation='merge'):\n    pdf_files = glob.glob(os.path.join(input_dir, \"*.pdf\"))\n    \n    if operation == 'merge':\n        writer = PdfWriter()\n        for pdf_file in pdf_files:\n            try:\n                reader = PdfReader(pdf_file)\n                for page in reader.pages:\n                    writer.add_page(page)\n                logger.info(f\"Processed: {pdf_file}\")\n            except Exception as e:\n                logger.error(f\"Failed to process {pdf_file}: {e}\")\n                continue\n        \n        with open(\"batch_merged.pdf\", \"wb\") as output:\n            writer.write(output)\n    \n    elif operation == 'extract_text':\n        for pdf_file in pdf_files:\n            try:\n                reader = PdfReader(pdf_file)\n                text = \"\"\n                for page in reader.pages:\n                    text += page.extract_text()\n                \n                output_file = pdf_file.replace('.pdf', '.txt')\n                with open(output_file, 'w', encoding='utf-8') as f:\n                    f.write(text)\n                logger.info(f\"Extracted text from: {pdf_file}\")\n                \n            except Exception as e:\n                logger.error(f\"Failed to extract text from {pdf_file}: {e}\")\n                continue\n```\n\n### Advanced PDF Cropping\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\n# Crop page (left, bottom, right, top in points)\npage = reader.pages[0]\npage.mediabox.left = 50\npage.mediabox.bottom = 50\npage.mediabox.right = 550\npage.mediabox.top = 750\n\nwriter.add_page(page)\nwith open(\"cropped.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Performance Optimization Tips\n\n### 1. For Large PDFs\n- Use streaming approaches instead of loading entire PDF in memory\n- Use `qpdf --split-pages` for splitting large files\n- Process pages individually with pypdfium2\n\n### 2. For Text Extraction\n- `pdftotext -bbox-layout` is fastest for plain text extraction\n- Use pdfplumber for structured data and tables\n- Avoid `pypdf.extract_text()` for very large documents\n\n### 3. For Image Extraction\n- `pdfimages` is much faster than rendering pages\n- Use low resolution for previews, high resolution for final output\n\n### 4. For Form Filling\n- pdf-lib maintains form structure better than most alternatives\n- Pre-validate form fields before processing\n\n### 5. Memory Management\n```python\n# Process PDFs in chunks\ndef process_large_pdf(pdf_path, chunk_size=10):\n    reader = PdfReader(pdf_path)\n    total_pages = len(reader.pages)\n    \n    for start_idx in range(0, total_pages, chunk_size):\n        end_idx = min(start_idx + chunk_size, total_pages)\n        writer = PdfWriter()\n        \n        for i in range(start_idx, end_idx):\n            writer.add_page(reader.pages[i])\n        \n        # Process chunk\n        with open(f\"chunk_{start_idx//chunk_size}.pdf\", \"wb\") as output:\n            writer.write(output)\n```\n\n## Troubleshooting Common Issues\n\n### Encrypted PDFs\n```python\n# Handle password-protected PDFs\nfrom pypdf import PdfReader\n\ntry:\n    reader = PdfReader(\"encrypted.pdf\")\n    if reader.is_encrypted:\n        reader.decrypt(\"password\")\nexcept Exception as e:\n    print(f\"Failed to decrypt: {e}\")\n```\n\n### Corrupted PDFs\n```bash\n# Use qpdf to repair\nqpdf --check corrupted.pdf\nqpdf --replace-input corrupted.pdf\n```\n\n### Text Extraction Issues\n```python\n# Fallback to OCR for scanned PDFs\nimport pytesseract\nfrom pdf2image import convert_from_path\n\ndef extract_text_with_ocr(pdf_path):\n    images = convert_from_path(pdf_path)\n    text = \"\"\n    for i, image in enumerate(images):\n        text += pytesseract.image_to_string(image)\n    return text\n```\n\n## License Information\n\n- **pypdf**: BSD License\n- **pdfplumber**: MIT License\n- **pypdfium2**: Apache/BSD License\n- **reportlab**: BSD License\n- **poppler-utils**: GPL-2 License\n- **qpdf**: Apache License\n- **pdf-lib**: MIT License\n- **pdfjs-dist**: Apache License"
  },
  {
    "path": "skills/pdf/scripts/check_bounding_boxes.py",
    "content": "from dataclasses import dataclass\nimport json\nimport sys\n\n\n\n\n@dataclass\nclass RectAndField:\n    rect: list[float]\n    rect_type: str\n    field: dict\n\n\ndef get_bounding_box_messages(fields_json_stream) -> list[str]:\n    messages = []\n    fields = json.load(fields_json_stream)\n    messages.append(f\"Read {len(fields['form_fields'])} fields\")\n\n    def rects_intersect(r1, r2):\n        disjoint_horizontal = r1[0] >= r2[2] or r1[2] <= r2[0]\n        disjoint_vertical = r1[1] >= r2[3] or r1[3] <= r2[1]\n        return not (disjoint_horizontal or disjoint_vertical)\n\n    rects_and_fields = []\n    for f in fields[\"form_fields\"]:\n        rects_and_fields.append(RectAndField(f[\"label_bounding_box\"], \"label\", f))\n        rects_and_fields.append(RectAndField(f[\"entry_bounding_box\"], \"entry\", f))\n\n    has_error = False\n    for i, ri in enumerate(rects_and_fields):\n        for j in range(i + 1, len(rects_and_fields)):\n            rj = rects_and_fields[j]\n            if ri.field[\"page_number\"] == rj.field[\"page_number\"] and rects_intersect(ri.rect, rj.rect):\n                has_error = True\n                if ri.field is rj.field:\n                    messages.append(f\"FAILURE: intersection between label and entry bounding boxes for `{ri.field['description']}` ({ri.rect}, {rj.rect})\")\n                else:\n                    messages.append(f\"FAILURE: intersection between {ri.rect_type} bounding box for `{ri.field['description']}` ({ri.rect}) and {rj.rect_type} bounding box for `{rj.field['description']}` ({rj.rect})\")\n                if len(messages) >= 20:\n                    messages.append(\"Aborting further checks; fix bounding boxes and try again\")\n                    return messages\n        if ri.rect_type == \"entry\":\n            if \"entry_text\" in ri.field:\n                font_size = ri.field[\"entry_text\"].get(\"font_size\", 14)\n                entry_height = ri.rect[3] - ri.rect[1]\n                if entry_height < font_size:\n                    has_error = True\n                    messages.append(f\"FAILURE: entry bounding box height ({entry_height}) for `{ri.field['description']}` is too short for the text content (font size: {font_size}). Increase the box height or decrease the font size.\")\n                    if len(messages) >= 20:\n                        messages.append(\"Aborting further checks; fix bounding boxes and try again\")\n                        return messages\n\n    if not has_error:\n        messages.append(\"SUCCESS: All bounding boxes are valid\")\n    return messages\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        print(\"Usage: check_bounding_boxes.py [fields.json]\")\n        sys.exit(1)\n    with open(sys.argv[1]) as f:\n        messages = get_bounding_box_messages(f)\n    for msg in messages:\n        print(msg)\n"
  },
  {
    "path": "skills/pdf/scripts/check_fillable_fields.py",
    "content": "import sys\nfrom pypdf import PdfReader\n\n\n\n\nreader = PdfReader(sys.argv[1])\nif (reader.get_fields()):\n    print(\"This PDF has fillable form fields\")\nelse:\n    print(\"This PDF does not have fillable form fields; you will need to visually determine where to enter data\")\n"
  },
  {
    "path": "skills/pdf/scripts/convert_pdf_to_images.py",
    "content": "import os\nimport sys\n\nfrom pdf2image import convert_from_path\n\n\n\n\ndef convert(pdf_path, output_dir, max_dim=1000):\n    images = convert_from_path(pdf_path, dpi=200)\n\n    for i, image in enumerate(images):\n        width, height = image.size\n        if width > max_dim or height > max_dim:\n            scale_factor = min(max_dim / width, max_dim / height)\n            new_width = int(width * scale_factor)\n            new_height = int(height * scale_factor)\n            image = image.resize((new_width, new_height))\n        \n        image_path = os.path.join(output_dir, f\"page_{i+1}.png\")\n        image.save(image_path)\n        print(f\"Saved page {i+1} as {image_path} (size: {image.size})\")\n\n    print(f\"Converted {len(images)} pages to PNG images\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 3:\n        print(\"Usage: convert_pdf_to_images.py [input pdf] [output directory]\")\n        sys.exit(1)\n    pdf_path = sys.argv[1]\n    output_directory = sys.argv[2]\n    convert(pdf_path, output_directory)\n"
  },
  {
    "path": "skills/pdf/scripts/create_validation_image.py",
    "content": "import json\nimport sys\n\nfrom PIL import Image, ImageDraw\n\n\n\n\ndef create_validation_image(page_number, fields_json_path, input_path, output_path):\n    with open(fields_json_path, 'r') as f:\n        data = json.load(f)\n\n        img = Image.open(input_path)\n        draw = ImageDraw.Draw(img)\n        num_boxes = 0\n        \n        for field in data[\"form_fields\"]:\n            if field[\"page_number\"] == page_number:\n                entry_box = field['entry_bounding_box']\n                label_box = field['label_bounding_box']\n                draw.rectangle(entry_box, outline='red', width=2)\n                draw.rectangle(label_box, outline='blue', width=2)\n                num_boxes += 2\n        \n        img.save(output_path)\n        print(f\"Created validation image at {output_path} with {num_boxes} bounding boxes\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 5:\n        print(\"Usage: create_validation_image.py [page number] [fields.json file] [input image path] [output image path]\")\n        sys.exit(1)\n    page_number = int(sys.argv[1])\n    fields_json_path = sys.argv[2]\n    input_image_path = sys.argv[3]\n    output_image_path = sys.argv[4]\n    create_validation_image(page_number, fields_json_path, input_image_path, output_image_path)\n"
  },
  {
    "path": "skills/pdf/scripts/extract_form_field_info.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader\n\n\n\n\ndef get_full_annotation_field_id(annotation):\n    components = []\n    while annotation:\n        field_name = annotation.get('/T')\n        if field_name:\n            components.append(field_name)\n        annotation = annotation.get('/Parent')\n    return \".\".join(reversed(components)) if components else None\n\n\ndef make_field_dict(field, field_id):\n    field_dict = {\"field_id\": field_id}\n    ft = field.get('/FT')\n    if ft == \"/Tx\":\n        field_dict[\"type\"] = \"text\"\n    elif ft == \"/Btn\":\n        field_dict[\"type\"] = \"checkbox\"  \n        states = field.get(\"/_States_\", [])\n        if len(states) == 2:\n            if \"/Off\" in states:\n                field_dict[\"checked_value\"] = states[0] if states[0] != \"/Off\" else states[1]\n                field_dict[\"unchecked_value\"] = \"/Off\"\n            else:\n                print(f\"Unexpected state values for checkbox `${field_id}`. Its checked and unchecked values may not be correct; if you're trying to check it, visually verify the results.\")\n                field_dict[\"checked_value\"] = states[0]\n                field_dict[\"unchecked_value\"] = states[1]\n    elif ft == \"/Ch\":\n        field_dict[\"type\"] = \"choice\"\n        states = field.get(\"/_States_\", [])\n        field_dict[\"choice_options\"] = [{\n            \"value\": state[0],\n            \"text\": state[1],\n        } for state in states]\n    else:\n        field_dict[\"type\"] = f\"unknown ({ft})\"\n    return field_dict\n\n\ndef get_field_info(reader: PdfReader):\n    fields = reader.get_fields()\n\n    field_info_by_id = {}\n    possible_radio_names = set()\n\n    for field_id, field in fields.items():\n        if field.get(\"/Kids\"):\n            if field.get(\"/FT\") == \"/Btn\":\n                possible_radio_names.add(field_id)\n            continue\n        field_info_by_id[field_id] = make_field_dict(field, field_id)\n\n\n    radio_fields_by_id = {}\n\n    for page_index, page in enumerate(reader.pages):\n        annotations = page.get('/Annots', [])\n        for ann in annotations:\n            field_id = get_full_annotation_field_id(ann)\n            if field_id in field_info_by_id:\n                field_info_by_id[field_id][\"page\"] = page_index + 1\n                field_info_by_id[field_id][\"rect\"] = ann.get('/Rect')\n            elif field_id in possible_radio_names:\n                try:\n                    on_values = [v for v in ann[\"/AP\"][\"/N\"] if v != \"/Off\"]\n                except KeyError:\n                    continue\n                if len(on_values) == 1:\n                    rect = ann.get(\"/Rect\")\n                    if field_id not in radio_fields_by_id:\n                        radio_fields_by_id[field_id] = {\n                            \"field_id\": field_id,\n                            \"type\": \"radio_group\",\n                            \"page\": page_index + 1,\n                            \"radio_options\": [],\n                        }\n                    radio_fields_by_id[field_id][\"radio_options\"].append({\n                        \"value\": on_values[0],\n                        \"rect\": rect,\n                    })\n\n    fields_with_location = []\n    for field_info in field_info_by_id.values():\n        if \"page\" in field_info:\n            fields_with_location.append(field_info)\n        else:\n            print(f\"Unable to determine location for field id: {field_info.get('field_id')}, ignoring\")\n\n    def sort_key(f):\n        if \"radio_options\" in f:\n            rect = f[\"radio_options\"][0][\"rect\"] or [0, 0, 0, 0]\n        else:\n            rect = f.get(\"rect\") or [0, 0, 0, 0]\n        adjusted_position = [-rect[1], rect[0]]\n        return [f.get(\"page\"), adjusted_position]\n    \n    sorted_fields = fields_with_location + list(radio_fields_by_id.values())\n    sorted_fields.sort(key=sort_key)\n\n    return sorted_fields\n\n\ndef write_field_info(pdf_path: str, json_output_path: str):\n    reader = PdfReader(pdf_path)\n    field_info = get_field_info(reader)\n    with open(json_output_path, \"w\") as f:\n        json.dump(field_info, f, indent=2)\n    print(f\"Wrote {len(field_info)} fields to {json_output_path}\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 3:\n        print(\"Usage: extract_form_field_info.py [input pdf] [output json]\")\n        sys.exit(1)\n    write_field_info(sys.argv[1], sys.argv[2])\n"
  },
  {
    "path": "skills/pdf/scripts/extract_form_structure.py",
    "content": "\"\"\"\nExtract form structure from a non-fillable PDF.\n\nThis script analyzes the PDF to find:\n- Text labels with their exact coordinates\n- Horizontal lines (row boundaries)\n- Checkboxes (small rectangles)\n\nOutput: A JSON file with the form structure that can be used to generate\naccurate field coordinates for filling.\n\nUsage: python extract_form_structure.py <input.pdf> <output.json>\n\"\"\"\n\nimport json\nimport sys\nimport pdfplumber\n\n\ndef extract_form_structure(pdf_path):\n    structure = {\n        \"pages\": [],\n        \"labels\": [],\n        \"lines\": [],\n        \"checkboxes\": [],\n        \"row_boundaries\": []\n    }\n\n    with pdfplumber.open(pdf_path) as pdf:\n        for page_num, page in enumerate(pdf.pages, 1):\n            structure[\"pages\"].append({\n                \"page_number\": page_num,\n                \"width\": float(page.width),\n                \"height\": float(page.height)\n            })\n\n            words = page.extract_words()\n            for word in words:\n                structure[\"labels\"].append({\n                    \"page\": page_num,\n                    \"text\": word[\"text\"],\n                    \"x0\": round(float(word[\"x0\"]), 1),\n                    \"top\": round(float(word[\"top\"]), 1),\n                    \"x1\": round(float(word[\"x1\"]), 1),\n                    \"bottom\": round(float(word[\"bottom\"]), 1)\n                })\n\n            for line in page.lines:\n                if abs(float(line[\"x1\"]) - float(line[\"x0\"])) > page.width * 0.5:\n                    structure[\"lines\"].append({\n                        \"page\": page_num,\n                        \"y\": round(float(line[\"top\"]), 1),\n                        \"x0\": round(float(line[\"x0\"]), 1),\n                        \"x1\": round(float(line[\"x1\"]), 1)\n                    })\n\n            for rect in page.rects:\n                width = float(rect[\"x1\"]) - float(rect[\"x0\"])\n                height = float(rect[\"bottom\"]) - float(rect[\"top\"])\n                if 5 <= width <= 15 and 5 <= height <= 15 and abs(width - height) < 2:\n                    structure[\"checkboxes\"].append({\n                        \"page\": page_num,\n                        \"x0\": round(float(rect[\"x0\"]), 1),\n                        \"top\": round(float(rect[\"top\"]), 1),\n                        \"x1\": round(float(rect[\"x1\"]), 1),\n                        \"bottom\": round(float(rect[\"bottom\"]), 1),\n                        \"center_x\": round((float(rect[\"x0\"]) + float(rect[\"x1\"])) / 2, 1),\n                        \"center_y\": round((float(rect[\"top\"]) + float(rect[\"bottom\"])) / 2, 1)\n                    })\n\n    lines_by_page = {}\n    for line in structure[\"lines\"]:\n        page = line[\"page\"]\n        if page not in lines_by_page:\n            lines_by_page[page] = []\n        lines_by_page[page].append(line[\"y\"])\n\n    for page, y_coords in lines_by_page.items():\n        y_coords = sorted(set(y_coords))\n        for i in range(len(y_coords) - 1):\n            structure[\"row_boundaries\"].append({\n                \"page\": page,\n                \"row_top\": y_coords[i],\n                \"row_bottom\": y_coords[i + 1],\n                \"row_height\": round(y_coords[i + 1] - y_coords[i], 1)\n            })\n\n    return structure\n\n\ndef main():\n    if len(sys.argv) != 3:\n        print(\"Usage: extract_form_structure.py <input.pdf> <output.json>\")\n        sys.exit(1)\n\n    pdf_path = sys.argv[1]\n    output_path = sys.argv[2]\n\n    print(f\"Extracting structure from {pdf_path}...\")\n    structure = extract_form_structure(pdf_path)\n\n    with open(output_path, \"w\") as f:\n        json.dump(structure, f, indent=2)\n\n    print(f\"Found:\")\n    print(f\"  - {len(structure['pages'])} pages\")\n    print(f\"  - {len(structure['labels'])} text labels\")\n    print(f\"  - {len(structure['lines'])} horizontal lines\")\n    print(f\"  - {len(structure['checkboxes'])} checkboxes\")\n    print(f\"  - {len(structure['row_boundaries'])} row boundaries\")\n    print(f\"Saved to {output_path}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/pdf/scripts/fill_fillable_fields.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader, PdfWriter\n\nfrom extract_form_field_info import get_field_info\n\n\n\n\ndef fill_pdf_fields(input_pdf_path: str, fields_json_path: str, output_pdf_path: str):\n    with open(fields_json_path) as f:\n        fields = json.load(f)\n    fields_by_page = {}\n    for field in fields:\n        if \"value\" in field:\n            field_id = field[\"field_id\"]\n            page = field[\"page\"]\n            if page not in fields_by_page:\n                fields_by_page[page] = {}\n            fields_by_page[page][field_id] = field[\"value\"]\n    \n    reader = PdfReader(input_pdf_path)\n\n    has_error = False\n    field_info = get_field_info(reader)\n    fields_by_ids = {f[\"field_id\"]: f for f in field_info}\n    for field in fields:\n        existing_field = fields_by_ids.get(field[\"field_id\"])\n        if not existing_field:\n            has_error = True\n            print(f\"ERROR: `{field['field_id']}` is not a valid field ID\")\n        elif field[\"page\"] != existing_field[\"page\"]:\n            has_error = True\n            print(f\"ERROR: Incorrect page number for `{field['field_id']}` (got {field['page']}, expected {existing_field['page']})\")\n        else:\n            if \"value\" in field:\n                err = validation_error_for_field_value(existing_field, field[\"value\"])\n                if err:\n                    print(err)\n                    has_error = True\n    if has_error:\n        sys.exit(1)\n\n    writer = PdfWriter(clone_from=reader)\n    for page, field_values in fields_by_page.items():\n        writer.update_page_form_field_values(writer.pages[page - 1], field_values, auto_regenerate=False)\n\n    writer.set_need_appearances_writer(True)\n    \n    with open(output_pdf_path, \"wb\") as f:\n        writer.write(f)\n\n\ndef validation_error_for_field_value(field_info, field_value):\n    field_type = field_info[\"type\"]\n    field_id = field_info[\"field_id\"]\n    if field_type == \"checkbox\":\n        checked_val = field_info[\"checked_value\"]\n        unchecked_val = field_info[\"unchecked_value\"]\n        if field_value != checked_val and field_value != unchecked_val:\n            return f'ERROR: Invalid value \"{field_value}\" for checkbox field \"{field_id}\". The checked value is \"{checked_val}\" and the unchecked value is \"{unchecked_val}\"'\n    elif field_type == \"radio_group\":\n        option_values = [opt[\"value\"] for opt in field_info[\"radio_options\"]]\n        if field_value not in option_values:\n            return f'ERROR: Invalid value \"{field_value}\" for radio group field \"{field_id}\". Valid values are: {option_values}' \n    elif field_type == \"choice\":\n        choice_values = [opt[\"value\"] for opt in field_info[\"choice_options\"]]\n        if field_value not in choice_values:\n            return f'ERROR: Invalid value \"{field_value}\" for choice field \"{field_id}\". Valid values are: {choice_values}'\n    return None\n\n\ndef monkeypatch_pydpf_method():\n    from pypdf.generic import DictionaryObject\n    from pypdf.constants import FieldDictionaryAttributes\n\n    original_get_inherited = DictionaryObject.get_inherited\n\n    def patched_get_inherited(self, key: str, default = None):\n        result = original_get_inherited(self, key, default)\n        if key == FieldDictionaryAttributes.Opt:\n            if isinstance(result, list) and all(isinstance(v, list) and len(v) == 2 for v in result):\n                result = [r[0] for r in result]\n        return result\n\n    DictionaryObject.get_inherited = patched_get_inherited\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 4:\n        print(\"Usage: fill_fillable_fields.py [input pdf] [field_values.json] [output pdf]\")\n        sys.exit(1)\n    monkeypatch_pydpf_method()\n    input_pdf = sys.argv[1]\n    fields_json = sys.argv[2]\n    output_pdf = sys.argv[3]\n    fill_pdf_fields(input_pdf, fields_json, output_pdf)\n"
  },
  {
    "path": "skills/pdf/scripts/fill_pdf_form_with_annotations.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader, PdfWriter\nfrom pypdf.annotations import FreeText\n\n\n\n\ndef transform_from_image_coords(bbox, image_width, image_height, pdf_width, pdf_height):\n    x_scale = pdf_width / image_width\n    y_scale = pdf_height / image_height\n\n    left = bbox[0] * x_scale\n    right = bbox[2] * x_scale\n\n    top = pdf_height - (bbox[1] * y_scale)\n    bottom = pdf_height - (bbox[3] * y_scale)\n\n    return left, bottom, right, top\n\n\ndef transform_from_pdf_coords(bbox, pdf_height):\n    left = bbox[0]\n    right = bbox[2]\n\n    pypdf_top = pdf_height - bbox[1]      \n    pypdf_bottom = pdf_height - bbox[3]   \n\n    return left, pypdf_bottom, right, pypdf_top\n\n\ndef fill_pdf_form(input_pdf_path, fields_json_path, output_pdf_path):\n    \n    with open(fields_json_path, \"r\") as f:\n        fields_data = json.load(f)\n    \n    reader = PdfReader(input_pdf_path)\n    writer = PdfWriter()\n    \n    writer.append(reader)\n    \n    pdf_dimensions = {}\n    for i, page in enumerate(reader.pages):\n        mediabox = page.mediabox\n        pdf_dimensions[i + 1] = [mediabox.width, mediabox.height]\n    \n    annotations = []\n    for field in fields_data[\"form_fields\"]:\n        page_num = field[\"page_number\"]\n\n        page_info = next(p for p in fields_data[\"pages\"] if p[\"page_number\"] == page_num)\n        pdf_width, pdf_height = pdf_dimensions[page_num]\n\n        if \"pdf_width\" in page_info:\n            transformed_entry_box = transform_from_pdf_coords(\n                field[\"entry_bounding_box\"],\n                float(pdf_height)\n            )\n        else:\n            image_width = page_info[\"image_width\"]\n            image_height = page_info[\"image_height\"]\n            transformed_entry_box = transform_from_image_coords(\n                field[\"entry_bounding_box\"],\n                image_width, image_height,\n                float(pdf_width), float(pdf_height)\n            )\n        \n        if \"entry_text\" not in field or \"text\" not in field[\"entry_text\"]:\n            continue\n        entry_text = field[\"entry_text\"]\n        text = entry_text[\"text\"]\n        if not text:\n            continue\n        \n        font_name = entry_text.get(\"font\", \"Arial\")\n        font_size = str(entry_text.get(\"font_size\", 14)) + \"pt\"\n        font_color = entry_text.get(\"font_color\", \"000000\")\n\n        annotation = FreeText(\n            text=text,\n            rect=transformed_entry_box,\n            font=font_name,\n            font_size=font_size,\n            font_color=font_color,\n            border_color=None,\n            background_color=None,\n        )\n        annotations.append(annotation)\n        writer.add_annotation(page_number=page_num - 1, annotation=annotation)\n        \n    with open(output_pdf_path, \"wb\") as output:\n        writer.write(output)\n    \n    print(f\"Successfully filled PDF form and saved to {output_pdf_path}\")\n    print(f\"Added {len(annotations)} text annotations\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 4:\n        print(\"Usage: fill_pdf_form_with_annotations.py [input pdf] [fields.json] [output pdf]\")\n        sys.exit(1)\n    input_pdf = sys.argv[1]\n    fields_json = sys.argv[2]\n    output_pdf = sys.argv[3]\n    \n    fill_pdf_form(input_pdf, fields_json, output_pdf)\n"
  },
  {
    "path": "skills/pptx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "skills/pptx/SKILL.md",
    "content": "---\nname: pptx\ndescription: \"Use this skill any time a .pptx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx file (even if the extracted content will be used elsewhere, like in an email or summary); editing, modifying, or updating existing presentations; combining or splitting slide files; working with templates, layouts, speaker notes, or comments. Trigger whenever the user mentions \\\"deck,\\\" \\\"slides,\\\" \\\"presentation,\\\" or references a .pptx filename, regardless of what they plan to do with the content afterward. If a .pptx file needs to be opened, created, or touched, use this skill.\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# PPTX Skill\n\n## Quick Reference\n\n| Task | Guide |\n|------|-------|\n| Read/analyze content | `python -m markitdown presentation.pptx` |\n| Edit or create from template | Read [editing.md](editing.md) |\n| Create from scratch | Read [pptxgenjs.md](pptxgenjs.md) |\n\n---\n\n## Reading Content\n\n```bash\n# Text extraction\npython -m markitdown presentation.pptx\n\n# Visual overview\npython scripts/thumbnail.py presentation.pptx\n\n# Raw XML\npython scripts/office/unpack.py presentation.pptx unpacked/\n```\n\n---\n\n## Editing Workflow\n\n**Read [editing.md](editing.md) for full details.**\n\n1. Analyze template with `thumbnail.py`\n2. Unpack → manipulate slides → edit content → clean → pack\n\n---\n\n## Creating from Scratch\n\n**Read [pptxgenjs.md](pptxgenjs.md) for full details.**\n\nUse when no template or reference presentation is available.\n\n---\n\n## Design Ideas\n\n**Don't create boring slides.** Plain bullets on a white background won't impress anyone. Consider ideas from this list for each slide.\n\n### Before Starting\n\n- **Pick a bold, content-informed color palette**: The palette should feel designed for THIS topic. If swapping your colors into a completely different presentation would still \"work,\" you haven't made specific enough choices.\n- **Dominance over equality**: One color should dominate (60-70% visual weight), with 1-2 supporting tones and one sharp accent. Never give all colors equal weight.\n- **Dark/light contrast**: Dark backgrounds for title + conclusion slides, light for content (\"sandwich\" structure). Or commit to dark throughout for a premium feel.\n- **Commit to a visual motif**: Pick ONE distinctive element and repeat it — rounded image frames, icons in colored circles, thick single-side borders. Carry it across every slide.\n\n### Color Palettes\n\nChoose colors that match your topic — don't default to generic blue. Use these palettes as inspiration:\n\n| Theme | Primary | Secondary | Accent |\n|-------|---------|-----------|--------|\n| **Midnight Executive** | `1E2761` (navy) | `CADCFC` (ice blue) | `FFFFFF` (white) |\n| **Forest & Moss** | `2C5F2D` (forest) | `97BC62` (moss) | `F5F5F5` (cream) |\n| **Coral Energy** | `F96167` (coral) | `F9E795` (gold) | `2F3C7E` (navy) |\n| **Warm Terracotta** | `B85042` (terracotta) | `E7E8D1` (sand) | `A7BEAE` (sage) |\n| **Ocean Gradient** | `065A82` (deep blue) | `1C7293` (teal) | `21295C` (midnight) |\n| **Charcoal Minimal** | `36454F` (charcoal) | `F2F2F2` (off-white) | `212121` (black) |\n| **Teal Trust** | `028090` (teal) | `00A896` (seafoam) | `02C39A` (mint) |\n| **Berry & Cream** | `6D2E46` (berry) | `A26769` (dusty rose) | `ECE2D0` (cream) |\n| **Sage Calm** | `84B59F` (sage) | `69A297` (eucalyptus) | `50808E` (slate) |\n| **Cherry Bold** | `990011` (cherry) | `FCF6F5` (off-white) | `2F3C7E` (navy) |\n\n### For Each Slide\n\n**Every slide needs a visual element** — image, chart, icon, or shape. Text-only slides are forgettable.\n\n**Layout options:**\n- Two-column (text left, illustration on right)\n- Icon + text rows (icon in colored circle, bold header, description below)\n- 2x2 or 2x3 grid (image on one side, grid of content blocks on other)\n- Half-bleed image (full left or right side) with content overlay\n\n**Data display:**\n- Large stat callouts (big numbers 60-72pt with small labels below)\n- Comparison columns (before/after, pros/cons, side-by-side options)\n- Timeline or process flow (numbered steps, arrows)\n\n**Visual polish:**\n- Icons in small colored circles next to section headers\n- Italic accent text for key stats or taglines\n\n### Typography\n\n**Choose an interesting font pairing** — don't default to Arial. Pick a header font with personality and pair it with a clean body font.\n\n| Header Font | Body Font |\n|-------------|-----------|\n| Georgia | Calibri |\n| Arial Black | Arial |\n| Calibri | Calibri Light |\n| Cambria | Calibri |\n| Trebuchet MS | Calibri |\n| Impact | Arial |\n| Palatino | Garamond |\n| Consolas | Calibri |\n\n| Element | Size |\n|---------|------|\n| Slide title | 36-44pt bold |\n| Section header | 20-24pt bold |\n| Body text | 14-16pt |\n| Captions | 10-12pt muted |\n\n### Spacing\n\n- 0.5\" minimum margins\n- 0.3-0.5\" between content blocks\n- Leave breathing room—don't fill every inch\n\n### Avoid (Common Mistakes)\n\n- **Don't repeat the same layout** — vary columns, cards, and callouts across slides\n- **Don't center body text** — left-align paragraphs and lists; center only titles\n- **Don't skimp on size contrast** — titles need 36pt+ to stand out from 14-16pt body\n- **Don't default to blue** — pick colors that reflect the specific topic\n- **Don't mix spacing randomly** — choose 0.3\" or 0.5\" gaps and use consistently\n- **Don't style one slide and leave the rest plain** — commit fully or keep it simple throughout\n- **Don't create text-only slides** — add images, icons, charts, or visual elements; avoid plain title + bullets\n- **Don't forget text box padding** — when aligning lines or shapes with text edges, set `margin: 0` on the text box or offset the shape to account for padding\n- **Don't use low-contrast elements** — icons AND text need strong contrast against the background; avoid light text on light backgrounds or dark text on dark backgrounds\n- **NEVER use accent lines under titles** — these are a hallmark of AI-generated slides; use whitespace or background color instead\n\n---\n\n## QA (Required)\n\n**Assume there are problems. Your job is to find them.**\n\nYour first render is almost never correct. Approach QA as a bug hunt, not a confirmation step. If you found zero issues on first inspection, you weren't looking hard enough.\n\n### Content QA\n\n```bash\npython -m markitdown output.pptx\n```\n\nCheck for missing content, typos, wrong order.\n\n**When using templates, check for leftover placeholder text:**\n\n```bash\npython -m markitdown output.pptx | grep -iE \"xxxx|lorem|ipsum|this.*(page|slide).*layout\"\n```\n\nIf grep returns results, fix them before declaring success.\n\n### Visual QA\n\n**⚠️ USE SUBAGENTS** — even for 2-3 slides. You've been staring at the code and will see what you expect, not what's there. Subagents have fresh eyes.\n\nConvert slides to images (see [Converting to Images](#converting-to-images)), then use this prompt:\n\n```\nVisually inspect these slides. Assume there are issues — find them.\n\nLook for:\n- Overlapping elements (text through shapes, lines through words, stacked elements)\n- Text overflow or cut off at edges/box boundaries\n- Decorative lines positioned for single-line text but title wrapped to two lines\n- Source citations or footers colliding with content above\n- Elements too close (< 0.3\" gaps) or cards/sections nearly touching\n- Uneven gaps (large empty area in one place, cramped in another)\n- Insufficient margin from slide edges (< 0.5\")\n- Columns or similar elements not aligned consistently\n- Low-contrast text (e.g., light gray text on cream-colored background)\n- Low-contrast icons (e.g., dark icons on dark backgrounds without a contrasting circle)\n- Text boxes too narrow causing excessive wrapping\n- Leftover placeholder content\n\nFor each slide, list issues or areas of concern, even if minor.\n\nRead and analyze these images:\n1. /path/to/slide-01.jpg (Expected: [brief description])\n2. /path/to/slide-02.jpg (Expected: [brief description])\n\nReport ALL issues found, including minor ones.\n```\n\n### Verification Loop\n\n1. Generate slides → Convert to images → Inspect\n2. **List issues found** (if none found, look again more critically)\n3. Fix issues\n4. **Re-verify affected slides** — one fix often creates another problem\n5. Repeat until a full pass reveals no new issues\n\n**Do not declare success until you've completed at least one fix-and-verify cycle.**\n\n---\n\n## Converting to Images\n\nConvert presentations to individual slide images for visual inspection:\n\n```bash\npython scripts/office/soffice.py --headless --convert-to pdf output.pptx\npdftoppm -jpeg -r 150 output.pdf slide\n```\n\nThis creates `slide-01.jpg`, `slide-02.jpg`, etc.\n\nTo re-render specific slides after fixes:\n\n```bash\npdftoppm -jpeg -r 150 -f N -l N output.pdf slide-fixed\n```\n\n---\n\n## Dependencies\n\n- `pip install \"markitdown[pptx]\"` - text extraction\n- `pip install Pillow` - thumbnail grids\n- `npm install -g pptxgenjs` - creating from scratch\n- LibreOffice (`soffice`) - PDF conversion (auto-configured for sandboxed environments via `scripts/office/soffice.py`)\n- Poppler (`pdftoppm`) - PDF to images\n"
  },
  {
    "path": "skills/pptx/editing.md",
    "content": "# Editing Presentations\n\n## Template-Based Workflow\n\nWhen using an existing presentation as a template:\n\n1. **Analyze existing slides**:\n   ```bash\n   python scripts/thumbnail.py template.pptx\n   python -m markitdown template.pptx\n   ```\n   Review `thumbnails.jpg` to see layouts, and markitdown output to see placeholder text.\n\n2. **Plan slide mapping**: For each content section, choose a template slide.\n\n   ⚠️ **USE VARIED LAYOUTS** — monotonous presentations are a common failure mode. Don't default to basic title + bullet slides. Actively seek out:\n   - Multi-column layouts (2-column, 3-column)\n   - Image + text combinations\n   - Full-bleed images with text overlay\n   - Quote or callout slides\n   - Section dividers\n   - Stat/number callouts\n   - Icon grids or icon + text rows\n\n   **Avoid:** Repeating the same text-heavy layout for every slide.\n\n   Match content type to layout style (e.g., key points → bullet slide, team info → multi-column, testimonials → quote slide).\n\n3. **Unpack**: `python scripts/office/unpack.py template.pptx unpacked/`\n\n4. **Build presentation** (do this yourself, not with subagents):\n   - Delete unwanted slides (remove from `<p:sldIdLst>`)\n   - Duplicate slides you want to reuse (`add_slide.py`)\n   - Reorder slides in `<p:sldIdLst>`\n   - **Complete all structural changes before step 5**\n\n5. **Edit content**: Update text in each `slide{N}.xml`.\n   **Use subagents here if available** — slides are separate XML files, so subagents can edit in parallel.\n\n6. **Clean**: `python scripts/clean.py unpacked/`\n\n7. **Pack**: `python scripts/office/pack.py unpacked/ output.pptx --original template.pptx`\n\n---\n\n## Scripts\n\n| Script | Purpose |\n|--------|---------|\n| `unpack.py` | Extract and pretty-print PPTX |\n| `add_slide.py` | Duplicate slide or create from layout |\n| `clean.py` | Remove orphaned files |\n| `pack.py` | Repack with validation |\n| `thumbnail.py` | Create visual grid of slides |\n\n### unpack.py\n\n```bash\npython scripts/office/unpack.py input.pptx unpacked/\n```\n\nExtracts PPTX, pretty-prints XML, escapes smart quotes.\n\n### add_slide.py\n\n```bash\npython scripts/add_slide.py unpacked/ slide2.xml      # Duplicate slide\npython scripts/add_slide.py unpacked/ slideLayout2.xml # From layout\n```\n\nPrints `<p:sldId>` to add to `<p:sldIdLst>` at desired position.\n\n### clean.py\n\n```bash\npython scripts/clean.py unpacked/\n```\n\nRemoves slides not in `<p:sldIdLst>`, unreferenced media, orphaned rels.\n\n### pack.py\n\n```bash\npython scripts/office/pack.py unpacked/ output.pptx --original input.pptx\n```\n\nValidates, repairs, condenses XML, re-encodes smart quotes.\n\n### thumbnail.py\n\n```bash\npython scripts/thumbnail.py input.pptx [output_prefix] [--cols N]\n```\n\nCreates `thumbnails.jpg` with slide filenames as labels. Default 3 columns, max 12 per grid.\n\n**Use for template analysis only** (choosing layouts). For visual QA, use `soffice` + `pdftoppm` to create full-resolution individual slide images—see SKILL.md.\n\n---\n\n## Slide Operations\n\nSlide order is in `ppt/presentation.xml` → `<p:sldIdLst>`.\n\n**Reorder**: Rearrange `<p:sldId>` elements.\n\n**Delete**: Remove `<p:sldId>`, then run `clean.py`.\n\n**Add**: Use `add_slide.py`. Never manually copy slide files—the script handles notes references, Content_Types.xml, and relationship IDs that manual copying misses.\n\n---\n\n## Editing Content\n\n**Subagents:** If available, use them here (after completing step 4). Each slide is a separate XML file, so subagents can edit in parallel. In your prompt to subagents, include:\n- The slide file path(s) to edit\n- **\"Use the Edit tool for all changes\"**\n- The formatting rules and common pitfalls below\n\nFor each slide:\n1. Read the slide's XML\n2. Identify ALL placeholder content—text, images, charts, icons, captions\n3. Replace each placeholder with final content\n\n**Use the Edit tool, not sed or Python scripts.** The Edit tool forces specificity about what to replace and where, yielding better reliability.\n\n### Formatting Rules\n\n- **Bold all headers, subheadings, and inline labels**: Use `b=\"1\"` on `<a:rPr>`. This includes:\n  - Slide titles\n  - Section headers within a slide\n  - Inline labels like (e.g.: \"Status:\", \"Description:\") at the start of a line\n- **Never use unicode bullets (•)**: Use proper list formatting with `<a:buChar>` or `<a:buAutoNum>`\n- **Bullet consistency**: Let bullets inherit from the layout. Only specify `<a:buChar>` or `<a:buNone>`.\n\n---\n\n## Common Pitfalls\n\n### Template Adaptation\n\nWhen source content has fewer items than the template:\n- **Remove excess elements entirely** (images, shapes, text boxes), don't just clear text\n- Check for orphaned visuals after clearing text content\n- Run visual QA to catch mismatched counts\n\nWhen replacing text with different length content:\n- **Shorter replacements**: Usually safe\n- **Longer replacements**: May overflow or wrap unexpectedly\n- Test with visual QA after text changes\n- Consider truncating or splitting content to fit the template's design constraints\n\n**Template slots ≠ Source items**: If template has 4 team members but source has 3 users, delete the 4th member's entire group (image + text boxes), not just the text.\n\n### Multi-Item Content\n\nIf source has multiple items (numbered lists, multiple sections), create separate `<a:p>` elements for each — **never concatenate into one string**.\n\n**❌ WRONG** — all items in one paragraph:\n```xml\n<a:p>\n  <a:r><a:rPr .../><a:t>Step 1: Do the first thing. Step 2: Do the second thing.</a:t></a:r>\n</a:p>\n```\n\n**✅ CORRECT** — separate paragraphs with bold headers:\n```xml\n<a:p>\n  <a:pPr algn=\"l\"><a:lnSpc><a:spcPts val=\"3919\"/></a:lnSpc></a:pPr>\n  <a:r><a:rPr lang=\"en-US\" sz=\"2799\" b=\"1\" .../><a:t>Step 1</a:t></a:r>\n</a:p>\n<a:p>\n  <a:pPr algn=\"l\"><a:lnSpc><a:spcPts val=\"3919\"/></a:lnSpc></a:pPr>\n  <a:r><a:rPr lang=\"en-US\" sz=\"2799\" .../><a:t>Do the first thing.</a:t></a:r>\n</a:p>\n<a:p>\n  <a:pPr algn=\"l\"><a:lnSpc><a:spcPts val=\"3919\"/></a:lnSpc></a:pPr>\n  <a:r><a:rPr lang=\"en-US\" sz=\"2799\" b=\"1\" .../><a:t>Step 2</a:t></a:r>\n</a:p>\n<!-- continue pattern -->\n```\n\nCopy `<a:pPr>` from the original paragraph to preserve line spacing. Use `b=\"1\"` on headers.\n\n### Smart Quotes\n\nHandled automatically by unpack/pack. But the Edit tool converts smart quotes to ASCII.\n\n**When adding new text with quotes, use XML entities:**\n\n```xml\n<a:t>the &#x201C;Agreement&#x201D;</a:t>\n```\n\n| Character | Name | Unicode | XML Entity |\n|-----------|------|---------|------------|\n| `“` | Left double quote | U+201C | `&#x201C;` |\n| `”` | Right double quote | U+201D | `&#x201D;` |\n| `‘` | Left single quote | U+2018 | `&#x2018;` |\n| `’` | Right single quote | U+2019 | `&#x2019;` |\n\n### Other\n\n- **Whitespace**: Use `xml:space=\"preserve\"` on `<a:t>` with leading/trailing spaces\n- **XML parsing**: Use `defusedxml.minidom`, not `xml.etree.ElementTree` (corrupts namespaces)\n"
  },
  {
    "path": "skills/pptx/pptxgenjs.md",
    "content": "# PptxGenJS Tutorial\n\n## Setup & Basic Structure\n\n```javascript\nconst pptxgen = require(\"pptxgenjs\");\n\nlet pres = new pptxgen();\npres.layout = 'LAYOUT_16x9';  // or 'LAYOUT_16x10', 'LAYOUT_4x3', 'LAYOUT_WIDE'\npres.author = 'Your Name';\npres.title = 'Presentation Title';\n\nlet slide = pres.addSlide();\nslide.addText(\"Hello World!\", { x: 0.5, y: 0.5, fontSize: 36, color: \"363636\" });\n\npres.writeFile({ fileName: \"Presentation.pptx\" });\n```\n\n## Layout Dimensions\n\nSlide dimensions (coordinates in inches):\n- `LAYOUT_16x9`: 10\" × 5.625\" (default)\n- `LAYOUT_16x10`: 10\" × 6.25\"\n- `LAYOUT_4x3`: 10\" × 7.5\"\n- `LAYOUT_WIDE`: 13.3\" × 7.5\"\n\n---\n\n## Text & Formatting\n\n```javascript\n// Basic text\nslide.addText(\"Simple Text\", {\n  x: 1, y: 1, w: 8, h: 2, fontSize: 24, fontFace: \"Arial\",\n  color: \"363636\", bold: true, align: \"center\", valign: \"middle\"\n});\n\n// Character spacing (use charSpacing, not letterSpacing which is silently ignored)\nslide.addText(\"SPACED TEXT\", { x: 1, y: 1, w: 8, h: 1, charSpacing: 6 });\n\n// Rich text arrays\nslide.addText([\n  { text: \"Bold \", options: { bold: true } },\n  { text: \"Italic \", options: { italic: true } }\n], { x: 1, y: 3, w: 8, h: 1 });\n\n// Multi-line text (requires breakLine: true)\nslide.addText([\n  { text: \"Line 1\", options: { breakLine: true } },\n  { text: \"Line 2\", options: { breakLine: true } },\n  { text: \"Line 3\" }  // Last item doesn't need breakLine\n], { x: 0.5, y: 0.5, w: 8, h: 2 });\n\n// Text box margin (internal padding)\nslide.addText(\"Title\", {\n  x: 0.5, y: 0.3, w: 9, h: 0.6,\n  margin: 0  // Use 0 when aligning text with other elements like shapes or icons\n});\n```\n\n**Tip:** Text boxes have internal margin by default. Set `margin: 0` when you need text to align precisely with shapes, lines, or icons at the same x-position.\n\n---\n\n## Lists & Bullets\n\n```javascript\n// ✅ CORRECT: Multiple bullets\nslide.addText([\n  { text: \"First item\", options: { bullet: true, breakLine: true } },\n  { text: \"Second item\", options: { bullet: true, breakLine: true } },\n  { text: \"Third item\", options: { bullet: true } }\n], { x: 0.5, y: 0.5, w: 8, h: 3 });\n\n// ❌ WRONG: Never use unicode bullets\nslide.addText(\"• First item\", { ... });  // Creates double bullets\n\n// Sub-items and numbered lists\n{ text: \"Sub-item\", options: { bullet: true, indentLevel: 1 } }\n{ text: \"First\", options: { bullet: { type: \"number\" }, breakLine: true } }\n```\n\n---\n\n## Shapes\n\n```javascript\nslide.addShape(pres.shapes.RECTANGLE, {\n  x: 0.5, y: 0.8, w: 1.5, h: 3.0,\n  fill: { color: \"FF0000\" }, line: { color: \"000000\", width: 2 }\n});\n\nslide.addShape(pres.shapes.OVAL, { x: 4, y: 1, w: 2, h: 2, fill: { color: \"0000FF\" } });\n\nslide.addShape(pres.shapes.LINE, {\n  x: 1, y: 3, w: 5, h: 0, line: { color: \"FF0000\", width: 3, dashType: \"dash\" }\n});\n\n// With transparency\nslide.addShape(pres.shapes.RECTANGLE, {\n  x: 1, y: 1, w: 3, h: 2,\n  fill: { color: \"0088CC\", transparency: 50 }\n});\n\n// Rounded rectangle (rectRadius only works with ROUNDED_RECTANGLE, not RECTANGLE)\n// ⚠️ Don't pair with rectangular accent overlays — they won't cover rounded corners. Use RECTANGLE instead.\nslide.addShape(pres.shapes.ROUNDED_RECTANGLE, {\n  x: 1, y: 1, w: 3, h: 2,\n  fill: { color: \"FFFFFF\" }, rectRadius: 0.1\n});\n\n// With shadow\nslide.addShape(pres.shapes.RECTANGLE, {\n  x: 1, y: 1, w: 3, h: 2,\n  fill: { color: \"FFFFFF\" },\n  shadow: { type: \"outer\", color: \"000000\", blur: 6, offset: 2, angle: 135, opacity: 0.15 }\n});\n```\n\nShadow options:\n\n| Property | Type | Range | Notes |\n|----------|------|-------|-------|\n| `type` | string | `\"outer\"`, `\"inner\"` | |\n| `color` | string | 6-char hex (e.g. `\"000000\"`) | No `#` prefix, no 8-char hex — see Common Pitfalls |\n| `blur` | number | 0-100 pt | |\n| `offset` | number | 0-200 pt | **Must be non-negative** — negative values corrupt the file |\n| `angle` | number | 0-359 degrees | Direction the shadow falls (135 = bottom-right, 270 = upward) |\n| `opacity` | number | 0.0-1.0 | Use this for transparency, never encode in color string |\n\nTo cast a shadow upward (e.g. on a footer bar), use `angle: 270` with a positive offset — do **not** use a negative offset.\n\n**Note**: Gradient fills are not natively supported. Use a gradient image as a background instead.\n\n---\n\n## Images\n\n### Image Sources\n\n```javascript\n// From file path\nslide.addImage({ path: \"images/chart.png\", x: 1, y: 1, w: 5, h: 3 });\n\n// From URL\nslide.addImage({ path: \"https://example.com/image.jpg\", x: 1, y: 1, w: 5, h: 3 });\n\n// From base64 (faster, no file I/O)\nslide.addImage({ data: \"image/png;base64,iVBORw0KGgo...\", x: 1, y: 1, w: 5, h: 3 });\n```\n\n### Image Options\n\n```javascript\nslide.addImage({\n  path: \"image.png\",\n  x: 1, y: 1, w: 5, h: 3,\n  rotate: 45,              // 0-359 degrees\n  rounding: true,          // Circular crop\n  transparency: 50,        // 0-100\n  flipH: true,             // Horizontal flip\n  flipV: false,            // Vertical flip\n  altText: \"Description\",  // Accessibility\n  hyperlink: { url: \"https://example.com\" }\n});\n```\n\n### Image Sizing Modes\n\n```javascript\n// Contain - fit inside, preserve ratio\n{ sizing: { type: 'contain', w: 4, h: 3 } }\n\n// Cover - fill area, preserve ratio (may crop)\n{ sizing: { type: 'cover', w: 4, h: 3 } }\n\n// Crop - cut specific portion\n{ sizing: { type: 'crop', x: 0.5, y: 0.5, w: 2, h: 2 } }\n```\n\n### Calculate Dimensions (preserve aspect ratio)\n\n```javascript\nconst origWidth = 1978, origHeight = 923, maxHeight = 3.0;\nconst calcWidth = maxHeight * (origWidth / origHeight);\nconst centerX = (10 - calcWidth) / 2;\n\nslide.addImage({ path: \"image.png\", x: centerX, y: 1.2, w: calcWidth, h: maxHeight });\n```\n\n### Supported Formats\n\n- **Standard**: PNG, JPG, GIF (animated GIFs work in Microsoft 365)\n- **SVG**: Works in modern PowerPoint/Microsoft 365\n\n---\n\n## Icons\n\nUse react-icons to generate SVG icons, then rasterize to PNG for universal compatibility.\n\n### Setup\n\n```javascript\nconst React = require(\"react\");\nconst ReactDOMServer = require(\"react-dom/server\");\nconst sharp = require(\"sharp\");\nconst { FaCheckCircle, FaChartLine } = require(\"react-icons/fa\");\n\nfunction renderIconSvg(IconComponent, color = \"#000000\", size = 256) {\n  return ReactDOMServer.renderToStaticMarkup(\n    React.createElement(IconComponent, { color, size: String(size) })\n  );\n}\n\nasync function iconToBase64Png(IconComponent, color, size = 256) {\n  const svg = renderIconSvg(IconComponent, color, size);\n  const pngBuffer = await sharp(Buffer.from(svg)).png().toBuffer();\n  return \"image/png;base64,\" + pngBuffer.toString(\"base64\");\n}\n```\n\n### Add Icon to Slide\n\n```javascript\nconst iconData = await iconToBase64Png(FaCheckCircle, \"#4472C4\", 256);\n\nslide.addImage({\n  data: iconData,\n  x: 1, y: 1, w: 0.5, h: 0.5  // Size in inches\n});\n```\n\n**Note**: Use size 256 or higher for crisp icons. The size parameter controls the rasterization resolution, not the display size on the slide (which is set by `w` and `h` in inches).\n\n### Icon Libraries\n\nInstall: `npm install -g react-icons react react-dom sharp`\n\nPopular icon sets in react-icons:\n- `react-icons/fa` - Font Awesome\n- `react-icons/md` - Material Design\n- `react-icons/hi` - Heroicons\n- `react-icons/bi` - Bootstrap Icons\n\n---\n\n## Slide Backgrounds\n\n```javascript\n// Solid color\nslide.background = { color: \"F1F1F1\" };\n\n// Color with transparency\nslide.background = { color: \"FF3399\", transparency: 50 };\n\n// Image from URL\nslide.background = { path: \"https://example.com/bg.jpg\" };\n\n// Image from base64\nslide.background = { data: \"image/png;base64,iVBORw0KGgo...\" };\n```\n\n---\n\n## Tables\n\n```javascript\nslide.addTable([\n  [\"Header 1\", \"Header 2\"],\n  [\"Cell 1\", \"Cell 2\"]\n], {\n  x: 1, y: 1, w: 8, h: 2,\n  border: { pt: 1, color: \"999999\" }, fill: { color: \"F1F1F1\" }\n});\n\n// Advanced with merged cells\nlet tableData = [\n  [{ text: \"Header\", options: { fill: { color: \"6699CC\" }, color: \"FFFFFF\", bold: true } }, \"Cell\"],\n  [{ text: \"Merged\", options: { colspan: 2 } }]\n];\nslide.addTable(tableData, { x: 1, y: 3.5, w: 8, colW: [4, 4] });\n```\n\n---\n\n## Charts\n\n```javascript\n// Bar chart\nslide.addChart(pres.charts.BAR, [{\n  name: \"Sales\", labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"], values: [4500, 5500, 6200, 7100]\n}], {\n  x: 0.5, y: 0.6, w: 6, h: 3, barDir: 'col',\n  showTitle: true, title: 'Quarterly Sales'\n});\n\n// Line chart\nslide.addChart(pres.charts.LINE, [{\n  name: \"Temp\", labels: [\"Jan\", \"Feb\", \"Mar\"], values: [32, 35, 42]\n}], { x: 0.5, y: 4, w: 6, h: 3, lineSize: 3, lineSmooth: true });\n\n// Pie chart\nslide.addChart(pres.charts.PIE, [{\n  name: \"Share\", labels: [\"A\", \"B\", \"Other\"], values: [35, 45, 20]\n}], { x: 7, y: 1, w: 5, h: 4, showPercent: true });\n```\n\n### Better-Looking Charts\n\nDefault charts look dated. Apply these options for a modern, clean appearance:\n\n```javascript\nslide.addChart(pres.charts.BAR, chartData, {\n  x: 0.5, y: 1, w: 9, h: 4, barDir: \"col\",\n\n  // Custom colors (match your presentation palette)\n  chartColors: [\"0D9488\", \"14B8A6\", \"5EEAD4\"],\n\n  // Clean background\n  chartArea: { fill: { color: \"FFFFFF\" }, roundedCorners: true },\n\n  // Muted axis labels\n  catAxisLabelColor: \"64748B\",\n  valAxisLabelColor: \"64748B\",\n\n  // Subtle grid (value axis only)\n  valGridLine: { color: \"E2E8F0\", size: 0.5 },\n  catGridLine: { style: \"none\" },\n\n  // Data labels on bars\n  showValue: true,\n  dataLabelPosition: \"outEnd\",\n  dataLabelColor: \"1E293B\",\n\n  // Hide legend for single series\n  showLegend: false,\n});\n```\n\n**Key styling options:**\n- `chartColors: [...]` - hex colors for series/segments\n- `chartArea: { fill, border, roundedCorners }` - chart background\n- `catGridLine/valGridLine: { color, style, size }` - grid lines (`style: \"none\"` to hide)\n- `lineSmooth: true` - curved lines (line charts)\n- `legendPos: \"r\"` - legend position: \"b\", \"t\", \"l\", \"r\", \"tr\"\n\n---\n\n## Slide Masters\n\n```javascript\npres.defineSlideMaster({\n  title: 'TITLE_SLIDE', background: { color: '283A5E' },\n  objects: [{\n    placeholder: { options: { name: 'title', type: 'title', x: 1, y: 2, w: 8, h: 2 } }\n  }]\n});\n\nlet titleSlide = pres.addSlide({ masterName: \"TITLE_SLIDE\" });\ntitleSlide.addText(\"My Title\", { placeholder: \"title\" });\n```\n\n---\n\n## Common Pitfalls\n\n⚠️ These issues cause file corruption, visual bugs, or broken output. Avoid them.\n\n1. **NEVER use \"#\" with hex colors** - causes file corruption\n   ```javascript\n   color: \"FF0000\"      // ✅ CORRECT\n   color: \"#FF0000\"     // ❌ WRONG\n   ```\n\n2. **NEVER encode opacity in hex color strings** - 8-char colors (e.g., `\"00000020\"`) corrupt the file. Use the `opacity` property instead.\n   ```javascript\n   shadow: { type: \"outer\", blur: 6, offset: 2, color: \"00000020\" }          // ❌ CORRUPTS FILE\n   shadow: { type: \"outer\", blur: 6, offset: 2, color: \"000000\", opacity: 0.12 }  // ✅ CORRECT\n   ```\n\n3. **Use `bullet: true`** - NEVER unicode symbols like \"•\" (creates double bullets)\n\n4. **Use `breakLine: true`** between array items or text runs together\n\n5. **Avoid `lineSpacing` with bullets** - causes excessive gaps; use `paraSpaceAfter` instead\n\n6. **Each presentation needs fresh instance** - don't reuse `pptxgen()` objects\n\n7. **NEVER reuse option objects across calls** - PptxGenJS mutates objects in-place (e.g. converting shadow values to EMU). Sharing one object between multiple calls corrupts the second shape.\n   ```javascript\n   const shadow = { type: \"outer\", blur: 6, offset: 2, color: \"000000\", opacity: 0.15 };\n   slide.addShape(pres.shapes.RECTANGLE, { shadow, ... });  // ❌ second call gets already-converted values\n   slide.addShape(pres.shapes.RECTANGLE, { shadow, ... });\n\n   const makeShadow = () => ({ type: \"outer\", blur: 6, offset: 2, color: \"000000\", opacity: 0.15 });\n   slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow(), ... });  // ✅ fresh object each time\n   slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow(), ... });\n   ```\n\n8. **Don't use `ROUNDED_RECTANGLE` with accent borders** - rectangular overlay bars won't cover rounded corners. Use `RECTANGLE` instead.\n   ```javascript\n   // ❌ WRONG: Accent bar doesn't cover rounded corners\n   slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: \"FFFFFF\" } });\n   slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: \"0891B2\" } });\n\n   // ✅ CORRECT: Use RECTANGLE for clean alignment\n   slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: \"FFFFFF\" } });\n   slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: \"0891B2\" } });\n   ```\n\n---\n\n## Quick Reference\n\n- **Shapes**: RECTANGLE, OVAL, LINE, ROUNDED_RECTANGLE\n- **Charts**: BAR, LINE, PIE, DOUGHNUT, SCATTER, BUBBLE, RADAR\n- **Layouts**: LAYOUT_16x9 (10\"×5.625\"), LAYOUT_16x10, LAYOUT_4x3, LAYOUT_WIDE\n- **Alignment**: \"left\", \"center\", \"right\"\n- **Chart data labels**: \"outEnd\", \"inEnd\", \"center\"\n"
  },
  {
    "path": "skills/pptx/scripts/__init__.py",
    "content": ""
  },
  {
    "path": "skills/pptx/scripts/add_slide.py",
    "content": "\"\"\"Add a new slide to an unpacked PPTX directory.\n\nUsage: python add_slide.py <unpacked_dir> <source>\n\nThe source can be:\n  - A slide file (e.g., slide2.xml) - duplicates the slide\n  - A layout file (e.g., slideLayout2.xml) - creates from layout\n\nExamples:\n    python add_slide.py unpacked/ slide2.xml\n    # Duplicates slide2, creates slide5.xml\n\n    python add_slide.py unpacked/ slideLayout2.xml\n    # Creates slide5.xml from slideLayout2.xml\n\nTo see available layouts: ls unpacked/ppt/slideLayouts/\n\nPrints the <p:sldId> element to add to presentation.xml.\n\"\"\"\n\nimport re\nimport shutil\nimport sys\nfrom pathlib import Path\n\n\ndef get_next_slide_number(slides_dir: Path) -> int:\n    existing = [int(m.group(1)) for f in slides_dir.glob(\"slide*.xml\")\n                if (m := re.match(r\"slide(\\d+)\\.xml\", f.name))]\n    return max(existing) + 1 if existing else 1\n\n\ndef create_slide_from_layout(unpacked_dir: Path, layout_file: str) -> None:\n    slides_dir = unpacked_dir / \"ppt\" / \"slides\"\n    rels_dir = slides_dir / \"_rels\"\n    layouts_dir = unpacked_dir / \"ppt\" / \"slideLayouts\"\n\n    layout_path = layouts_dir / layout_file\n    if not layout_path.exists():\n        print(f\"Error: {layout_path} not found\", file=sys.stderr)\n        sys.exit(1)\n\n    next_num = get_next_slide_number(slides_dir)\n    dest = f\"slide{next_num}.xml\"\n    dest_slide = slides_dir / dest\n    dest_rels = rels_dir / f\"{dest}.rels\"\n\n    slide_xml = '''<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <p:cSld>\n    <p:spTree>\n      <p:nvGrpSpPr>\n        <p:cNvPr id=\"1\" name=\"\"/>\n        <p:cNvGrpSpPr/>\n        <p:nvPr/>\n      </p:nvGrpSpPr>\n      <p:grpSpPr>\n        <a:xfrm>\n          <a:off x=\"0\" y=\"0\"/>\n          <a:ext cx=\"0\" cy=\"0\"/>\n          <a:chOff x=\"0\" y=\"0\"/>\n          <a:chExt cx=\"0\" cy=\"0\"/>\n        </a:xfrm>\n      </p:grpSpPr>\n    </p:spTree>\n  </p:cSld>\n  <p:clrMapOvr>\n    <a:masterClrMapping/>\n  </p:clrMapOvr>\n</p:sld>'''\n    dest_slide.write_text(slide_xml, encoding=\"utf-8\")\n\n    rels_dir.mkdir(exist_ok=True)\n    rels_xml = f'''<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n  <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/{layout_file}\"/>\n</Relationships>'''\n    dest_rels.write_text(rels_xml, encoding=\"utf-8\")\n\n    _add_to_content_types(unpacked_dir, dest)\n\n    rid = _add_to_presentation_rels(unpacked_dir, dest)\n\n    next_slide_id = _get_next_slide_id(unpacked_dir)\n\n    print(f\"Created {dest} from {layout_file}\")\n    print(f'Add to presentation.xml <p:sldIdLst>: <p:sldId id=\"{next_slide_id}\" r:id=\"{rid}\"/>')\n\n\ndef duplicate_slide(unpacked_dir: Path, source: str) -> None:\n    slides_dir = unpacked_dir / \"ppt\" / \"slides\"\n    rels_dir = slides_dir / \"_rels\"\n\n    source_slide = slides_dir / source\n\n    if not source_slide.exists():\n        print(f\"Error: {source_slide} not found\", file=sys.stderr)\n        sys.exit(1)\n\n    next_num = get_next_slide_number(slides_dir)\n    dest = f\"slide{next_num}.xml\"\n    dest_slide = slides_dir / dest\n\n    source_rels = rels_dir / f\"{source}.rels\"\n    dest_rels = rels_dir / f\"{dest}.rels\"\n\n    shutil.copy2(source_slide, dest_slide)\n\n    if source_rels.exists():\n        shutil.copy2(source_rels, dest_rels)\n\n        rels_content = dest_rels.read_text(encoding=\"utf-8\")\n        rels_content = re.sub(\n            r'\\s*<Relationship[^>]*Type=\"[^\"]*notesSlide\"[^>]*/>\\s*',\n            \"\\n\",\n            rels_content,\n        )\n        dest_rels.write_text(rels_content, encoding=\"utf-8\")\n\n    _add_to_content_types(unpacked_dir, dest)\n\n    rid = _add_to_presentation_rels(unpacked_dir, dest)\n\n    next_slide_id = _get_next_slide_id(unpacked_dir)\n\n    print(f\"Created {dest} from {source}\")\n    print(f'Add to presentation.xml <p:sldIdLst>: <p:sldId id=\"{next_slide_id}\" r:id=\"{rid}\"/>')\n\n\ndef _add_to_content_types(unpacked_dir: Path, dest: str) -> None:\n    content_types_path = unpacked_dir / \"[Content_Types].xml\"\n    content_types = content_types_path.read_text(encoding=\"utf-8\")\n\n    new_override = f'<Override PartName=\"/ppt/slides/{dest}\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\"/>'\n\n    if f\"/ppt/slides/{dest}\" not in content_types:\n        content_types = content_types.replace(\"</Types>\", f\"  {new_override}\\n</Types>\")\n        content_types_path.write_text(content_types, encoding=\"utf-8\")\n\n\ndef _add_to_presentation_rels(unpacked_dir: Path, dest: str) -> str:\n    pres_rels_path = unpacked_dir / \"ppt\" / \"_rels\" / \"presentation.xml.rels\"\n    pres_rels = pres_rels_path.read_text(encoding=\"utf-8\")\n\n    rids = [int(m) for m in re.findall(r'Id=\"rId(\\d+)\"', pres_rels)]\n    next_rid = max(rids) + 1 if rids else 1\n    rid = f\"rId{next_rid}\"\n\n    new_rel = f'<Relationship Id=\"{rid}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"slides/{dest}\"/>'\n\n    if f\"slides/{dest}\" not in pres_rels:\n        pres_rels = pres_rels.replace(\"</Relationships>\", f\"  {new_rel}\\n</Relationships>\")\n        pres_rels_path.write_text(pres_rels, encoding=\"utf-8\")\n\n    return rid\n\n\ndef _get_next_slide_id(unpacked_dir: Path) -> int:\n    pres_path = unpacked_dir / \"ppt\" / \"presentation.xml\"\n    pres_content = pres_path.read_text(encoding=\"utf-8\")\n    slide_ids = [int(m) for m in re.findall(r'<p:sldId[^>]*id=\"(\\d+)\"', pres_content)]\n    return max(slide_ids) + 1 if slide_ids else 256\n\n\ndef parse_source(source: str) -> tuple[str, str | None]:\n    if source.startswith(\"slideLayout\") and source.endswith(\".xml\"):\n        return (\"layout\", source)\n\n    return (\"slide\", None)\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 3:\n        print(\"Usage: python add_slide.py <unpacked_dir> <source>\", file=sys.stderr)\n        print(\"\", file=sys.stderr)\n        print(\"Source can be:\", file=sys.stderr)\n        print(\"  slide2.xml        - duplicate an existing slide\", file=sys.stderr)\n        print(\"  slideLayout2.xml  - create from a layout template\", file=sys.stderr)\n        print(\"\", file=sys.stderr)\n        print(\"To see available layouts: ls <unpacked_dir>/ppt/slideLayouts/\", file=sys.stderr)\n        sys.exit(1)\n\n    unpacked_dir = Path(sys.argv[1])\n    source = sys.argv[2]\n\n    if not unpacked_dir.exists():\n        print(f\"Error: {unpacked_dir} not found\", file=sys.stderr)\n        sys.exit(1)\n\n    source_type, layout_file = parse_source(source)\n\n    if source_type == \"layout\" and layout_file is not None:\n        create_slide_from_layout(unpacked_dir, layout_file)\n    else:\n        duplicate_slide(unpacked_dir, source)\n"
  },
  {
    "path": "skills/pptx/scripts/clean.py",
    "content": "\"\"\"Remove unreferenced files from an unpacked PPTX directory.\n\nUsage: python clean.py <unpacked_dir>\n\nExample:\n    python clean.py unpacked/\n\nThis script removes:\n- Orphaned slides (not in sldIdLst) and their relationships\n- [trash] directory (unreferenced files)\n- Orphaned .rels files for deleted resources\n- Unreferenced media, embeddings, charts, diagrams, drawings, ink files\n- Unreferenced theme files\n- Unreferenced notes slides\n- Content-Type overrides for deleted files\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\n\nimport re\n\n\ndef get_slides_in_sldidlst(unpacked_dir: Path) -> set[str]:\n    pres_path = unpacked_dir / \"ppt\" / \"presentation.xml\"\n    pres_rels_path = unpacked_dir / \"ppt\" / \"_rels\" / \"presentation.xml.rels\"\n\n    if not pres_path.exists() or not pres_rels_path.exists():\n        return set()\n\n    rels_dom = defusedxml.minidom.parse(str(pres_rels_path))\n    rid_to_slide = {}\n    for rel in rels_dom.getElementsByTagName(\"Relationship\"):\n        rid = rel.getAttribute(\"Id\")\n        target = rel.getAttribute(\"Target\")\n        rel_type = rel.getAttribute(\"Type\")\n        if \"slide\" in rel_type and target.startswith(\"slides/\"):\n            rid_to_slide[rid] = target.replace(\"slides/\", \"\")\n\n    pres_content = pres_path.read_text(encoding=\"utf-8\")\n    referenced_rids = set(re.findall(r'<p:sldId[^>]*r:id=\"([^\"]+)\"', pres_content))\n\n    return {rid_to_slide[rid] for rid in referenced_rids if rid in rid_to_slide}\n\n\ndef remove_orphaned_slides(unpacked_dir: Path) -> list[str]:\n    slides_dir = unpacked_dir / \"ppt\" / \"slides\"\n    slides_rels_dir = slides_dir / \"_rels\"\n    pres_rels_path = unpacked_dir / \"ppt\" / \"_rels\" / \"presentation.xml.rels\"\n\n    if not slides_dir.exists():\n        return []\n\n    referenced_slides = get_slides_in_sldidlst(unpacked_dir)\n    removed = []\n\n    for slide_file in slides_dir.glob(\"slide*.xml\"):\n        if slide_file.name not in referenced_slides:\n            rel_path = slide_file.relative_to(unpacked_dir)\n            slide_file.unlink()\n            removed.append(str(rel_path))\n\n            rels_file = slides_rels_dir / f\"{slide_file.name}.rels\"\n            if rels_file.exists():\n                rels_file.unlink()\n                removed.append(str(rels_file.relative_to(unpacked_dir)))\n\n    if removed and pres_rels_path.exists():\n        rels_dom = defusedxml.minidom.parse(str(pres_rels_path))\n        changed = False\n\n        for rel in list(rels_dom.getElementsByTagName(\"Relationship\")):\n            target = rel.getAttribute(\"Target\")\n            if target.startswith(\"slides/\"):\n                slide_name = target.replace(\"slides/\", \"\")\n                if slide_name not in referenced_slides:\n                    if rel.parentNode:\n                        rel.parentNode.removeChild(rel)\n                        changed = True\n\n        if changed:\n            with open(pres_rels_path, \"wb\") as f:\n                f.write(rels_dom.toxml(encoding=\"utf-8\"))\n\n    return removed\n\n\ndef remove_trash_directory(unpacked_dir: Path) -> list[str]:\n    trash_dir = unpacked_dir / \"[trash]\"\n    removed = []\n\n    if trash_dir.exists() and trash_dir.is_dir():\n        for file_path in trash_dir.iterdir():\n            if file_path.is_file():\n                rel_path = file_path.relative_to(unpacked_dir)\n                removed.append(str(rel_path))\n                file_path.unlink()\n        trash_dir.rmdir()\n\n    return removed\n\n\ndef get_slide_referenced_files(unpacked_dir: Path) -> set:\n    referenced = set()\n    slides_rels_dir = unpacked_dir / \"ppt\" / \"slides\" / \"_rels\"\n\n    if not slides_rels_dir.exists():\n        return referenced\n\n    for rels_file in slides_rels_dir.glob(\"*.rels\"):\n        dom = defusedxml.minidom.parse(str(rels_file))\n        for rel in dom.getElementsByTagName(\"Relationship\"):\n            target = rel.getAttribute(\"Target\")\n            if not target:\n                continue\n            target_path = (rels_file.parent.parent / target).resolve()\n            try:\n                referenced.add(target_path.relative_to(unpacked_dir.resolve()))\n            except ValueError:\n                pass\n\n    return referenced\n\n\ndef remove_orphaned_rels_files(unpacked_dir: Path) -> list[str]:\n    resource_dirs = [\"charts\", \"diagrams\", \"drawings\"]\n    removed = []\n    slide_referenced = get_slide_referenced_files(unpacked_dir)\n\n    for dir_name in resource_dirs:\n        rels_dir = unpacked_dir / \"ppt\" / dir_name / \"_rels\"\n        if not rels_dir.exists():\n            continue\n\n        for rels_file in rels_dir.glob(\"*.rels\"):\n            resource_file = rels_dir.parent / rels_file.name.replace(\".rels\", \"\")\n            try:\n                resource_rel_path = resource_file.resolve().relative_to(unpacked_dir.resolve())\n            except ValueError:\n                continue\n\n            if not resource_file.exists() or resource_rel_path not in slide_referenced:\n                rels_file.unlink()\n                rel_path = rels_file.relative_to(unpacked_dir)\n                removed.append(str(rel_path))\n\n    return removed\n\n\ndef get_referenced_files(unpacked_dir: Path) -> set:\n    referenced = set()\n\n    for rels_file in unpacked_dir.rglob(\"*.rels\"):\n        dom = defusedxml.minidom.parse(str(rels_file))\n        for rel in dom.getElementsByTagName(\"Relationship\"):\n            target = rel.getAttribute(\"Target\")\n            if not target:\n                continue\n            target_path = (rels_file.parent.parent / target).resolve()\n            try:\n                referenced.add(target_path.relative_to(unpacked_dir.resolve()))\n            except ValueError:\n                pass\n\n    return referenced\n\n\ndef remove_orphaned_files(unpacked_dir: Path, referenced: set) -> list[str]:\n    resource_dirs = [\"media\", \"embeddings\", \"charts\", \"diagrams\", \"tags\", \"drawings\", \"ink\"]\n    removed = []\n\n    for dir_name in resource_dirs:\n        dir_path = unpacked_dir / \"ppt\" / dir_name\n        if not dir_path.exists():\n            continue\n\n        for file_path in dir_path.glob(\"*\"):\n            if not file_path.is_file():\n                continue\n            rel_path = file_path.relative_to(unpacked_dir)\n            if rel_path not in referenced:\n                file_path.unlink()\n                removed.append(str(rel_path))\n\n    theme_dir = unpacked_dir / \"ppt\" / \"theme\"\n    if theme_dir.exists():\n        for file_path in theme_dir.glob(\"theme*.xml\"):\n            rel_path = file_path.relative_to(unpacked_dir)\n            if rel_path not in referenced:\n                file_path.unlink()\n                removed.append(str(rel_path))\n                theme_rels = theme_dir / \"_rels\" / f\"{file_path.name}.rels\"\n                if theme_rels.exists():\n                    theme_rels.unlink()\n                    removed.append(str(theme_rels.relative_to(unpacked_dir)))\n\n    notes_dir = unpacked_dir / \"ppt\" / \"notesSlides\"\n    if notes_dir.exists():\n        for file_path in notes_dir.glob(\"*.xml\"):\n            if not file_path.is_file():\n                continue\n            rel_path = file_path.relative_to(unpacked_dir)\n            if rel_path not in referenced:\n                file_path.unlink()\n                removed.append(str(rel_path))\n\n        notes_rels_dir = notes_dir / \"_rels\"\n        if notes_rels_dir.exists():\n            for file_path in notes_rels_dir.glob(\"*.rels\"):\n                notes_file = notes_dir / file_path.name.replace(\".rels\", \"\")\n                if not notes_file.exists():\n                    file_path.unlink()\n                    removed.append(str(file_path.relative_to(unpacked_dir)))\n\n    return removed\n\n\ndef update_content_types(unpacked_dir: Path, removed_files: list[str]) -> None:\n    ct_path = unpacked_dir / \"[Content_Types].xml\"\n    if not ct_path.exists():\n        return\n\n    dom = defusedxml.minidom.parse(str(ct_path))\n    changed = False\n\n    for override in list(dom.getElementsByTagName(\"Override\")):\n        part_name = override.getAttribute(\"PartName\").lstrip(\"/\")\n        if part_name in removed_files:\n            if override.parentNode:\n                override.parentNode.removeChild(override)\n                changed = True\n\n    if changed:\n        with open(ct_path, \"wb\") as f:\n            f.write(dom.toxml(encoding=\"utf-8\"))\n\n\ndef clean_unused_files(unpacked_dir: Path) -> list[str]:\n    all_removed = []\n\n    slides_removed = remove_orphaned_slides(unpacked_dir)\n    all_removed.extend(slides_removed)\n\n    trash_removed = remove_trash_directory(unpacked_dir)\n    all_removed.extend(trash_removed)\n\n    while True:\n        removed_rels = remove_orphaned_rels_files(unpacked_dir)\n        referenced = get_referenced_files(unpacked_dir)\n        removed_files = remove_orphaned_files(unpacked_dir, referenced)\n\n        total_removed = removed_rels + removed_files\n        if not total_removed:\n            break\n\n        all_removed.extend(total_removed)\n\n    if all_removed:\n        update_content_types(unpacked_dir, all_removed)\n\n    return all_removed\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        print(\"Usage: python clean.py <unpacked_dir>\", file=sys.stderr)\n        print(\"Example: python clean.py unpacked/\", file=sys.stderr)\n        sys.exit(1)\n\n    unpacked_dir = Path(sys.argv[1])\n\n    if not unpacked_dir.exists():\n        print(f\"Error: {unpacked_dir} not found\", file=sys.stderr)\n        sys.exit(1)\n\n    removed = clean_unused_files(unpacked_dir)\n\n    if removed:\n        print(f\"Removed {len(removed)} unreferenced files:\")\n        for f in removed:\n            print(f\"  {f}\")\n    else:\n        print(\"No unreferenced files found\")\n"
  },
  {
    "path": "skills/pptx/scripts/office/helpers/__init__.py",
    "content": ""
  },
  {
    "path": "skills/pptx/scripts/office/helpers/merge_runs.py",
    "content": "\"\"\"Merge adjacent runs with identical formatting in DOCX.\n\nMerges adjacent <w:r> elements that have identical <w:rPr> properties.\nWorks on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).\n\nAlso:\n- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)\n- Removes proofErr elements (spell/grammar markers that block merging)\n\"\"\"\n\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\n\ndef merge_runs(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        _remove_elements(root, \"proofErr\")\n        _strip_run_rsid_attrs(root)\n\n        containers = {run.parentNode for run in _find_elements(root, \"r\")}\n\n        merge_count = 0\n        for container in containers:\n            merge_count += _merge_runs_in(container)\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Merged {merge_count} runs\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef _get_child(parent, tag: str):\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                return child\n    return None\n\n\ndef _get_children(parent, tag: str) -> list:\n    results = []\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(child)\n    return results\n\n\ndef _is_adjacent(elem1, elem2) -> bool:\n    node = elem1.nextSibling\n    while node:\n        if node == elem2:\n            return True\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n    return False\n\n\n\n\ndef _remove_elements(root, tag: str):\n    for elem in _find_elements(root, tag):\n        if elem.parentNode:\n            elem.parentNode.removeChild(elem)\n\n\ndef _strip_run_rsid_attrs(root):\n    for run in _find_elements(root, \"r\"):\n        for attr in list(run.attributes.values()):\n            if \"rsid\" in attr.name.lower():\n                run.removeAttribute(attr.name)\n\n\n\n\ndef _merge_runs_in(container) -> int:\n    merge_count = 0\n    run = _first_child_run(container)\n\n    while run:\n        while True:\n            next_elem = _next_element_sibling(run)\n            if next_elem and _is_run(next_elem) and _can_merge(run, next_elem):\n                _merge_run_content(run, next_elem)\n                container.removeChild(next_elem)\n                merge_count += 1\n            else:\n                break\n\n        _consolidate_text(run)\n        run = _next_sibling_run(run)\n\n    return merge_count\n\n\ndef _first_child_run(container):\n    for child in container.childNodes:\n        if child.nodeType == child.ELEMENT_NODE and _is_run(child):\n            return child\n    return None\n\n\ndef _next_element_sibling(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _next_sibling_run(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            if _is_run(sibling):\n                return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _is_run(node) -> bool:\n    name = node.localName or node.tagName\n    return name == \"r\" or name.endswith(\":r\")\n\n\ndef _can_merge(run1, run2) -> bool:\n    rpr1 = _get_child(run1, \"rPr\")\n    rpr2 = _get_child(run2, \"rPr\")\n\n    if (rpr1 is None) != (rpr2 is None):\n        return False\n    if rpr1 is None:\n        return True\n    return rpr1.toxml() == rpr2.toxml()  \n\n\ndef _merge_run_content(target, source):\n    for child in list(source.childNodes):\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name != \"rPr\" and not name.endswith(\":rPr\"):\n                target.appendChild(child)\n\n\ndef _consolidate_text(run):\n    t_elements = _get_children(run, \"t\")\n\n    for i in range(len(t_elements) - 1, 0, -1):\n        curr, prev = t_elements[i], t_elements[i - 1]\n\n        if _is_adjacent(prev, curr):\n            prev_text = prev.firstChild.data if prev.firstChild else \"\"\n            curr_text = curr.firstChild.data if curr.firstChild else \"\"\n            merged = prev_text + curr_text\n\n            if prev.firstChild:\n                prev.firstChild.data = merged\n            else:\n                prev.appendChild(run.ownerDocument.createTextNode(merged))\n\n            if merged.startswith(\" \") or merged.endswith(\" \"):\n                prev.setAttribute(\"xml:space\", \"preserve\")\n            elif prev.hasAttribute(\"xml:space\"):\n                prev.removeAttribute(\"xml:space\")\n\n            run.removeChild(curr)\n"
  },
  {
    "path": "skills/pptx/scripts/office/helpers/simplify_redlines.py",
    "content": "\"\"\"Simplify tracked changes by merging adjacent w:ins or w:del elements.\n\nMerges adjacent <w:ins> elements from the same author into a single element.\nSame for <w:del> elements. This makes heavily-redlined documents easier to\nwork with by reducing the number of tracked change wrappers.\n\nRules:\n- Only merges w:ins with w:ins, w:del with w:del (same element type)\n- Only merges if same author (ignores timestamp differences)\n- Only merges if truly adjacent (only whitespace between them)\n\"\"\"\n\nimport xml.etree.ElementTree as ET\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nWORD_NS = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\n\ndef simplify_redlines(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        merge_count = 0\n\n        containers = _find_elements(root, \"p\") + _find_elements(root, \"tc\")\n\n        for container in containers:\n            merge_count += _merge_tracked_changes_in(container, \"ins\")\n            merge_count += _merge_tracked_changes_in(container, \"del\")\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Simplified {merge_count} tracked changes\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\ndef _merge_tracked_changes_in(container, tag: str) -> int:\n    merge_count = 0\n\n    tracked = [\n        child\n        for child in container.childNodes\n        if child.nodeType == child.ELEMENT_NODE and _is_element(child, tag)\n    ]\n\n    if len(tracked) < 2:\n        return 0\n\n    i = 0\n    while i < len(tracked) - 1:\n        curr = tracked[i]\n        next_elem = tracked[i + 1]\n\n        if _can_merge_tracked(curr, next_elem):\n            _merge_tracked_content(curr, next_elem)\n            container.removeChild(next_elem)\n            tracked.pop(i + 1)\n            merge_count += 1\n        else:\n            i += 1\n\n    return merge_count\n\n\ndef _is_element(node, tag: str) -> bool:\n    name = node.localName or node.tagName\n    return name == tag or name.endswith(f\":{tag}\")\n\n\ndef _get_author(elem) -> str:\n    author = elem.getAttribute(\"w:author\")\n    if not author:\n        for attr in elem.attributes.values():\n            if attr.localName == \"author\" or attr.name.endswith(\":author\"):\n                return attr.value\n    return author\n\n\ndef _can_merge_tracked(elem1, elem2) -> bool:\n    if _get_author(elem1) != _get_author(elem2):\n        return False\n\n    node = elem1.nextSibling\n    while node and node != elem2:\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n\n    return True\n\n\ndef _merge_tracked_content(target, source):\n    while source.firstChild:\n        child = source.firstChild\n        source.removeChild(child)\n        target.appendChild(child)\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]:\n    if not doc_xml_path.exists():\n        return {}\n\n    try:\n        tree = ET.parse(doc_xml_path)\n        root = tree.getroot()\n    except ET.ParseError:\n        return {}\n\n    namespaces = {\"w\": WORD_NS}\n    author_attr = f\"{{{WORD_NS}}}author\"\n\n    authors: dict[str, int] = {}\n    for tag in [\"ins\", \"del\"]:\n        for elem in root.findall(f\".//w:{tag}\", namespaces):\n            author = elem.get(author_attr)\n            if author:\n                authors[author] = authors.get(author, 0) + 1\n\n    return authors\n\n\ndef _get_authors_from_docx(docx_path: Path) -> dict[str, int]:\n    try:\n        with zipfile.ZipFile(docx_path, \"r\") as zf:\n            if \"word/document.xml\" not in zf.namelist():\n                return {}\n            with zf.open(\"word/document.xml\") as f:\n                tree = ET.parse(f)\n                root = tree.getroot()\n\n                namespaces = {\"w\": WORD_NS}\n                author_attr = f\"{{{WORD_NS}}}author\"\n\n                authors: dict[str, int] = {}\n                for tag in [\"ins\", \"del\"]:\n                    for elem in root.findall(f\".//w:{tag}\", namespaces):\n                        author = elem.get(author_attr)\n                        if author:\n                            authors[author] = authors.get(author, 0) + 1\n                return authors\n    except (zipfile.BadZipFile, ET.ParseError):\n        return {}\n\n\ndef infer_author(modified_dir: Path, original_docx: Path, default: str = \"Claude\") -> str:\n    modified_xml = modified_dir / \"word\" / \"document.xml\"\n    modified_authors = get_tracked_change_authors(modified_xml)\n\n    if not modified_authors:\n        return default\n\n    original_authors = _get_authors_from_docx(original_docx)\n\n    new_changes: dict[str, int] = {}\n    for author, count in modified_authors.items():\n        original_count = original_authors.get(author, 0)\n        diff = count - original_count\n        if diff > 0:\n            new_changes[author] = diff\n\n    if not new_changes:\n        return default\n\n    if len(new_changes) == 1:\n        return next(iter(new_changes))\n\n    raise ValueError(\n        f\"Multiple authors added new changes: {new_changes}. \"\n        \"Cannot infer which author to validate.\"\n    )\n"
  },
  {
    "path": "skills/pptx/scripts/office/pack.py",
    "content": "\"\"\"Pack a directory into a DOCX, PPTX, or XLSX file.\n\nValidates with auto-repair, condenses XML formatting, and creates the Office file.\n\nUsage:\n    python pack.py <input_directory> <output_file> [--original <file>] [--validate true|false]\n\nExamples:\n    python pack.py unpacked/ output.docx --original input.docx\n    python pack.py unpacked/ output.pptx --validate false\n\"\"\"\n\nimport argparse\nimport sys\nimport shutil\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\ndef pack(\n    input_directory: str,\n    output_file: str,\n    original_file: str | None = None,\n    validate: bool = True,\n    infer_author_func=None,\n) -> tuple[None, str]:\n    input_dir = Path(input_directory)\n    output_path = Path(output_file)\n    suffix = output_path.suffix.lower()\n\n    if not input_dir.is_dir():\n        return None, f\"Error: {input_dir} is not a directory\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {output_file} must be a .docx, .pptx, or .xlsx file\"\n\n    if validate and original_file:\n        original_path = Path(original_file)\n        if original_path.exists():\n            success, output = _run_validation(\n                input_dir, original_path, suffix, infer_author_func\n            )\n            if output:\n                print(output)\n            if not success:\n                return None, f\"Error: Validation failed for {input_dir}\"\n\n    with tempfile.TemporaryDirectory() as temp_dir:\n        temp_content_dir = Path(temp_dir) / \"content\"\n        shutil.copytree(input_dir, temp_content_dir)\n\n        for pattern in [\"*.xml\", \"*.rels\"]:\n            for xml_file in temp_content_dir.rglob(pattern):\n                _condense_xml(xml_file)\n\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n            for f in temp_content_dir.rglob(\"*\"):\n                if f.is_file():\n                    zf.write(f, f.relative_to(temp_content_dir))\n\n    return None, f\"Successfully packed {input_dir} to {output_file}\"\n\n\ndef _run_validation(\n    unpacked_dir: Path,\n    original_file: Path,\n    suffix: str,\n    infer_author_func=None,\n) -> tuple[bool, str | None]:\n    output_lines = []\n    validators = []\n\n    if suffix == \".docx\":\n        author = \"Claude\"\n        if infer_author_func:\n            try:\n                author = infer_author_func(unpacked_dir, original_file)\n            except ValueError as e:\n                print(f\"Warning: {e} Using default author 'Claude'.\", file=sys.stderr)\n\n        validators = [\n            DOCXSchemaValidator(unpacked_dir, original_file),\n            RedliningValidator(unpacked_dir, original_file, author=author),\n        ]\n    elif suffix == \".pptx\":\n        validators = [PPTXSchemaValidator(unpacked_dir, original_file)]\n\n    if not validators:\n        return True, None\n\n    total_repairs = sum(v.repair() for v in validators)\n    if total_repairs:\n        output_lines.append(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        output_lines.append(\"All validations PASSED!\")\n\n    return success, \"\\n\".join(output_lines) if output_lines else None\n\n\ndef _condense_xml(xml_file: Path) -> None:\n    try:\n        with open(xml_file, encoding=\"utf-8\") as f:\n            dom = defusedxml.minidom.parse(f)\n\n        for element in dom.getElementsByTagName(\"*\"):\n            if element.tagName.endswith(\":t\"):\n                continue\n\n            for child in list(element.childNodes):\n                if (\n                    child.nodeType == child.TEXT_NODE\n                    and child.nodeValue\n                    and child.nodeValue.strip() == \"\"\n                ) or child.nodeType == child.COMMENT_NODE:\n                    element.removeChild(child)\n\n        xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n    except Exception as e:\n        print(f\"ERROR: Failed to parse {xml_file.name}: {e}\", file=sys.stderr)\n        raise\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Pack a directory into a DOCX, PPTX, or XLSX file\"\n    )\n    parser.add_argument(\"input_directory\", help=\"Unpacked Office document directory\")\n    parser.add_argument(\"output_file\", help=\"Output Office file (.docx/.pptx/.xlsx)\")\n    parser.add_argument(\n        \"--original\",\n        help=\"Original file for validation comparison\",\n    )\n    parser.add_argument(\n        \"--validate\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Run validation with auto-repair (default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = pack(\n        args.input_directory,\n        args.output_file,\n        original_file=args.original,\n        validate=args.validate,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  xmlns:cdr=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n    schemaLocation=\"dml-chartDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Double\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedInt\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumData\">\n    <xsd:sequence>\n      <xsd:element name=\"formatCode\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_NumVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numCache\" type=\"CT_NumData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strCache\" type=\"CT_StrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"rich\" type=\"a:CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLanguageID\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"multiLvlStrCache\" type=\"CT_MultiLvlStrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AxDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"multiLvlStrRef\" type=\"CT_MultiLvlStrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strLit\" type=\"CT_StrData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerTx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutTarget\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inner\"/>\n      <xsd:enumeration value=\"outer\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutTarget\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutTarget\" default=\"outer\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"edge\"/>\n      <xsd:enumeration value=\"factor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutMode\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutMode\" default=\"factor\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualLayout\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutTarget\" type=\"CT_LayoutTarget\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"x\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"w\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"h\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Layout\">\n    <xsd:sequence>\n      <xsd:element name=\"manualLayout\" type=\"CT_ManualLayout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Title\">\n    <xsd:sequence>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotX\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-90\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotX\">\n    <xsd:attribute name=\"val\" type=\"ST_RotX\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HPercent\">\n    <xsd:union memberTypes=\"ST_HPercentWithSymbol ST_HPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_HPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotY\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotY\">\n    <xsd:attribute name=\"val\" type=\"ST_RotY\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DepthPercent\">\n    <xsd:union memberTypes=\"ST_DepthPercentWithSymbol ST_DepthPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"20\"/>\n      <xsd:maxInclusive value=\"2000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DepthPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_DepthPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Perspective\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"240\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perspective\">\n    <xsd:attribute name=\"val\" type=\"ST_Perspective\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_View3D\">\n    <xsd:sequence>\n      <xsd:element name=\"rotX\" type=\"CT_RotX\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hPercent\" type=\"CT_HPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rotY\" type=\"CT_RotY\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"depthPercent\" type=\"CT_DepthPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rAngAx\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"perspective\" type=\"CT_Perspective\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface\">\n    <xsd:sequence>\n      <xsd:element name=\"thickness\" type=\"CT_Thickness\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Thickness\">\n    <xsd:union memberTypes=\"ST_ThicknessPercent xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ThicknessPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"([0-9]+)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Thickness\">\n    <xsd:attribute name=\"val\" type=\"ST_Thickness\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DTable\">\n    <xsd:sequence>\n      <xsd:element name=\"showHorzBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVertBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showOutline\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showKeys\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GapAmount\">\n    <xsd:union memberTypes=\"ST_GapAmountPercent ST_GapAmountUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GapAmount\">\n    <xsd:attribute name=\"val\" type=\"ST_GapAmount\" default=\"150%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Overlap\">\n    <xsd:union memberTypes=\"ST_OverlapPercent ST_OverlapByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"(-?0*(([0-9])|([1-9][0-9])|100))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapByte\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-100\"/>\n      <xsd:maxInclusive value=\"100\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Overlap\">\n    <xsd:attribute name=\"val\" type=\"ST_Overlap\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BubbleScale\">\n    <xsd:union memberTypes=\"ST_BubbleScalePercent ST_BubbleScaleUInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-2][0-9][0-9])|300)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScaleUInt\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"300\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BubbleScale\">\n    <xsd:attribute name=\"val\" type=\"ST_BubbleScale\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SizeRepresents\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"w\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SizeRepresents\">\n    <xsd:attribute name=\"val\" type=\"ST_SizeRepresents\" default=\"area\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FirstSliceAng\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FirstSliceAng\">\n    <xsd:attribute name=\"val\" type=\"ST_FirstSliceAng\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HoleSize\">\n    <xsd:union memberTypes=\"ST_HoleSizePercent ST_HoleSizeUByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*([1-9]|([1-8][0-9])|90)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizeUByte\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HoleSize\">\n    <xsd:attribute name=\"val\" type=\"ST_HoleSize\" default=\"10%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SplitType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"val\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SplitType\">\n    <xsd:attribute name=\"val\" type=\"ST_SplitType\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustSplit\">\n    <xsd:sequence>\n      <xsd:element name=\"secondPiePt\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SecondPieSize\">\n    <xsd:union memberTypes=\"ST_SecondPieSizePercent ST_SecondPieSizeUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|(1[0-9][0-9])|200)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizeUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SecondPieSize\">\n    <xsd:attribute name=\"val\" type=\"ST_SecondPieSize\" default=\"75%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceLinked\" type=\"xsd:boolean\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblAlgn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblAlgn\">\n    <xsd:attribute name=\"val\" type=\"ST_LblAlgn\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"inBase\"/>\n      <xsd:enumeration value=\"inEnd\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"outEnd\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_DLblPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_DLblShared\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLblPos\" type=\"CT_DLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLegendKey\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVal\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showCatName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showSerName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPercent\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showBubbleSize\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"separator\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"Group_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbl\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"Group_DLbls\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLeaderLines\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"leaderLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbls\">\n    <xsd:sequence>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbls\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"picture\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"star\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerStyle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerSize\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"72\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerSize\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerSize\" default=\"5\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"symbol\" type=\"CT_MarkerStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"size\" type=\"CT_MarkerSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TrendlineType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"exp\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"log\"/>\n      <xsd:enumeration value=\"movingAvg\"/>\n      <xsd:enumeration value=\"poly\"/>\n      <xsd:enumeration value=\"power\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TrendlineType\">\n    <xsd:attribute name=\"val\" type=\"ST_TrendlineType\" default=\"linear\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Order\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"6\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Order\">\n    <xsd:attribute name=\"val\" type=\"ST_Order\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Period\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Period\">\n    <xsd:attribute name=\"val\" type=\"ST_Period\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrendlineLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Trendline\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineType\" type=\"CT_TrendlineType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_Order\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"period\" type=\"CT_Period\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"intercept\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispRSqr\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispEq\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineLbl\" type=\"CT_TrendlineLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrDir\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrDir\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrBarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"minus\"/>\n      <xsd:enumeration value=\"plus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrBarType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrBarType\" default=\"both\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrValType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"fixedVal\"/>\n      <xsd:enumeration value=\"percentage\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdErr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrValType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrValType\" default=\"fixedVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ErrBars\">\n    <xsd:sequence>\n      <xsd:element name=\"errDir\" type=\"CT_ErrDir\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errBarType\" type=\"CT_ErrBarType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errValType\" type=\"CT_ErrValType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noEndCap\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBar\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBars\">\n    <xsd:sequence>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"downBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SerShared\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_SerTx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AreaSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PieSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleSize\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SurfaceSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Grouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Grouping\">\n    <xsd:attribute name=\"val\" type=\"ST_Grouping\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartLines\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StockChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"3\" maxOccurs=\"4\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ScatterStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineMarker\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"smooth\"/>\n      <xsd:enumeration value=\"smoothMarker\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ScatterStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_ScatterStyle\" default=\"marker\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterChart\">\n    <xsd:sequence>\n      <xsd:element name=\"scatterStyle\" type=\"CT_ScatterStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_ScatterSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RadarStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"filled\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RadarStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_RadarStyle\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarChart\">\n    <xsd:sequence>\n      <xsd:element name=\"radarStyle\" type=\"CT_RadarStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_RadarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"clustered\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarGrouping\">\n    <xsd:attribute name=\"val\" type=\"ST_BarGrouping\" default=\"clustered\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarDir\">\n    <xsd:attribute name=\"val\" type=\"ST_BarDir\" default=\"col\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shape\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cone\"/>\n      <xsd:enumeration value=\"coneToMax\"/>\n      <xsd:enumeration value=\"box\"/>\n      <xsd:enumeration value=\"cylinder\"/>\n      <xsd:enumeration value=\"pyramid\"/>\n      <xsd:enumeration value=\"pyramidToMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:attribute name=\"val\" type=\"ST_Shape\" default=\"box\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_BarChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"barDir\" type=\"CT_BarDir\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grouping\" type=\"CT_BarGrouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_BarChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlap\" type=\"CT_Overlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AreaChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_AreaSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AreaChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Area3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PieChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_PieSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_PieChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pie3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DoughnutChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"holeSize\" type=\"CT_HoleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_OfPieType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"bar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OfPieType\">\n    <xsd:attribute name=\"val\" type=\"ST_OfPieType\" default=\"pie\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfPieChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ofPieType\" type=\"CT_OfPieType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitType\" type=\"CT_SplitType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitPos\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custSplit\" type=\"CT_CustSplit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"secondPieSize\" type=\"CT_SecondPieSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleChart\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BubbleSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleScale\" type=\"CT_BubbleScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showNegBubbles\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sizeRepresents\" type=\"CT_SizeRepresents\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"bandFmt\" type=\"CT_BandFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SurfaceChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"wireframe\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_SurfaceSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"bandFmts\" type=\"CT_BandFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SurfaceChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxPos\">\n    <xsd:attribute name=\"val\" type=\"ST_AxPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Crosses\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"autoZero\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Crosses\">\n    <xsd:attribute name=\"val\" type=\"ST_Crosses\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CrossBetween\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"midCat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CrossBetween\">\n    <xsd:attribute name=\"val\" type=\"ST_CrossBetween\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"out\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickMark\">\n    <xsd:attribute name=\"val\" type=\"ST_TickMark\" default=\"cross\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"high\"/>\n      <xsd:enumeration value=\"low\"/>\n      <xsd:enumeration value=\"nextTo\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_TickLblPos\" default=\"nextTo\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Skip\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Skip\">\n    <xsd:attribute name=\"val\" type=\"ST_Skip\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TimeUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TimeUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_TimeUnit\" default=\"days\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxisUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxisUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_AxisUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BuiltInUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hundreds\"/>\n      <xsd:enumeration value=\"thousands\"/>\n      <xsd:enumeration value=\"tenThousands\"/>\n      <xsd:enumeration value=\"hundredThousands\"/>\n      <xsd:enumeration value=\"millions\"/>\n      <xsd:enumeration value=\"tenMillions\"/>\n      <xsd:enumeration value=\"hundredMillions\"/>\n      <xsd:enumeration value=\"billions\"/>\n      <xsd:enumeration value=\"trillions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BuiltInUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_BuiltInUnit\" default=\"thousands\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stretch\"/>\n      <xsd:enumeration value=\"stack\"/>\n      <xsd:enumeration value=\"stackScale\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureFormat\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureFormat\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureStackUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureStackUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureStackUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureOptions\">\n    <xsd:sequence>\n      <xsd:element name=\"applyToFront\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToSides\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToEnd\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureFormat\" type=\"CT_PictureFormat\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureStackUnit\" type=\"CT_PictureStackUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnitsLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnits\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"custUnit\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"builtInUnit\" type=\"CT_BuiltInUnit\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dispUnitsLbl\" type=\"CT_DispUnitsLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"maxMin\"/>\n      <xsd:enumeration value=\"minMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Orientation\">\n    <xsd:attribute name=\"val\" type=\"ST_Orientation\" default=\"minMax\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LogBase\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LogBase\">\n    <xsd:attribute name=\"val\" type=\"ST_LogBase\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scaling\">\n    <xsd:sequence>\n      <xsd:element name=\"logBase\" type=\"CT_LogBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"orientation\" type=\"CT_Orientation\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"max\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"min\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblOffset\">\n    <xsd:union memberTypes=\"ST_LblOffsetPercent ST_LblOffsetUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblOffset\">\n    <xsd:attribute name=\"val\" type=\"ST_LblOffset\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AxShared\">\n    <xsd:sequence>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scaling\" type=\"CT_Scaling\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axPos\" type=\"CT_AxPos\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblPos\" type=\"CT_TickLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossAx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"crosses\" type=\"CT_Crosses\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"crossesAt\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CatAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblAlgn\" type=\"CT_LblAlgn\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noMultiLvlLbl\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"baseTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ValAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossBetween\" type=\"CT_CrossBetween\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispUnits\" type=\"CT_DispUnits\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PlotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"areaChart\" type=\"CT_AreaChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"area3DChart\" type=\"CT_Area3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lineChart\" type=\"CT_LineChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"line3DChart\" type=\"CT_Line3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"stockChart\" type=\"CT_StockChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"radarChart\" type=\"CT_RadarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"scatterChart\" type=\"CT_ScatterChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pieChart\" type=\"CT_PieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pie3DChart\" type=\"CT_Pie3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"doughnutChart\" type=\"CT_DoughnutChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"barChart\" type=\"CT_BarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bar3DChart\" type=\"CT_Bar3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ofPieChart\" type=\"CT_OfPieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surfaceChart\" type=\"CT_SurfaceChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surface3DChart\" type=\"CT_Surface3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bubbleChart\" type=\"CT_BubbleChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"valAx\" type=\"CT_ValAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"catAx\" type=\"CT_CatAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"dateAx\" type=\"CT_DateAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"serAx\" type=\"CT_SerAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dTable\" type=\"CT_DTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotFmt\" type=\"CT_PivotFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LegendPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LegendPos\">\n    <xsd:attribute name=\"val\" type=\"ST_LegendPos\" default=\"r\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LegendEntryData\">\n    <xsd:sequence>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LegendEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"EG_LegendEntryData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Legend\">\n    <xsd:sequence>\n      <xsd:element name=\"legendPos\" type=\"CT_LegendPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legendEntry\" type=\"CT_LegendEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DispBlanksAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"gap\"/>\n      <xsd:enumeration value=\"zero\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DispBlanksAs\">\n    <xsd:attribute name=\"val\" type=\"ST_DispBlanksAs\" default=\"zero\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chart\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoTitleDeleted\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotFmts\" type=\"CT_PivotFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"view3D\" type=\"CT_View3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"floor\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sideWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotArea\" type=\"CT_PlotArea\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legend\" type=\"CT_Legend\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotVisOnly\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispBlanksAs\" type=\"CT_DispBlanksAs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showDLblsOverMax\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"48\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSource\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Protection\">\n    <xsd:sequence>\n      <xsd:element name=\"chartObject\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"data\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formatting\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userInterface\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"l\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageSetupOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ExternalData\">\n    <xsd:sequence>\n      <xsd:element name=\"autoUpdate\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_PageSetupOrientation\" use=\"optional\"\n      default=\"default\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartSpace\">\n    <xsd:sequence>\n      <xsd:element name=\"date1904\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lang\" type=\"CT_TextLanguageID\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"roundedCorners\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotSource\" type=\"CT_PivotSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_Protection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chart\" type=\"CT_Chart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalData\" type=\"CT_ExternalData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printSettings\" type=\"CT_PrintSettings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userShapes\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"chartSpace\" type=\"CT_ChartSpace\"/>\n  <xsd:element name=\"userShapes\" type=\"cdr:CT_Drawing\"/>\n  <xsd:element name=\"chart\" type=\"CT_RelId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_MarkerCoordinate\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"0.0\"/>\n      <xsd:maxInclusive value=\"1.0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"relSizeAnchor\" type=\"CT_RelSizeAnchor\"/>\n      <xsd:element name=\"absSizeAnchor\" type=\"CT_AbsSizeAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_CTName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_CTCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ClrAppMethod\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HueDir\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"meth\" type=\"ST_ClrAppMethod\" use=\"optional\" default=\"span\"/>\n    <xsd:attribute name=\"hueDir\" type=\"ST_HueDir\" use=\"optional\" default=\"cw\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTStyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"fillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"linClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txLinClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txFillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txEffectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorTransform\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_CTStyleLabel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDef\" type=\"CT_ColorTransform\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdrLst\" type=\"CT_ColorTransformHeaderLst\"/>\n  <xsd:simpleType name=\"ST_PtType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pt\">\n    <xsd:sequence>\n      <xsd:element name=\"prSet\" type=\"CT_ElemPropSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PtType\" use=\"optional\" default=\"node\"/>\n    <xsd:attribute name=\"cxnId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PtList\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_Pt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CxnType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parOf\"/>\n      <xsd:enumeration value=\"presOf\"/>\n      <xsd:enumeration value=\"presParOf\"/>\n      <xsd:enumeration value=\"unknownRelationship\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cxn\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_CxnType\" use=\"optional\" default=\"parOf\"/>\n    <xsd:attribute name=\"srcId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"destId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"srcOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"destOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"parTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sibTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"presId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CxnList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_Cxn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataModel\">\n    <xsd:sequence>\n      <xsd:element name=\"ptLst\" type=\"CT_PtList\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_CxnList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"dataModel\" type=\"CT_DataModel\"/>\n  <xsd:attributeGroup name=\"AG_IteratorAttributes\">\n    <xsd:attribute name=\"axis\" type=\"ST_AxisTypes\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementTypes\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"hideLastTrans\" type=\"ST_Booleans\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"st\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cnt\" type=\"ST_UnsignedInts\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"step\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintAttributes\">\n    <xsd:attribute name=\"type\" type=\"ST_ConstraintType\" use=\"required\"/>\n    <xsd:attribute name=\"for\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"forName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintRefAttributes\">\n    <xsd:attribute name=\"refType\" type=\"ST_ConstraintType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"refFor\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"refForName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"refPtType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_Constraint\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ConstraintRefAttributes\"/>\n    <xsd:attribute name=\"op\" type=\"ST_BoolOperator\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Constraints\">\n    <xsd:sequence>\n      <xsd:element name=\"constr\" type=\"CT_Constraint\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumericRule\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"rule\" type=\"CT_NumericRule\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationOf\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutShapeType\" final=\"restriction\">\n    <xsd:union memberTypes=\"a:ST_ShapeType ST_OutputShapeType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index1\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Adj\">\n    <xsd:attribute name=\"idx\" type=\"ST_Index1\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjLst\">\n    <xsd:sequence>\n      <xsd:element name=\"adj\" type=\"CT_Adj\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"adjLst\" type=\"CT_AdjLst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"type\" type=\"ST_LayoutShapeType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute ref=\"r:blip\" use=\"optional\"/>\n    <xsd:attribute name=\"zOrderOff\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hideGeom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lkTxEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"blipPhldr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"type\" type=\"ST_ParameterId\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ParameterVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Algorithm\">\n    <xsd:sequence>\n      <xsd:element name=\"param\" type=\"CT_Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_AlgorithmType\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutNode\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varLst\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"styleLbl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"chOrder\" type=\"ST_ChildOrderType\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"moveWith\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ForEach\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ref\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_When\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n    <xsd:attribute name=\"func\" type=\"ST_FunctionType\" use=\"required\"/>\n    <xsd:attribute name=\"arg\" type=\"ST_FunctionArgument\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"op\" type=\"ST_FunctionOperator\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FunctionValue\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Otherwise\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Choose\">\n    <xsd:sequence>\n      <xsd:element name=\"if\" type=\"CT_When\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"else\" type=\"CT_Otherwise\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SampleData\">\n    <xsd:sequence>\n      <xsd:element name=\"dataModel\" type=\"CT_DataModel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useDef\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Category\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Categories\">\n    <xsd:sequence>\n      <xsd:element name=\"cat\" type=\"CT_Category\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Name\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Description\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DiagramDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"sampData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"clrData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDef\" type=\"CT_DiagramDefinition\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdrLst\" type=\"CT_DiagramDefinitionHeaderLst\"/>\n  <xsd:complexType name=\"CT_RelIds\">\n    <xsd:attribute ref=\"r:dm\" use=\"required\"/>\n    <xsd:attribute ref=\"r:lo\" use=\"required\"/>\n    <xsd:attribute ref=\"r:qs\" use=\"required\"/>\n    <xsd:attribute ref=\"r:cs\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"relIds\" type=\"CT_RelIds\"/>\n  <xsd:simpleType name=\"ST_ParameterVal\">\n    <xsd:union\n      memberTypes=\"ST_DiagramHorizontalAlignment ST_VerticalAlignment ST_ChildDirection ST_ChildAlignment ST_SecondaryChildAlignment ST_LinearDirection ST_SecondaryLinearDirection ST_StartingElement ST_BendPoint ST_ConnectorRouting ST_ArrowheadStyle ST_ConnectorDimension ST_RotationPath ST_CenterShapeMapping ST_NodeHorizontalAlignment ST_NodeVerticalAlignment ST_FallbackDimension ST_TextDirection ST_PyramidAccentPosition ST_PyramidAccentTextMargin ST_TextBlockDirection ST_TextAnchorHorizontal ST_TextAnchorVertical ST_DiagramTextAlignment ST_AutoTextRotation ST_GrowDirection ST_FlowDirection ST_ContinueDirection ST_Breakpoint ST_Offset ST_HierarchyAlignment xsd:int xsd:double xsd:boolean xsd:string ST_ConnectorPoint\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ModelId\">\n    <xsd:union memberTypes=\"xsd:int s:ST_Guid\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrSetCustVal\">\n    <xsd:union memberTypes=\"s:ST_Percentage xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ElemPropSet\">\n    <xsd:sequence>\n      <xsd:element name=\"presLayoutVars\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"presAssocID\" type=\"ST_ModelId\" use=\"optional\"/>\n    <xsd:attribute name=\"presName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleLbl\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleIdx\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleCnt\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"loTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"loCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coherent3DOff\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"phldrT\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"phldr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custAng\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipVert\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipHor\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzX\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzY\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custT\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleRad\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleInc\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"rev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierBranchStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"hang\"/>\n      <xsd:enumeration value=\"std\"/>\n      <xsd:enumeration value=\"init\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimOneStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"branch\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimLvlStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"lvl\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OrgChart\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NodeCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChildMax\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChildPref\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BulletEnabled\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Direction\">\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" default=\"norm\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierBranchStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_HierBranchStyle\" default=\"std\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimOne\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimOneStr\" default=\"one\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimLvl\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimLvlStr\" default=\"none\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ResizeHandlesStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"rel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ResizeHandles\">\n    <xsd:attribute name=\"val\" type=\"ST_ResizeHandlesStr\" default=\"rel\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutVariablePropertySet\">\n    <xsd:sequence>\n      <xsd:element name=\"orgChart\" type=\"CT_OrgChart\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chMax\" type=\"CT_ChildMax\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chPref\" type=\"CT_ChildPref\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bulletEnabled\" type=\"CT_BulletEnabled\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dir\" type=\"CT_Direction\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hierBranch\" type=\"CT_HierBranchStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animOne\" type=\"CT_AnimOne\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animLvl\" type=\"CT_AnimLvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"resizeHandles\" type=\"CT_ResizeHandles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_SDCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextProps\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"a:CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"CT_TextProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_StyleLabel\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDef\" type=\"CT_StyleDefinition\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdrLst\" type=\"CT_StyleDefinitionHeaderLst\"/>\n  <xsd:simpleType name=\"ST_AlgorithmType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"composite\"/>\n      <xsd:enumeration value=\"conn\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"hierChild\"/>\n      <xsd:enumeration value=\"hierRoot\"/>\n      <xsd:enumeration value=\"pyra\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"snake\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n      <xsd:enumeration value=\"desOrSelf\"/>\n      <xsd:enumeration value=\"par\"/>\n      <xsd:enumeration value=\"ancst\"/>\n      <xsd:enumeration value=\"ancstOrSelf\"/>\n      <xsd:enumeration value=\"followSib\"/>\n      <xsd:enumeration value=\"precedSib\"/>\n      <xsd:enumeration value=\"follow\"/>\n      <xsd:enumeration value=\"preced\"/>\n      <xsd:enumeration value=\"root\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisTypes\">\n    <xsd:list itemType=\"ST_AxisType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BoolOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildOrderType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alignOff\"/>\n      <xsd:enumeration value=\"begMarg\"/>\n      <xsd:enumeration value=\"bendDist\"/>\n      <xsd:enumeration value=\"begPad\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"bMarg\"/>\n      <xsd:enumeration value=\"bOff\"/>\n      <xsd:enumeration value=\"ctrX\"/>\n      <xsd:enumeration value=\"ctrXOff\"/>\n      <xsd:enumeration value=\"ctrY\"/>\n      <xsd:enumeration value=\"ctrYOff\"/>\n      <xsd:enumeration value=\"connDist\"/>\n      <xsd:enumeration value=\"diam\"/>\n      <xsd:enumeration value=\"endMarg\"/>\n      <xsd:enumeration value=\"endPad\"/>\n      <xsd:enumeration value=\"h\"/>\n      <xsd:enumeration value=\"hArH\"/>\n      <xsd:enumeration value=\"hOff\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"lMarg\"/>\n      <xsd:enumeration value=\"lOff\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"rMarg\"/>\n      <xsd:enumeration value=\"rOff\"/>\n      <xsd:enumeration value=\"primFontSz\"/>\n      <xsd:enumeration value=\"pyraAcctRatio\"/>\n      <xsd:enumeration value=\"secFontSz\"/>\n      <xsd:enumeration value=\"sibSp\"/>\n      <xsd:enumeration value=\"secSibSp\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"stemThick\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tMarg\"/>\n      <xsd:enumeration value=\"tOff\"/>\n      <xsd:enumeration value=\"userA\"/>\n      <xsd:enumeration value=\"userB\"/>\n      <xsd:enumeration value=\"userC\"/>\n      <xsd:enumeration value=\"userD\"/>\n      <xsd:enumeration value=\"userE\"/>\n      <xsd:enumeration value=\"userF\"/>\n      <xsd:enumeration value=\"userG\"/>\n      <xsd:enumeration value=\"userH\"/>\n      <xsd:enumeration value=\"userI\"/>\n      <xsd:enumeration value=\"userJ\"/>\n      <xsd:enumeration value=\"userK\"/>\n      <xsd:enumeration value=\"userL\"/>\n      <xsd:enumeration value=\"userM\"/>\n      <xsd:enumeration value=\"userN\"/>\n      <xsd:enumeration value=\"userO\"/>\n      <xsd:enumeration value=\"userP\"/>\n      <xsd:enumeration value=\"userQ\"/>\n      <xsd:enumeration value=\"userR\"/>\n      <xsd:enumeration value=\"userS\"/>\n      <xsd:enumeration value=\"userT\"/>\n      <xsd:enumeration value=\"userU\"/>\n      <xsd:enumeration value=\"userV\"/>\n      <xsd:enumeration value=\"userW\"/>\n      <xsd:enumeration value=\"userX\"/>\n      <xsd:enumeration value=\"userY\"/>\n      <xsd:enumeration value=\"userZ\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"wArH\"/>\n      <xsd:enumeration value=\"wOff\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintRelationship\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"nonNorm\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"nonAsst\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementTypes\">\n    <xsd:list itemType=\"ST_ElementType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ParameterId\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horzAlign\"/>\n      <xsd:enumeration value=\"vertAlign\"/>\n      <xsd:enumeration value=\"chDir\"/>\n      <xsd:enumeration value=\"chAlign\"/>\n      <xsd:enumeration value=\"secChAlign\"/>\n      <xsd:enumeration value=\"linDir\"/>\n      <xsd:enumeration value=\"secLinDir\"/>\n      <xsd:enumeration value=\"stElem\"/>\n      <xsd:enumeration value=\"bendPt\"/>\n      <xsd:enumeration value=\"connRout\"/>\n      <xsd:enumeration value=\"begSty\"/>\n      <xsd:enumeration value=\"endSty\"/>\n      <xsd:enumeration value=\"dim\"/>\n      <xsd:enumeration value=\"rotPath\"/>\n      <xsd:enumeration value=\"ctrShpMap\"/>\n      <xsd:enumeration value=\"nodeHorzAlign\"/>\n      <xsd:enumeration value=\"nodeVertAlign\"/>\n      <xsd:enumeration value=\"fallback\"/>\n      <xsd:enumeration value=\"txDir\"/>\n      <xsd:enumeration value=\"pyraAcctPos\"/>\n      <xsd:enumeration value=\"pyraAcctTxMar\"/>\n      <xsd:enumeration value=\"txBlDir\"/>\n      <xsd:enumeration value=\"txAnchorHorz\"/>\n      <xsd:enumeration value=\"txAnchorVert\"/>\n      <xsd:enumeration value=\"txAnchorHorzCh\"/>\n      <xsd:enumeration value=\"txAnchorVertCh\"/>\n      <xsd:enumeration value=\"parTxLTRAlign\"/>\n      <xsd:enumeration value=\"parTxRTLAlign\"/>\n      <xsd:enumeration value=\"shpTxLTRAlignCh\"/>\n      <xsd:enumeration value=\"shpTxRTLAlignCh\"/>\n      <xsd:enumeration value=\"autoTxRot\"/>\n      <xsd:enumeration value=\"grDir\"/>\n      <xsd:enumeration value=\"flowDir\"/>\n      <xsd:enumeration value=\"contDir\"/>\n      <xsd:enumeration value=\"bkpt\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"hierAlign\"/>\n      <xsd:enumeration value=\"bkPtFixedVal\"/>\n      <xsd:enumeration value=\"stBulletLvl\"/>\n      <xsd:enumeration value=\"stAng\"/>\n      <xsd:enumeration value=\"spanAng\"/>\n      <xsd:enumeration value=\"ar\"/>\n      <xsd:enumeration value=\"lnSpPar\"/>\n      <xsd:enumeration value=\"lnSpAfParP\"/>\n      <xsd:enumeration value=\"lnSpCh\"/>\n      <xsd:enumeration value=\"lnSpAfChP\"/>\n      <xsd:enumeration value=\"rtShortDist\"/>\n      <xsd:enumeration value=\"alignTx\"/>\n      <xsd:enumeration value=\"pyraLvlNode\"/>\n      <xsd:enumeration value=\"pyraAcctBkgdNode\"/>\n      <xsd:enumeration value=\"pyraAcctTxNode\"/>\n      <xsd:enumeration value=\"srcNode\"/>\n      <xsd:enumeration value=\"dstNode\"/>\n      <xsd:enumeration value=\"begPts\"/>\n      <xsd:enumeration value=\"endPts\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ints\">\n    <xsd:list itemType=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedInts\">\n    <xsd:list itemType=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Booleans\">\n    <xsd:list itemType=\"xsd:boolean\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cnt\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"revPos\"/>\n      <xsd:enumeration value=\"posEven\"/>\n      <xsd:enumeration value=\"posOdd\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"depth\"/>\n      <xsd:enumeration value=\"maxDepth\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"neq\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryLinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StartingElement\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"trans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RotationPath\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alongPath\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CenterShapeMapping\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fNode\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BendPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"beg\"/>\n      <xsd:enumeration value=\"def\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorRouting\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"stra\"/>\n      <xsd:enumeration value=\"bend\"/>\n      <xsd:enumeration value=\"curve\"/>\n      <xsd:enumeration value=\"longCurve\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrowheadStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"arr\"/>\n      <xsd:enumeration value=\"noArr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"bCtr\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"midL\"/>\n      <xsd:enumeration value=\"midR\"/>\n      <xsd:enumeration value=\"tCtr\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"radial\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeVerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FallbackDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentPosition\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bef\"/>\n      <xsd:enumeration value=\"aft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentTextMargin\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"step\"/>\n      <xsd:enumeration value=\"stack\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBlockDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorHorizontal\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorVertical\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramTextAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AutoTextRotation\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"upr\"/>\n      <xsd:enumeration value=\"grav\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GrowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FlowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContinueDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"revDir\"/>\n      <xsd:enumeration value=\"sameDir\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Breakpoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"endCnv\"/>\n      <xsd:enumeration value=\"bal\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Offset\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierarchyAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"tCtrCh\"/>\n      <xsd:enumeration value=\"tCtrDes\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"bCtrCh\"/>\n      <xsd:enumeration value=\"bCtrDes\"/>\n      <xsd:enumeration value=\"lT\"/>\n      <xsd:enumeration value=\"lB\"/>\n      <xsd:enumeration value=\"lCtrCh\"/>\n      <xsd:enumeration value=\"lCtrDes\"/>\n      <xsd:enumeration value=\"rT\"/>\n      <xsd:enumeration value=\"rB\"/>\n      <xsd:enumeration value=\"rCtrCh\"/>\n      <xsd:enumeration value=\"rCtrDes\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionValue\" final=\"restriction\">\n    <xsd:union\n      memberTypes=\"xsd:int xsd:boolean ST_Direction ST_HierBranchStyle ST_AnimOneStr ST_AnimLvlStr ST_ResizeHandlesStr\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VariableType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"orgChart\"/>\n      <xsd:enumeration value=\"chMax\"/>\n      <xsd:enumeration value=\"chPref\"/>\n      <xsd:enumeration value=\"bulEnabled\"/>\n      <xsd:enumeration value=\"dir\"/>\n      <xsd:enumeration value=\"hierBranch\"/>\n      <xsd:enumeration value=\"animOne\"/>\n      <xsd:enumeration value=\"animLvl\"/>\n      <xsd:enumeration value=\"resizeHandles\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionArgument\" final=\"restriction\">\n    <xsd:union memberTypes=\"ST_VariableType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OutputShapeType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"conn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:element name=\"lockedCanvas\" type=\"a:CT_GvmlGroupShape\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n    schemaLocation=\"dml-diagram.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n    schemaLocation=\"dml-chart.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n    schemaLocation=\"dml-lockedCanvas.xsd\"/>\n  <xsd:complexType name=\"CT_AudioFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VideoFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QuickTimeFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCDTime\">\n    <xsd:attribute name=\"track\" type=\"xsd:unsignedByte\" use=\"required\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCD\">\n    <xsd:sequence>\n      <xsd:element name=\"st\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Media\">\n    <xsd:choice>\n      <xsd:element name=\"audioCd\" type=\"CT_AudioCD\"/>\n      <xsd:element name=\"wavAudioFile\" type=\"CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"audioFile\" type=\"CT_AudioFile\"/>\n      <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n      <xsd:element name=\"quickTimeFile\" type=\"CT_QuickTimeFile\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n  <xsd:simpleType name=\"ST_StyleMatrixColumnIndex\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontCollectionIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"dk1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dk2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent3\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent4\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent5\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent6\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"folHlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SupplementalFont\">\n    <xsd:attribute name=\"script\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColorList\">\n    <xsd:sequence>\n      <xsd:element name=\"custClr\" type=\"CT_CustomColor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontCollection\">\n    <xsd:sequence>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"font\" type=\"CT_SupplementalFont\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleItem\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"majorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LineStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"effectStyle\" type=\"CT_EffectStyleItem\" minOccurs=\"3\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrix\">\n    <xsd:sequence>\n      <xsd:element name=\"fillStyleLst\" type=\"CT_FillStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnStyleLst\" type=\"CT_LineStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectStyleLst\" type=\"CT_EffectStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgFillStyleLst\" type=\"CT_BackgroundFillStyleList\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeArtExtension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Coordinate\">\n    <xsd:union memberTypes=\"ST_CoordinateUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CoordinateUnqualified\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"-27273042329600\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32\">\n    <xsd:union memberTypes=\"ST_Coordinate32Unqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32Unqualified\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate32\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Angle\">\n    <xsd:attribute name=\"val\" type=\"ST_Angle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minExclusive value=\"-5400000\"/>\n      <xsd:maxExclusive value=\"5400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxExclusive value=\"21600000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedAngle\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:union memberTypes=\"ST_PercentageDecimal s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PercentageDecimal\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Percentage\">\n    <xsd:attribute name=\"val\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:union memberTypes=\"ST_PositivePercentageDecimal s:ST_PositivePercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositivePercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:union memberTypes=\"ST_FixedPercentageDecimal s:ST_FixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"-100000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:union memberTypes=\"ST_PositiveFixedPercentageDecimal s:ST_PositiveFixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ratio\">\n    <xsd:attribute name=\"n\" type=\"xsd:long\" use=\"required\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:long\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point2D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PositiveSize2D\">\n    <xsd:attribute name=\"cx\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ComplementTransform\"/>\n  <xsd:complexType name=\"CT_InverseTransform\"/>\n  <xsd:complexType name=\"CT_GrayscaleTransform\"/>\n  <xsd:complexType name=\"CT_GammaTransform\"/>\n  <xsd:complexType name=\"CT_InverseGammaTransform\"/>\n  <xsd:group name=\"EG_ColorTransform\">\n    <xsd:choice>\n      <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"comp\" type=\"CT_ComplementTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"inv\" type=\"CT_InverseTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gray\" type=\"CT_GrayscaleTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOff\" type=\"CT_FixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hue\" type=\"CT_PositiveFixedAngle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueOff\" type=\"CT_Angle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sat\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"red\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"green\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blue\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gamma\" type=\"CT_GammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invGamma\" type=\"CT_InverseGammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ScRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HslColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SystemColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"scrollBar\"/>\n      <xsd:enumeration value=\"background\"/>\n      <xsd:enumeration value=\"activeCaption\"/>\n      <xsd:enumeration value=\"inactiveCaption\"/>\n      <xsd:enumeration value=\"menu\"/>\n      <xsd:enumeration value=\"window\"/>\n      <xsd:enumeration value=\"windowFrame\"/>\n      <xsd:enumeration value=\"menuText\"/>\n      <xsd:enumeration value=\"windowText\"/>\n      <xsd:enumeration value=\"captionText\"/>\n      <xsd:enumeration value=\"activeBorder\"/>\n      <xsd:enumeration value=\"inactiveBorder\"/>\n      <xsd:enumeration value=\"appWorkspace\"/>\n      <xsd:enumeration value=\"highlight\"/>\n      <xsd:enumeration value=\"highlightText\"/>\n      <xsd:enumeration value=\"btnFace\"/>\n      <xsd:enumeration value=\"btnShadow\"/>\n      <xsd:enumeration value=\"grayText\"/>\n      <xsd:enumeration value=\"btnText\"/>\n      <xsd:enumeration value=\"inactiveCaptionText\"/>\n      <xsd:enumeration value=\"btnHighlight\"/>\n      <xsd:enumeration value=\"3dDkShadow\"/>\n      <xsd:enumeration value=\"3dLight\"/>\n      <xsd:enumeration value=\"infoText\"/>\n      <xsd:enumeration value=\"infoBk\"/>\n      <xsd:enumeration value=\"hotLight\"/>\n      <xsd:enumeration value=\"gradientActiveCaption\"/>\n      <xsd:enumeration value=\"gradientInactiveCaption\"/>\n      <xsd:enumeration value=\"menuHighlight\"/>\n      <xsd:enumeration value=\"menuBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SystemColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SystemColorVal\" use=\"required\"/>\n    <xsd:attribute name=\"lastClr\" type=\"s:ST_HexColorRGB\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SchemeColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bg1\"/>\n      <xsd:enumeration value=\"tx1\"/>\n      <xsd:enumeration value=\"bg2\"/>\n      <xsd:enumeration value=\"tx2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n      <xsd:enumeration value=\"phClr\"/>\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SchemeColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"aliceBlue\"/>\n      <xsd:enumeration value=\"antiqueWhite\"/>\n      <xsd:enumeration value=\"aqua\"/>\n      <xsd:enumeration value=\"aquamarine\"/>\n      <xsd:enumeration value=\"azure\"/>\n      <xsd:enumeration value=\"beige\"/>\n      <xsd:enumeration value=\"bisque\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blanchedAlmond\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"blueViolet\"/>\n      <xsd:enumeration value=\"brown\"/>\n      <xsd:enumeration value=\"burlyWood\"/>\n      <xsd:enumeration value=\"cadetBlue\"/>\n      <xsd:enumeration value=\"chartreuse\"/>\n      <xsd:enumeration value=\"chocolate\"/>\n      <xsd:enumeration value=\"coral\"/>\n      <xsd:enumeration value=\"cornflowerBlue\"/>\n      <xsd:enumeration value=\"cornsilk\"/>\n      <xsd:enumeration value=\"crimson\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGoldenrod\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"darkGrey\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkKhaki\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkOliveGreen\"/>\n      <xsd:enumeration value=\"darkOrange\"/>\n      <xsd:enumeration value=\"darkOrchid\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkSalmon\"/>\n      <xsd:enumeration value=\"darkSeaGreen\"/>\n      <xsd:enumeration value=\"darkSlateBlue\"/>\n      <xsd:enumeration value=\"darkSlateGray\"/>\n      <xsd:enumeration value=\"darkSlateGrey\"/>\n      <xsd:enumeration value=\"darkTurquoise\"/>\n      <xsd:enumeration value=\"darkViolet\"/>\n      <xsd:enumeration value=\"dkBlue\"/>\n      <xsd:enumeration value=\"dkCyan\"/>\n      <xsd:enumeration value=\"dkGoldenrod\"/>\n      <xsd:enumeration value=\"dkGray\"/>\n      <xsd:enumeration value=\"dkGrey\"/>\n      <xsd:enumeration value=\"dkGreen\"/>\n      <xsd:enumeration value=\"dkKhaki\"/>\n      <xsd:enumeration value=\"dkMagenta\"/>\n      <xsd:enumeration value=\"dkOliveGreen\"/>\n      <xsd:enumeration value=\"dkOrange\"/>\n      <xsd:enumeration value=\"dkOrchid\"/>\n      <xsd:enumeration value=\"dkRed\"/>\n      <xsd:enumeration value=\"dkSalmon\"/>\n      <xsd:enumeration value=\"dkSeaGreen\"/>\n      <xsd:enumeration value=\"dkSlateBlue\"/>\n      <xsd:enumeration value=\"dkSlateGray\"/>\n      <xsd:enumeration value=\"dkSlateGrey\"/>\n      <xsd:enumeration value=\"dkTurquoise\"/>\n      <xsd:enumeration value=\"dkViolet\"/>\n      <xsd:enumeration value=\"deepPink\"/>\n      <xsd:enumeration value=\"deepSkyBlue\"/>\n      <xsd:enumeration value=\"dimGray\"/>\n      <xsd:enumeration value=\"dimGrey\"/>\n      <xsd:enumeration value=\"dodgerBlue\"/>\n      <xsd:enumeration value=\"firebrick\"/>\n      <xsd:enumeration value=\"floralWhite\"/>\n      <xsd:enumeration value=\"forestGreen\"/>\n      <xsd:enumeration value=\"fuchsia\"/>\n      <xsd:enumeration value=\"gainsboro\"/>\n      <xsd:enumeration value=\"ghostWhite\"/>\n      <xsd:enumeration value=\"gold\"/>\n      <xsd:enumeration value=\"goldenrod\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"grey\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"greenYellow\"/>\n      <xsd:enumeration value=\"honeydew\"/>\n      <xsd:enumeration value=\"hotPink\"/>\n      <xsd:enumeration value=\"indianRed\"/>\n      <xsd:enumeration value=\"indigo\"/>\n      <xsd:enumeration value=\"ivory\"/>\n      <xsd:enumeration value=\"khaki\"/>\n      <xsd:enumeration value=\"lavender\"/>\n      <xsd:enumeration value=\"lavenderBlush\"/>\n      <xsd:enumeration value=\"lawnGreen\"/>\n      <xsd:enumeration value=\"lemonChiffon\"/>\n      <xsd:enumeration value=\"lightBlue\"/>\n      <xsd:enumeration value=\"lightCoral\"/>\n      <xsd:enumeration value=\"lightCyan\"/>\n      <xsd:enumeration value=\"lightGoldenrodYellow\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"lightGrey\"/>\n      <xsd:enumeration value=\"lightGreen\"/>\n      <xsd:enumeration value=\"lightPink\"/>\n      <xsd:enumeration value=\"lightSalmon\"/>\n      <xsd:enumeration value=\"lightSeaGreen\"/>\n      <xsd:enumeration value=\"lightSkyBlue\"/>\n      <xsd:enumeration value=\"lightSlateGray\"/>\n      <xsd:enumeration value=\"lightSlateGrey\"/>\n      <xsd:enumeration value=\"lightSteelBlue\"/>\n      <xsd:enumeration value=\"lightYellow\"/>\n      <xsd:enumeration value=\"ltBlue\"/>\n      <xsd:enumeration value=\"ltCoral\"/>\n      <xsd:enumeration value=\"ltCyan\"/>\n      <xsd:enumeration value=\"ltGoldenrodYellow\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"ltGrey\"/>\n      <xsd:enumeration value=\"ltGreen\"/>\n      <xsd:enumeration value=\"ltPink\"/>\n      <xsd:enumeration value=\"ltSalmon\"/>\n      <xsd:enumeration value=\"ltSeaGreen\"/>\n      <xsd:enumeration value=\"ltSkyBlue\"/>\n      <xsd:enumeration value=\"ltSlateGray\"/>\n      <xsd:enumeration value=\"ltSlateGrey\"/>\n      <xsd:enumeration value=\"ltSteelBlue\"/>\n      <xsd:enumeration value=\"ltYellow\"/>\n      <xsd:enumeration value=\"lime\"/>\n      <xsd:enumeration value=\"limeGreen\"/>\n      <xsd:enumeration value=\"linen\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"maroon\"/>\n      <xsd:enumeration value=\"medAquamarine\"/>\n      <xsd:enumeration value=\"medBlue\"/>\n      <xsd:enumeration value=\"medOrchid\"/>\n      <xsd:enumeration value=\"medPurple\"/>\n      <xsd:enumeration value=\"medSeaGreen\"/>\n      <xsd:enumeration value=\"medSlateBlue\"/>\n      <xsd:enumeration value=\"medSpringGreen\"/>\n      <xsd:enumeration value=\"medTurquoise\"/>\n      <xsd:enumeration value=\"medVioletRed\"/>\n      <xsd:enumeration value=\"mediumAquamarine\"/>\n      <xsd:enumeration value=\"mediumBlue\"/>\n      <xsd:enumeration value=\"mediumOrchid\"/>\n      <xsd:enumeration value=\"mediumPurple\"/>\n      <xsd:enumeration value=\"mediumSeaGreen\"/>\n      <xsd:enumeration value=\"mediumSlateBlue\"/>\n      <xsd:enumeration value=\"mediumSpringGreen\"/>\n      <xsd:enumeration value=\"mediumTurquoise\"/>\n      <xsd:enumeration value=\"mediumVioletRed\"/>\n      <xsd:enumeration value=\"midnightBlue\"/>\n      <xsd:enumeration value=\"mintCream\"/>\n      <xsd:enumeration value=\"mistyRose\"/>\n      <xsd:enumeration value=\"moccasin\"/>\n      <xsd:enumeration value=\"navajoWhite\"/>\n      <xsd:enumeration value=\"navy\"/>\n      <xsd:enumeration value=\"oldLace\"/>\n      <xsd:enumeration value=\"olive\"/>\n      <xsd:enumeration value=\"oliveDrab\"/>\n      <xsd:enumeration value=\"orange\"/>\n      <xsd:enumeration value=\"orangeRed\"/>\n      <xsd:enumeration value=\"orchid\"/>\n      <xsd:enumeration value=\"paleGoldenrod\"/>\n      <xsd:enumeration value=\"paleGreen\"/>\n      <xsd:enumeration value=\"paleTurquoise\"/>\n      <xsd:enumeration value=\"paleVioletRed\"/>\n      <xsd:enumeration value=\"papayaWhip\"/>\n      <xsd:enumeration value=\"peachPuff\"/>\n      <xsd:enumeration value=\"peru\"/>\n      <xsd:enumeration value=\"pink\"/>\n      <xsd:enumeration value=\"plum\"/>\n      <xsd:enumeration value=\"powderBlue\"/>\n      <xsd:enumeration value=\"purple\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"rosyBrown\"/>\n      <xsd:enumeration value=\"royalBlue\"/>\n      <xsd:enumeration value=\"saddleBrown\"/>\n      <xsd:enumeration value=\"salmon\"/>\n      <xsd:enumeration value=\"sandyBrown\"/>\n      <xsd:enumeration value=\"seaGreen\"/>\n      <xsd:enumeration value=\"seaShell\"/>\n      <xsd:enumeration value=\"sienna\"/>\n      <xsd:enumeration value=\"silver\"/>\n      <xsd:enumeration value=\"skyBlue\"/>\n      <xsd:enumeration value=\"slateBlue\"/>\n      <xsd:enumeration value=\"slateGray\"/>\n      <xsd:enumeration value=\"slateGrey\"/>\n      <xsd:enumeration value=\"snow\"/>\n      <xsd:enumeration value=\"springGreen\"/>\n      <xsd:enumeration value=\"steelBlue\"/>\n      <xsd:enumeration value=\"tan\"/>\n      <xsd:enumeration value=\"teal\"/>\n      <xsd:enumeration value=\"thistle\"/>\n      <xsd:enumeration value=\"tomato\"/>\n      <xsd:enumeration value=\"turquoise\"/>\n      <xsd:enumeration value=\"violet\"/>\n      <xsd:enumeration value=\"wheat\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"whiteSmoke\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"yellowGreen\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_PresetColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_OfficeArtExtension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OfficeArtExtensionList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scale2D\">\n    <xsd:sequence>\n      <xsd:element name=\"sx\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sy\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Transform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupTransform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chOff\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chExt\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point3D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vector3D\">\n    <xsd:attribute name=\"dx\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dy\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dz\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SphereCoords\">\n    <xsd:attribute name=\"lat\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"lon\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeRect\">\n    <xsd:attribute name=\"l\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"t\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RectAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:group name=\"EG_ColorChoice\">\n    <xsd:choice>\n      <xsd:element name=\"scrgbClr\" type=\"CT_ScRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hslClr\" type=\"CT_HslColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sysClr\" type=\"CT_SystemColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstClr\" type=\"CT_PresetColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMRU\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlackWhiteMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clr\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"invGray\"/>\n      <xsd:enumeration value=\"grayWhite\"/>\n      <xsd:enumeration value=\"blackGray\"/>\n      <xsd:enumeration value=\"blackWhite\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Blob\">\n    <xsd:attribute ref=\"r:embed\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:link\" use=\"optional\" default=\"\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_EmbeddedWAVAudioFile\">\n    <xsd:attribute ref=\"r:embed\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:sequence>\n      <xsd:element name=\"snd\" type=\"CT_EmbeddedWAVAudioFile\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalidUrl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"action\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tooltip\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"highlightClick\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"endSnd\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DrawingElementId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Locking\">\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noEditPoints\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noAdjustHandles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeArrowheads\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeShapeType\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_ConnectorLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noTextEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noCrop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noUngrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noDrilldown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ContentPartLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkHover\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"descr\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"spLocks\" type=\"CT_ShapeLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"txBox\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualConnectorProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cxnSpLocks\" type=\"CT_ConnectorLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualPictureProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"picLocks\" type=\"CT_PictureLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preferRelativeResize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGroupDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"grpSpLocks\" type=\"CT_GroupLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGraphicFrameProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicFrameLocks\" type=\"CT_GraphicalObjectFrameLocking\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualContentPartProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cpLocks\" type=\"CT_ContentPartLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isComment\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectData\">\n    <xsd:sequence>\n      <xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"strict\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObject\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicData\" type=\"CT_GraphicalObjectData\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"graphic\" type=\"CT_GraphicalObject\"/>\n  <xsd:simpleType name=\"ST_ChartBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"allPts\"/>\n      <xsd:enumeration value=\"gridLegend\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DgmBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"bg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmElement\">\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"optional\"\n      default=\"{00000000-0000-0000-0000-000000000000}\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_DgmBuildStep\" use=\"optional\" default=\"sp\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationChartElement\">\n    <xsd:attribute name=\"seriesIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"categoryIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_ChartBuildStep\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationElementChoice\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"dgm\" type=\"CT_AnimationDgmElement\"/>\n      <xsd:element name=\"chart\" type=\"CT_AnimationChartElement\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"lvlOne\"/>\n      <xsd:enumeration value=\"lvlAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationDgmOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationDgmBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationChartOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationChartBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationChartOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationChartBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationGraphicalObjectBuildProperties\">\n    <xsd:choice>\n      <xsd:element name=\"bldDgm\" type=\"CT_AnimationDgmBuildProperties\"/>\n      <xsd:element name=\"bldChart\" type=\"CT_AnimationChartBuildProperties\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFormatting\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WholeE2oFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlUseShapeRectangle\"/>\n  <xsd:complexType name=\"CT_GvmlTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"useSpRect\" type=\"CT_GvmlUseShapeRectangle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_GvmlShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_GvmlConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"CT_NonVisualPictureProperties\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPicture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_GvmlPictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GvmlGraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element ref=\"graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GvmlGroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\"/>\n        <xsd:element name=\"sp\" type=\"CT_GvmlShape\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_GvmlConnector\"/>\n        <xsd:element name=\"pic\" type=\"CT_GvmlPicture\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GvmlGraphicalObjectFrame\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GvmlGroupShape\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetCameraType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueTop\"/>\n      <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n      <xsd:enumeration value=\"legacyObliqueLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueFront\"/>\n      <xsd:enumeration value=\"legacyObliqueRight\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueBottom\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n      <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n      <xsd:enumeration value=\"orthographicFront\"/>\n      <xsd:enumeration value=\"isometricTopUp\"/>\n      <xsd:enumeration value=\"isometricTopDown\"/>\n      <xsd:enumeration value=\"isometricBottomUp\"/>\n      <xsd:enumeration value=\"isometricBottomDown\"/>\n      <xsd:enumeration value=\"isometricLeftUp\"/>\n      <xsd:enumeration value=\"isometricLeftDown\"/>\n      <xsd:enumeration value=\"isometricRightUp\"/>\n      <xsd:enumeration value=\"isometricRightDown\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n      <xsd:enumeration value=\"obliqueTopLeft\"/>\n      <xsd:enumeration value=\"obliqueTop\"/>\n      <xsd:enumeration value=\"obliqueTopRight\"/>\n      <xsd:enumeration value=\"obliqueLeft\"/>\n      <xsd:enumeration value=\"obliqueRight\"/>\n      <xsd:enumeration value=\"obliqueBottomLeft\"/>\n      <xsd:enumeration value=\"obliqueBottom\"/>\n      <xsd:enumeration value=\"obliqueBottomRight\"/>\n      <xsd:enumeration value=\"perspectiveFront\"/>\n      <xsd:enumeration value=\"perspectiveLeft\"/>\n      <xsd:enumeration value=\"perspectiveRight\"/>\n      <xsd:enumeration value=\"perspectiveAbove\"/>\n      <xsd:enumeration value=\"perspectiveBelow\"/>\n      <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveRelaxed\"/>\n      <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FOVAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"10800000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Camera\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetCameraType\" use=\"required\"/>\n    <xsd:attribute name=\"fov\" type=\"ST_FOVAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"zoom\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LightRigDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LightRigType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyFlat1\"/>\n      <xsd:enumeration value=\"legacyFlat2\"/>\n      <xsd:enumeration value=\"legacyFlat3\"/>\n      <xsd:enumeration value=\"legacyFlat4\"/>\n      <xsd:enumeration value=\"legacyNormal1\"/>\n      <xsd:enumeration value=\"legacyNormal2\"/>\n      <xsd:enumeration value=\"legacyNormal3\"/>\n      <xsd:enumeration value=\"legacyNormal4\"/>\n      <xsd:enumeration value=\"legacyHarsh1\"/>\n      <xsd:enumeration value=\"legacyHarsh2\"/>\n      <xsd:enumeration value=\"legacyHarsh3\"/>\n      <xsd:enumeration value=\"legacyHarsh4\"/>\n      <xsd:enumeration value=\"threePt\"/>\n      <xsd:enumeration value=\"balanced\"/>\n      <xsd:enumeration value=\"soft\"/>\n      <xsd:enumeration value=\"harsh\"/>\n      <xsd:enumeration value=\"flood\"/>\n      <xsd:enumeration value=\"contrasting\"/>\n      <xsd:enumeration value=\"morning\"/>\n      <xsd:enumeration value=\"sunrise\"/>\n      <xsd:enumeration value=\"sunset\"/>\n      <xsd:enumeration value=\"chilly\"/>\n      <xsd:enumeration value=\"freezing\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"twoPt\"/>\n      <xsd:enumeration value=\"glow\"/>\n      <xsd:enumeration value=\"brightRoom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LightRig\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scene3D\">\n    <xsd:sequence>\n      <xsd:element name=\"camera\" type=\"CT_Camera\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backdrop\" type=\"CT_Backdrop\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Backdrop\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_Point3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"norm\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"up\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BevelPresetType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relaxedInset\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"slope\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"softRound\"/>\n      <xsd:enumeration value=\"convex\"/>\n      <xsd:enumeration value=\"coolSlant\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"riblet\"/>\n      <xsd:enumeration value=\"hardEdge\"/>\n      <xsd:enumeration value=\"artDeco\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Bevel\">\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\" default=\"circle\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetMaterialType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyMatte\"/>\n      <xsd:enumeration value=\"legacyPlastic\"/>\n      <xsd:enumeration value=\"legacyMetal\"/>\n      <xsd:enumeration value=\"legacyWireframe\"/>\n      <xsd:enumeration value=\"matte\"/>\n      <xsd:enumeration value=\"plastic\"/>\n      <xsd:enumeration value=\"metal\"/>\n      <xsd:enumeration value=\"warmMatte\"/>\n      <xsd:enumeration value=\"translucentPowder\"/>\n      <xsd:enumeration value=\"powder\"/>\n      <xsd:enumeration value=\"dkEdge\"/>\n      <xsd:enumeration value=\"softEdge\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"softmetal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"extrusionH\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"contourW\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"\n      default=\"warmMatte\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FlatText\">\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Text3D\">\n    <xsd:choice>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"flatTx\" type=\"CT_FlatText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AlphaBiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaCeilingEffect\"/>\n  <xsd:complexType name=\"CT_AlphaFloorEffect\"/>\n  <xsd:complexType name=\"CT_AlphaInverseEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateFixedEffect\">\n    <xsd:attribute name=\"amt\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaOutsetEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaReplaceEffect\">\n    <xsd:attribute name=\"a\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlurEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"grow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorChangeEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"clrFrom\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrTo\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useA\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorReplaceEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DuotoneEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GrayscaleEffect\"/>\n  <xsd:complexType name=\"CT_HSLEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InnerShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LuminanceEffect\">\n    <xsd:attribute name=\"bright\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"contrast\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OuterShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetShadowVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shdw1\"/>\n      <xsd:enumeration value=\"shdw2\"/>\n      <xsd:enumeration value=\"shdw3\"/>\n      <xsd:enumeration value=\"shdw4\"/>\n      <xsd:enumeration value=\"shdw5\"/>\n      <xsd:enumeration value=\"shdw6\"/>\n      <xsd:enumeration value=\"shdw7\"/>\n      <xsd:enumeration value=\"shdw8\"/>\n      <xsd:enumeration value=\"shdw9\"/>\n      <xsd:enumeration value=\"shdw10\"/>\n      <xsd:enumeration value=\"shdw11\"/>\n      <xsd:enumeration value=\"shdw12\"/>\n      <xsd:enumeration value=\"shdw13\"/>\n      <xsd:enumeration value=\"shdw14\"/>\n      <xsd:enumeration value=\"shdw15\"/>\n      <xsd:enumeration value=\"shdw16\"/>\n      <xsd:enumeration value=\"shdw17\"/>\n      <xsd:enumeration value=\"shdw18\"/>\n      <xsd:enumeration value=\"shdw19\"/>\n      <xsd:enumeration value=\"shdw20\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetShadowVal\" use=\"required\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReflectionEffect\">\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"stA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"stPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fadeDir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"5400000\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeOffsetEffect\">\n    <xsd:attribute name=\"tx\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SoftEdgesEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TintEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"amt\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransformEffect\">\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NoFillProperties\"/>\n  <xsd:complexType name=\"CT_SolidColorFillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinearShadeProperties\">\n    <xsd:attribute name=\"ang\" type=\"ST_PositiveFixedAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"scaled\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PathShadeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shape\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PathShadeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShadeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"path\" type=\"CT_PathShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TileFlipMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n      <xsd:enumeration value=\"xy\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pos\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tileRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TileInfoProperties\">\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StretchInfoProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FillModeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"tile\" type=\"CT_TileInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stretch\" type=\"CT_StretchInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_BlipCompression\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"hqprint\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Blip\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Blob\"/>\n    <xsd:attribute name=\"cstate\" type=\"ST_BlipCompression\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlipFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srcRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillModeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetPatternVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"ltHorz\"/>\n      <xsd:enumeration value=\"ltVert\"/>\n      <xsd:enumeration value=\"dkHorz\"/>\n      <xsd:enumeration value=\"dkVert\"/>\n      <xsd:enumeration value=\"narHorz\"/>\n      <xsd:enumeration value=\"narVert\"/>\n      <xsd:enumeration value=\"dashHorz\"/>\n      <xsd:enumeration value=\"dashVert\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"dnDiag\"/>\n      <xsd:enumeration value=\"upDiag\"/>\n      <xsd:enumeration value=\"ltDnDiag\"/>\n      <xsd:enumeration value=\"ltUpDiag\"/>\n      <xsd:enumeration value=\"dkDnDiag\"/>\n      <xsd:enumeration value=\"dkUpDiag\"/>\n      <xsd:enumeration value=\"wdDnDiag\"/>\n      <xsd:enumeration value=\"wdUpDiag\"/>\n      <xsd:enumeration value=\"dashDnDiag\"/>\n      <xsd:enumeration value=\"dashUpDiag\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"smCheck\"/>\n      <xsd:enumeration value=\"lgCheck\"/>\n      <xsd:enumeration value=\"smGrid\"/>\n      <xsd:enumeration value=\"lgGrid\"/>\n      <xsd:enumeration value=\"dotGrid\"/>\n      <xsd:enumeration value=\"smConfetti\"/>\n      <xsd:enumeration value=\"lgConfetti\"/>\n      <xsd:enumeration value=\"horzBrick\"/>\n      <xsd:enumeration value=\"diagBrick\"/>\n      <xsd:enumeration value=\"solidDmnd\"/>\n      <xsd:enumeration value=\"openDmnd\"/>\n      <xsd:enumeration value=\"dotDmnd\"/>\n      <xsd:enumeration value=\"plaid\"/>\n      <xsd:enumeration value=\"sphere\"/>\n      <xsd:enumeration value=\"weave\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"shingle\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"trellis\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PatternFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetPatternVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupFillProperties\"/>\n  <xsd:group name=\"EG_FillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpFill\" type=\"CT_GroupFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlendMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"over\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"lighten\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FillOverlayEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectReference\">\n    <xsd:attribute name=\"ref\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Effect\">\n    <xsd:choice>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effect\" type=\"CT_EffectReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOutset\" type=\"CT_AlphaOutsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blend\" type=\"CT_BlendEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_FillEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"relOff\" type=\"CT_RelativeOffsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_TransformEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_EffectContainerType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sib\"/>\n      <xsd:enumeration value=\"tree\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EffectContainer\">\n    <xsd:group ref=\"EG_Effect\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"type\" type=\"ST_EffectContainerType\" use=\"optional\" default=\"sib\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlendEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectList\">\n    <xsd:sequence>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_EffectProperties\">\n    <xsd:choice>\n      <xsd:element name=\"effectLst\" type=\"CT_EffectList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectDag\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_EffectProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"blip\" type=\"CT_Blip\"/>\n  <xsd:simpleType name=\"ST_ShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineInv\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"rtTriangle\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"parallelogram\"/>\n      <xsd:enumeration value=\"trapezoid\"/>\n      <xsd:enumeration value=\"nonIsoscelesTrapezoid\"/>\n      <xsd:enumeration value=\"pentagon\"/>\n      <xsd:enumeration value=\"hexagon\"/>\n      <xsd:enumeration value=\"heptagon\"/>\n      <xsd:enumeration value=\"octagon\"/>\n      <xsd:enumeration value=\"decagon\"/>\n      <xsd:enumeration value=\"dodecagon\"/>\n      <xsd:enumeration value=\"star4\"/>\n      <xsd:enumeration value=\"star5\"/>\n      <xsd:enumeration value=\"star6\"/>\n      <xsd:enumeration value=\"star7\"/>\n      <xsd:enumeration value=\"star8\"/>\n      <xsd:enumeration value=\"star10\"/>\n      <xsd:enumeration value=\"star12\"/>\n      <xsd:enumeration value=\"star16\"/>\n      <xsd:enumeration value=\"star24\"/>\n      <xsd:enumeration value=\"star32\"/>\n      <xsd:enumeration value=\"roundRect\"/>\n      <xsd:enumeration value=\"round1Rect\"/>\n      <xsd:enumeration value=\"round2SameRect\"/>\n      <xsd:enumeration value=\"round2DiagRect\"/>\n      <xsd:enumeration value=\"snipRoundRect\"/>\n      <xsd:enumeration value=\"snip1Rect\"/>\n      <xsd:enumeration value=\"snip2SameRect\"/>\n      <xsd:enumeration value=\"snip2DiagRect\"/>\n      <xsd:enumeration value=\"plaque\"/>\n      <xsd:enumeration value=\"ellipse\"/>\n      <xsd:enumeration value=\"teardrop\"/>\n      <xsd:enumeration value=\"homePlate\"/>\n      <xsd:enumeration value=\"chevron\"/>\n      <xsd:enumeration value=\"pieWedge\"/>\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"blockArc\"/>\n      <xsd:enumeration value=\"donut\"/>\n      <xsd:enumeration value=\"noSmoking\"/>\n      <xsd:enumeration value=\"rightArrow\"/>\n      <xsd:enumeration value=\"leftArrow\"/>\n      <xsd:enumeration value=\"upArrow\"/>\n      <xsd:enumeration value=\"downArrow\"/>\n      <xsd:enumeration value=\"stripedRightArrow\"/>\n      <xsd:enumeration value=\"notchedRightArrow\"/>\n      <xsd:enumeration value=\"bentUpArrow\"/>\n      <xsd:enumeration value=\"leftRightArrow\"/>\n      <xsd:enumeration value=\"upDownArrow\"/>\n      <xsd:enumeration value=\"leftUpArrow\"/>\n      <xsd:enumeration value=\"leftRightUpArrow\"/>\n      <xsd:enumeration value=\"quadArrow\"/>\n      <xsd:enumeration value=\"leftArrowCallout\"/>\n      <xsd:enumeration value=\"rightArrowCallout\"/>\n      <xsd:enumeration value=\"upArrowCallout\"/>\n      <xsd:enumeration value=\"downArrowCallout\"/>\n      <xsd:enumeration value=\"leftRightArrowCallout\"/>\n      <xsd:enumeration value=\"upDownArrowCallout\"/>\n      <xsd:enumeration value=\"quadArrowCallout\"/>\n      <xsd:enumeration value=\"bentArrow\"/>\n      <xsd:enumeration value=\"uturnArrow\"/>\n      <xsd:enumeration value=\"circularArrow\"/>\n      <xsd:enumeration value=\"leftCircularArrow\"/>\n      <xsd:enumeration value=\"leftRightCircularArrow\"/>\n      <xsd:enumeration value=\"curvedRightArrow\"/>\n      <xsd:enumeration value=\"curvedLeftArrow\"/>\n      <xsd:enumeration value=\"curvedUpArrow\"/>\n      <xsd:enumeration value=\"curvedDownArrow\"/>\n      <xsd:enumeration value=\"swooshArrow\"/>\n      <xsd:enumeration value=\"cube\"/>\n      <xsd:enumeration value=\"can\"/>\n      <xsd:enumeration value=\"lightningBolt\"/>\n      <xsd:enumeration value=\"heart\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"moon\"/>\n      <xsd:enumeration value=\"smileyFace\"/>\n      <xsd:enumeration value=\"irregularSeal1\"/>\n      <xsd:enumeration value=\"irregularSeal2\"/>\n      <xsd:enumeration value=\"foldedCorner\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"halfFrame\"/>\n      <xsd:enumeration value=\"corner\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"chord\"/>\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"leftBracket\"/>\n      <xsd:enumeration value=\"rightBracket\"/>\n      <xsd:enumeration value=\"leftBrace\"/>\n      <xsd:enumeration value=\"rightBrace\"/>\n      <xsd:enumeration value=\"bracketPair\"/>\n      <xsd:enumeration value=\"bracePair\"/>\n      <xsd:enumeration value=\"straightConnector1\"/>\n      <xsd:enumeration value=\"bentConnector2\"/>\n      <xsd:enumeration value=\"bentConnector3\"/>\n      <xsd:enumeration value=\"bentConnector4\"/>\n      <xsd:enumeration value=\"bentConnector5\"/>\n      <xsd:enumeration value=\"curvedConnector2\"/>\n      <xsd:enumeration value=\"curvedConnector3\"/>\n      <xsd:enumeration value=\"curvedConnector4\"/>\n      <xsd:enumeration value=\"curvedConnector5\"/>\n      <xsd:enumeration value=\"callout1\"/>\n      <xsd:enumeration value=\"callout2\"/>\n      <xsd:enumeration value=\"callout3\"/>\n      <xsd:enumeration value=\"accentCallout1\"/>\n      <xsd:enumeration value=\"accentCallout2\"/>\n      <xsd:enumeration value=\"accentCallout3\"/>\n      <xsd:enumeration value=\"borderCallout1\"/>\n      <xsd:enumeration value=\"borderCallout2\"/>\n      <xsd:enumeration value=\"borderCallout3\"/>\n      <xsd:enumeration value=\"accentBorderCallout1\"/>\n      <xsd:enumeration value=\"accentBorderCallout2\"/>\n      <xsd:enumeration value=\"accentBorderCallout3\"/>\n      <xsd:enumeration value=\"wedgeRectCallout\"/>\n      <xsd:enumeration value=\"wedgeRoundRectCallout\"/>\n      <xsd:enumeration value=\"wedgeEllipseCallout\"/>\n      <xsd:enumeration value=\"cloudCallout\"/>\n      <xsd:enumeration value=\"cloud\"/>\n      <xsd:enumeration value=\"ribbon\"/>\n      <xsd:enumeration value=\"ribbon2\"/>\n      <xsd:enumeration value=\"ellipseRibbon\"/>\n      <xsd:enumeration value=\"ellipseRibbon2\"/>\n      <xsd:enumeration value=\"leftRightRibbon\"/>\n      <xsd:enumeration value=\"verticalScroll\"/>\n      <xsd:enumeration value=\"horizontalScroll\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"flowChartProcess\"/>\n      <xsd:enumeration value=\"flowChartDecision\"/>\n      <xsd:enumeration value=\"flowChartInputOutput\"/>\n      <xsd:enumeration value=\"flowChartPredefinedProcess\"/>\n      <xsd:enumeration value=\"flowChartInternalStorage\"/>\n      <xsd:enumeration value=\"flowChartDocument\"/>\n      <xsd:enumeration value=\"flowChartMultidocument\"/>\n      <xsd:enumeration value=\"flowChartTerminator\"/>\n      <xsd:enumeration value=\"flowChartPreparation\"/>\n      <xsd:enumeration value=\"flowChartManualInput\"/>\n      <xsd:enumeration value=\"flowChartManualOperation\"/>\n      <xsd:enumeration value=\"flowChartConnector\"/>\n      <xsd:enumeration value=\"flowChartPunchedCard\"/>\n      <xsd:enumeration value=\"flowChartPunchedTape\"/>\n      <xsd:enumeration value=\"flowChartSummingJunction\"/>\n      <xsd:enumeration value=\"flowChartOr\"/>\n      <xsd:enumeration value=\"flowChartCollate\"/>\n      <xsd:enumeration value=\"flowChartSort\"/>\n      <xsd:enumeration value=\"flowChartExtract\"/>\n      <xsd:enumeration value=\"flowChartMerge\"/>\n      <xsd:enumeration value=\"flowChartOfflineStorage\"/>\n      <xsd:enumeration value=\"flowChartOnlineStorage\"/>\n      <xsd:enumeration value=\"flowChartMagneticTape\"/>\n      <xsd:enumeration value=\"flowChartMagneticDisk\"/>\n      <xsd:enumeration value=\"flowChartMagneticDrum\"/>\n      <xsd:enumeration value=\"flowChartDisplay\"/>\n      <xsd:enumeration value=\"flowChartDelay\"/>\n      <xsd:enumeration value=\"flowChartAlternateProcess\"/>\n      <xsd:enumeration value=\"flowChartOffpageConnector\"/>\n      <xsd:enumeration value=\"actionButtonBlank\"/>\n      <xsd:enumeration value=\"actionButtonHome\"/>\n      <xsd:enumeration value=\"actionButtonHelp\"/>\n      <xsd:enumeration value=\"actionButtonInformation\"/>\n      <xsd:enumeration value=\"actionButtonForwardNext\"/>\n      <xsd:enumeration value=\"actionButtonBackPrevious\"/>\n      <xsd:enumeration value=\"actionButtonEnd\"/>\n      <xsd:enumeration value=\"actionButtonBeginning\"/>\n      <xsd:enumeration value=\"actionButtonReturn\"/>\n      <xsd:enumeration value=\"actionButtonDocument\"/>\n      <xsd:enumeration value=\"actionButtonSound\"/>\n      <xsd:enumeration value=\"actionButtonMovie\"/>\n      <xsd:enumeration value=\"gear6\"/>\n      <xsd:enumeration value=\"gear9\"/>\n      <xsd:enumeration value=\"funnel\"/>\n      <xsd:enumeration value=\"mathPlus\"/>\n      <xsd:enumeration value=\"mathMinus\"/>\n      <xsd:enumeration value=\"mathMultiply\"/>\n      <xsd:enumeration value=\"mathDivide\"/>\n      <xsd:enumeration value=\"mathEqual\"/>\n      <xsd:enumeration value=\"mathNotEqual\"/>\n      <xsd:enumeration value=\"cornerTabs\"/>\n      <xsd:enumeration value=\"squareTabs\"/>\n      <xsd:enumeration value=\"plaqueTabs\"/>\n      <xsd:enumeration value=\"chartX\"/>\n      <xsd:enumeration value=\"chartStar\"/>\n      <xsd:enumeration value=\"chartPlus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"textNoShape\"/>\n      <xsd:enumeration value=\"textPlain\"/>\n      <xsd:enumeration value=\"textStop\"/>\n      <xsd:enumeration value=\"textTriangle\"/>\n      <xsd:enumeration value=\"textTriangleInverted\"/>\n      <xsd:enumeration value=\"textChevron\"/>\n      <xsd:enumeration value=\"textChevronInverted\"/>\n      <xsd:enumeration value=\"textRingInside\"/>\n      <xsd:enumeration value=\"textRingOutside\"/>\n      <xsd:enumeration value=\"textArchUp\"/>\n      <xsd:enumeration value=\"textArchDown\"/>\n      <xsd:enumeration value=\"textCircle\"/>\n      <xsd:enumeration value=\"textButton\"/>\n      <xsd:enumeration value=\"textArchUpPour\"/>\n      <xsd:enumeration value=\"textArchDownPour\"/>\n      <xsd:enumeration value=\"textCirclePour\"/>\n      <xsd:enumeration value=\"textButtonPour\"/>\n      <xsd:enumeration value=\"textCurveUp\"/>\n      <xsd:enumeration value=\"textCurveDown\"/>\n      <xsd:enumeration value=\"textCanUp\"/>\n      <xsd:enumeration value=\"textCanDown\"/>\n      <xsd:enumeration value=\"textWave1\"/>\n      <xsd:enumeration value=\"textWave2\"/>\n      <xsd:enumeration value=\"textDoubleWave1\"/>\n      <xsd:enumeration value=\"textWave4\"/>\n      <xsd:enumeration value=\"textInflate\"/>\n      <xsd:enumeration value=\"textDeflate\"/>\n      <xsd:enumeration value=\"textInflateBottom\"/>\n      <xsd:enumeration value=\"textDeflateBottom\"/>\n      <xsd:enumeration value=\"textInflateTop\"/>\n      <xsd:enumeration value=\"textDeflateTop\"/>\n      <xsd:enumeration value=\"textDeflateInflate\"/>\n      <xsd:enumeration value=\"textDeflateInflateDeflate\"/>\n      <xsd:enumeration value=\"textFadeRight\"/>\n      <xsd:enumeration value=\"textFadeLeft\"/>\n      <xsd:enumeration value=\"textFadeUp\"/>\n      <xsd:enumeration value=\"textFadeDown\"/>\n      <xsd:enumeration value=\"textSlantUp\"/>\n      <xsd:enumeration value=\"textSlantDown\"/>\n      <xsd:enumeration value=\"textCascadeUp\"/>\n      <xsd:enumeration value=\"textCascadeDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideName\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideFormula\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GeomGuide\">\n    <xsd:attribute name=\"name\" type=\"ST_GeomGuideName\" use=\"required\"/>\n    <xsd:attribute name=\"fmla\" type=\"ST_GeomGuideFormula\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomGuideList\">\n    <xsd:sequence>\n      <xsd:element name=\"gd\" type=\"CT_GeomGuide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AdjCoordinate\">\n    <xsd:union memberTypes=\"ST_Coordinate ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AdjAngle\">\n    <xsd:union memberTypes=\"ST_Angle ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AdjPoint2D\">\n    <xsd:attribute name=\"x\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomRect\">\n    <xsd:attribute name=\"l\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XYAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefX\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefY\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolarAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefR\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefAng\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"maxAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSite\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ang\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjustHandleList\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"ahXY\" type=\"CT_XYAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahPolar\" type=\"CT_PolarAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSiteList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_ConnectionSite\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DMoveTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DLineTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DArcTo\">\n    <xsd:attribute name=\"wR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"hR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"stAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n    <xsd:attribute name=\"swAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DQuadBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DCubicBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"3\" maxOccurs=\"3\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DClose\"/>\n  <xsd:simpleType name=\"ST_PathFillMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"lighten\"/>\n      <xsd:enumeration value=\"lightenLess\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"darkenLess\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Path2D\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"close\" type=\"CT_Path2DClose\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_Path2DMoveTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTo\" type=\"CT_Path2DLineTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"arcTo\" type=\"CT_Path2DArcTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"quadBezTo\" type=\"CT_Path2DQuadBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cubicBezTo\" type=\"CT_Path2DCubicBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_PathFillMode\" use=\"optional\" default=\"norm\"/>\n    <xsd:attribute name=\"stroke\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"extrusionOk\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DList\">\n    <xsd:sequence>\n      <xsd:element name=\"path\" type=\"CT_Path2D\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_ShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_TextShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gdLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahLst\" type=\"CT_AdjustHandleList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_ConnectionSiteList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rect\" type=\"CT_GeomRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pathLst\" type=\"CT_Path2DList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Geometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstGeom\" type=\"CT_PresetGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextGeometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineEndType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"stealth\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"arrow\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndWidth\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndLength\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineEndProperties\">\n    <xsd:attribute name=\"type\" type=\"ST_LineEndType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"w\" type=\"ST_LineEndWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"len\" type=\"ST_LineEndLength\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineFillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineJoinBevel\"/>\n  <xsd:complexType name=\"CT_LineJoinRound\"/>\n  <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n    <xsd:attribute name=\"lim\" type=\"ST_PositivePercentage\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineJoinProperties\">\n    <xsd:choice>\n      <xsd:element name=\"round\" type=\"CT_LineJoinRound\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevel\" type=\"CT_LineJoinBevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PresetLineDashVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"lgDash\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"lgDashDot\"/>\n      <xsd:enumeration value=\"lgDashDotDot\"/>\n      <xsd:enumeration value=\"sysDash\"/>\n      <xsd:enumeration value=\"sysDot\"/>\n      <xsd:enumeration value=\"sysDashDot\"/>\n      <xsd:enumeration value=\"sysDashDotDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetLineDashProperties\">\n    <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStop\">\n    <xsd:attribute name=\"d\" type=\"ST_PositivePercentage\" use=\"required\"/>\n    <xsd:attribute name=\"sp\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"ds\" type=\"CT_DashStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineDashProperties\">\n    <xsd:choice>\n      <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDash\" type=\"CT_DashStopList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineCap\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rnd\"/>\n      <xsd:enumeration value=\"sq\"/>\n      <xsd:enumeration value=\"flat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineWidth\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"20116800\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PenAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CompoundLine\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"tri\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineFillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tailEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_LineWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_LineCap\" use=\"optional\"/>\n    <xsd:attribute name=\"cmpd\" type=\"ST_CompoundLine\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_PenAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShapeID\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Geometry\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_GroupTransform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrixReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_StyleMatrixColumnIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_FontCollectionIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefaultShapeDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectStyleDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"spDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_ColorMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bg1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"hlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"folHlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMappingOverride\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"masterClrMapping\" type=\"CT_EmptyElement\"/>\n        <xsd:element name=\"overrideClrMapping\" type=\"CT_ColorMapping\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeAndMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeList\">\n    <xsd:sequence>\n      <xsd:element name=\"extraClrScheme\" type=\"CT_ColorSchemeAndMapping\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"objectDefaults\" type=\"CT_ObjectStyleDefaults\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extraClrSchemeLst\" type=\"CT_ColorSchemeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custClrLst\" type=\"CT_CustomColorList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStylesOverride\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipboardStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"theme\" type=\"CT_OfficeStyleSheet\"/>\n  <xsd:element name=\"themeOverride\" type=\"CT_BaseStylesOverride\"/>\n  <xsd:element name=\"themeManager\" type=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_TableCellProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnL\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnR\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnT\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnB\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTlToBr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnBlToTr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marT\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"marB\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\" default=\"t\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\" default=\"clip\"\n    />\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"xsd:string\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCol\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableGrid\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TableCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCell\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TableCellProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rowSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"gridSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"hMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableRow\">\n    <xsd:sequence>\n      <xsd:element name=\"tc\" type=\"CT_TableCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"h\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\"/>\n        <xsd:element name=\"tableStyleId\" type=\"s:ST_Guid\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPr\" type=\"CT_TableProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TableGrid\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr\" type=\"CT_TableRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tbl\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Cell3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevel\" type=\"CT_Bevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\" default=\"plastic\"\n    />\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableFillStyle\">\n    <xsd:choice>\n      <xsd:element name=\"fill\" type=\"CT_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ThemeableLineStyle\">\n    <xsd:choice>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableEffectStyle\">\n    <xsd:choice>\n      <xsd:element name=\"effect\" type=\"CT_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ThemeableFontStyles\">\n    <xsd:choice>\n      <xsd:element name=\"font\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_OnOffStyleType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"def\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleTextStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFontStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"b\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n    <xsd:attribute name=\"i\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCellBorderStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"left\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideH\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideV\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableBackgroundStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableEffectStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleCellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcBdr\" type=\"CT_TableCellBorderStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePartStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcTxStyle\" type=\"CT_TableStyleTextStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcStyle\" type=\"CT_TableStyleCellStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tblBg\" type=\"CT_TableBackgroundStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wholeTbl\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"seCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"swCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"neCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nwCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"styleName\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"def\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"tblStyleLst\" type=\"CT_TableStyleList\"/>\n  <xsd:complexType name=\"CT_TextParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"endParaRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAnchoringType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"dist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVertOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"ellipsis\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextHorzOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVerticalType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"vert270\"/>\n      <xsd:enumeration value=\"wordArtVert\"/>\n      <xsd:enumeration value=\"eaVert\"/>\n      <xsd:enumeration value=\"mongolianVert\"/>\n      <xsd:enumeration value=\"wordArtVertRtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextWrappingType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"square\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextColumnCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"16\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextListStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"defPPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl1pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl2pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl3pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl4pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl5pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl6pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl7pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl8pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl9pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextFontScalePercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextFontScalePercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontScalePercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"1000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextNormalAutofit\">\n    <xsd:attribute name=\"fontScale\" type=\"ST_TextFontScalePercentOrPercentString\" use=\"optional\"\n      default=\"100%\"/>\n    <xsd:attribute name=\"lnSpcReduction\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"optional\"\n      default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextShapeAutofit\"/>\n  <xsd:complexType name=\"CT_TextNoAutofit\"/>\n  <xsd:group name=\"EG_TextAutofit\">\n    <xsd:choice>\n      <xsd:element name=\"noAutofit\" type=\"CT_TextNoAutofit\"/>\n      <xsd:element name=\"normAutofit\" type=\"CT_TextNormalAutofit\"/>\n      <xsd:element name=\"spAutoFit\" type=\"CT_TextShapeAutofit\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBodyProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextAutofit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"spcFirstLastPara\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"vertOverflow\" type=\"ST_TextVertOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_TextWrappingType\" use=\"optional\"/>\n    <xsd:attribute name=\"lIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"tIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"bIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"numCol\" type=\"ST_TextColumnCount\" use=\"optional\"/>\n    <xsd:attribute name=\"spcCol\" type=\"ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtlCol\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fromWordArt\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"forceAA\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"upright\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatLnSpc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBody\">\n    <xsd:sequence>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"p\" type=\"CT_TextParagraph\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextBulletStartAtNum\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"32767\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAutonumberScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"alphaLcParenBoth\"/>\n      <xsd:enumeration value=\"alphaUcParenBoth\"/>\n      <xsd:enumeration value=\"alphaLcParenR\"/>\n      <xsd:enumeration value=\"alphaUcParenR\"/>\n      <xsd:enumeration value=\"alphaLcPeriod\"/>\n      <xsd:enumeration value=\"alphaUcPeriod\"/>\n      <xsd:enumeration value=\"arabicParenBoth\"/>\n      <xsd:enumeration value=\"arabicParenR\"/>\n      <xsd:enumeration value=\"arabicPeriod\"/>\n      <xsd:enumeration value=\"arabicPlain\"/>\n      <xsd:enumeration value=\"romanLcParenBoth\"/>\n      <xsd:enumeration value=\"romanUcParenBoth\"/>\n      <xsd:enumeration value=\"romanLcParenR\"/>\n      <xsd:enumeration value=\"romanUcParenR\"/>\n      <xsd:enumeration value=\"romanLcPeriod\"/>\n      <xsd:enumeration value=\"romanUcPeriod\"/>\n      <xsd:enumeration value=\"circleNumDbPlain\"/>\n      <xsd:enumeration value=\"circleNumWdBlackPlain\"/>\n      <xsd:enumeration value=\"circleNumWdWhitePlain\"/>\n      <xsd:enumeration value=\"arabicDbPeriod\"/>\n      <xsd:enumeration value=\"arabicDbPlain\"/>\n      <xsd:enumeration value=\"ea1ChsPeriod\"/>\n      <xsd:enumeration value=\"ea1ChsPlain\"/>\n      <xsd:enumeration value=\"ea1ChtPeriod\"/>\n      <xsd:enumeration value=\"ea1ChtPlain\"/>\n      <xsd:enumeration value=\"ea1JpnChsDbPeriod\"/>\n      <xsd:enumeration value=\"ea1JpnKorPlain\"/>\n      <xsd:enumeration value=\"ea1JpnKorPeriod\"/>\n      <xsd:enumeration value=\"arabic1Minus\"/>\n      <xsd:enumeration value=\"arabic2Minus\"/>\n      <xsd:enumeration value=\"hebrew2Minus\"/>\n      <xsd:enumeration value=\"thaiAlphaPeriod\"/>\n      <xsd:enumeration value=\"thaiAlphaParenR\"/>\n      <xsd:enumeration value=\"thaiAlphaParenBoth\"/>\n      <xsd:enumeration value=\"thaiNumPeriod\"/>\n      <xsd:enumeration value=\"thaiNumParenR\"/>\n      <xsd:enumeration value=\"thaiNumParenBoth\"/>\n      <xsd:enumeration value=\"hindiAlphaPeriod\"/>\n      <xsd:enumeration value=\"hindiNumPeriod\"/>\n      <xsd:enumeration value=\"hindiNumParenR\"/>\n      <xsd:enumeration value=\"hindiAlpha1Period\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletColorFollowText\"/>\n  <xsd:group name=\"EG_TextBulletColor\">\n    <xsd:choice>\n      <xsd:element name=\"buClrTx\" type=\"CT_TextBulletColorFollowText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"buClr\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextBulletSize\">\n    <xsd:union memberTypes=\"ST_TextBulletSizePercent ST_TextBulletSizeDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*((2[5-9])|([3-9][0-9])|([1-3][0-9][0-9])|400)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizeDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"25000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletSizeFollowText\"/>\n  <xsd:complexType name=\"CT_TextBulletSizePercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextBulletSizePercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBulletSizePoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextFontSize\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextBulletSize\">\n    <xsd:choice>\n      <xsd:element name=\"buSzTx\" type=\"CT_TextBulletSizeFollowText\"/>\n      <xsd:element name=\"buSzPct\" type=\"CT_TextBulletSizePercent\"/>\n      <xsd:element name=\"buSzPts\" type=\"CT_TextBulletSizePoint\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBulletTypefaceFollowText\"/>\n  <xsd:group name=\"EG_TextBulletTypeface\">\n    <xsd:choice>\n      <xsd:element name=\"buFontTx\" type=\"CT_TextBulletTypefaceFollowText\"/>\n      <xsd:element name=\"buFont\" type=\"CT_TextFont\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextAutonumberBullet\">\n    <xsd:attribute name=\"type\" type=\"ST_TextAutonumberScheme\" use=\"required\"/>\n    <xsd:attribute name=\"startAt\" type=\"ST_TextBulletStartAtNum\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextCharBullet\">\n    <xsd:attribute name=\"char\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBlipBullet\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextNoBullet\"/>\n  <xsd:group name=\"EG_TextBullet\">\n    <xsd:choice>\n      <xsd:element name=\"buNone\" type=\"CT_TextNoBullet\"/>\n      <xsd:element name=\"buAutoNum\" type=\"CT_TextAutonumberBullet\"/>\n      <xsd:element name=\"buChar\" type=\"CT_TextCharBullet\"/>\n      <xsd:element name=\"buBlip\" type=\"CT_TextBlipBullet\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextPoint\">\n    <xsd:union memberTypes=\"ST_TextPointUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextPointUnqualified\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-400000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextNonNegativePoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontSize\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"100\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTypeface\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PitchFamily\">\n   <xsd:restriction base=\"xsd:byte\">\n     <xsd:enumeration value=\"00\"/>\n     <xsd:enumeration value=\"01\"/>\n     <xsd:enumeration value=\"02\"/>\n     <xsd:enumeration value=\"16\"/>\n     <xsd:enumeration value=\"17\"/>\n     <xsd:enumeration value=\"18\"/>\n     <xsd:enumeration value=\"32\"/>\n     <xsd:enumeration value=\"33\"/>\n     <xsd:enumeration value=\"34\"/>\n     <xsd:enumeration value=\"48\"/>\n     <xsd:enumeration value=\"49\"/>\n     <xsd:enumeration value=\"50\"/>\n     <xsd:enumeration value=\"64\"/>\n     <xsd:enumeration value=\"65\"/>\n     <xsd:enumeration value=\"66\"/>\n     <xsd:enumeration value=\"80\"/>\n     <xsd:enumeration value=\"81\"/>\n     <xsd:enumeration value=\"82\"/>\n   </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_TextFont\">\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n    <xsd:attribute name=\"panose\" type=\"s:ST_Panose\" use=\"optional\"/>\n    <xsd:attribute name=\"pitchFamily\" type=\"ST_PitchFamily\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"charset\" type=\"xsd:byte\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextUnderlineType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDashHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dotDotDashHeavy\"/>\n      <xsd:enumeration value=\"wavy\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDbl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextUnderlineLineFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillGroupWrapper\">\n    <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextUnderlineLine\">\n    <xsd:choice>\n      <xsd:element name=\"uLnTx\" type=\"CT_TextUnderlineLineFollowText\"/>\n      <xsd:element name=\"uLn\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextUnderlineFill\">\n    <xsd:choice>\n      <xsd:element name=\"uFillTx\" type=\"CT_TextUnderlineFillFollowText\"/>\n      <xsd:element name=\"uFill\" type=\"CT_TextUnderlineFillGroupWrapper\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextStrikeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"noStrike\"/>\n      <xsd:enumeration value=\"sngStrike\"/>\n      <xsd:enumeration value=\"dblStrike\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextCapsType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"small\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextCharacterProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineLine\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sym\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkMouseOver\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rtl\" type=\"CT_Boolean\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"kumimoji\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"altLang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_TextFontSize\" use=\"optional\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"u\" type=\"ST_TextUnderlineType\" use=\"optional\"/>\n    <xsd:attribute name=\"strike\" type=\"ST_TextStrikeType\" use=\"optional\"/>\n    <xsd:attribute name=\"kern\" type=\"ST_TextNonNegativePoint\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_TextCapsType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"spc\" type=\"ST_TextPoint\" use=\"optional\"/>\n    <xsd:attribute name=\"normalizeH\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"baseline\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"noProof\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"dirty\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"err\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"smtClean\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"smtId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bmk\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextSpacingPoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"158400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextSpacingPercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"13200000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextSpacingPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacingPoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPoint\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextMargin\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndent\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"-51206400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTabAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"dec\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextTabStop\">\n    <xsd:attribute name=\"pos\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextTabAlignType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextTabStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TextTabStop\" minOccurs=\"0\" maxOccurs=\"32\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLineBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacing\">\n    <xsd:choice>\n      <xsd:element name=\"spcPct\" type=\"CT_TextSpacingPercent\"/>\n      <xsd:element name=\"spcPts\" type=\"CT_TextSpacingPoint\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"justLow\"/>\n      <xsd:enumeration value=\"dist\"/>\n      <xsd:enumeration value=\"thaiDist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndentLevelType\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"8\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextParagraphProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnSpc\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcBef\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcAft\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletColor\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletTypeface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBullet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tabLst\" type=\"CT_TextTabStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"defRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"lvl\" type=\"ST_TextIndentLevelType\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"ST_TextIndent\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"defTabSz\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"eaLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fontAlgn\" type=\"ST_TextFontAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"latinLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingPunct\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextRun\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_RegularTextRun\"/>\n      <xsd:element name=\"br\" type=\"CT_TextLineBreak\"/>\n      <xsd:element name=\"fld\" type=\"CT_TextField\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RegularTextRun\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"shared-relationshipReference.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>\n  <xsd:element name=\"from\" type=\"CT_Marker\"/>\n  <xsd:element name=\"to\" type=\"CT_Marker\"/>\n  <xsd:complexType name=\"CT_AnchorClientData\">\n    <xsd:attribute name=\"fLocksWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPrintsWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ColID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RowID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"ST_ColID\"/>\n      <xsd:element name=\"colOff\" type=\"a:ST_Coordinate\"/>\n      <xsd:element name=\"row\" type=\"ST_RowID\"/>\n      <xsd:element name=\"rowOff\" type=\"a:ST_Coordinate\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"twoCell\"/>\n      <xsd:enumeration value=\"oneCell\"/>\n      <xsd:enumeration value=\"absolute\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TwoCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"editAs\" type=\"ST_EditAs\" use=\"optional\" default=\"twoCell\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OneCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsoluteAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"twoCellAnchor\" type=\"CT_TwoCellAnchor\"/>\n      <xsd:element name=\"oneCellAnchor\" type=\"CT_OneCellAnchor\"/>\n      <xsd:element name=\"absoluteAnchor\" type=\"CT_AbsoluteAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wsDr\" type=\"CT_Drawing\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:dpct=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"wml.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:complexType name=\"CT_EffectExtent\">\n    <xsd:attribute name=\"l\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapDistance\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Inline\">\n    <xsd:sequence>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapText\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bothSides\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WrapPath\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lineTo\" type=\"a:CT_Point2D\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"edited\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapNone\"/>\n  <xsd:complexType name=\"CT_WrapSquare\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTight\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapThrough\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTopBottom\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_WrapType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"wrapNone\" type=\"CT_WrapNone\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapSquare\" type=\"CT_WrapSquare\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTight\" type=\"CT_WrapTight\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapThrough\" type=\"CT_WrapThrough\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTopAndBottom\" type=\"CT_WrapTopBottom\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PositionOffset\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlignH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"leftMargin\"/>\n      <xsd:enumeration value=\"rightMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosH\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignH\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromH\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlignV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"topMargin\"/>\n      <xsd:enumeration value=\"bottomMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosV\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignV\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromV\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Anchor\">\n    <xsd:sequence>\n      <xsd:element name=\"simplePos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"positionH\" type=\"CT_PosH\"/>\n      <xsd:element name=\"positionV\" type=\"CT_PosV\"/>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_WrapType\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"simplePos\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"relativeHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"behindDoc\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"layoutInCell\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"allowOverlap\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"w:EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextboxInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinkedTextboxInformation\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"seq\" type=\"xsd:unsignedShort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingShape\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"cNvCnPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"txbx\" type=\"CT_TextboxInfo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"linkedTxbx\" type=\"CT_LinkedTextboxInformation\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"bodyPr\" type=\"a:CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"normalEastAsianFlow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvFrPr\" type=\"a:CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPartNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvContentPartPr\" type=\"a:CT_NonVisualContentPartProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPart\">\n    <xsd:sequence>\n      <xsd:element name=\"nvContentPartPr\" type=\"CT_WordprocessingContentPartNonVisual\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingGroup\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_WordprocessingGroup\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingCanvas\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n        <xsd:element ref=\"wgp\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wpc\" type=\"CT_WordprocessingCanvas\"/>\n  <xsd:element name=\"wgp\" type=\"CT_WordprocessingGroup\"/>\n  <xsd:element name=\"wsp\" type=\"CT_WordprocessingShape\"/>\n  <xsd:element name=\"inline\" type=\"CT_Inline\"/>\n  <xsd:element name=\"anchor\" type=\"CT_Anchor\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_TransitionSideDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"d\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionCornerDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"lu\"/>\n      <xsd:enumeration value=\"ru\"/>\n      <xsd:enumeration value=\"ld\"/>\n      <xsd:enumeration value=\"rd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionInOutDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SideDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionSideDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CornerDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionCornerDirectionType\" use=\"optional\" default=\"lu\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionEightDirectionType\">\n    <xsd:union memberTypes=\"ST_TransitionSideDirectionType ST_TransitionCornerDirectionType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EightDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionEightDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OrientationTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InOutTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptionalBlackTransition\">\n    <xsd:attribute name=\"thruBlk\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SplitTransition\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WheelTransition\">\n    <xsd:attribute name=\"spokes\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"4\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionStartSoundAction\">\n    <xsd:sequence>\n      <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"snd\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionSoundAction\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"stSnd\" type=\"CT_TransitionStartSoundAction\"/>\n      <xsd:element name=\"endSnd\" type=\"CT_Empty\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionSpeed\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slow\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"fast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideTransition\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"blinds\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"checker\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"circle\" type=\"CT_Empty\"/>\n        <xsd:element name=\"dissolve\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comb\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"cover\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"cut\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"diamond\" type=\"CT_Empty\"/>\n        <xsd:element name=\"fade\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"newsflash\" type=\"CT_Empty\"/>\n        <xsd:element name=\"plus\" type=\"CT_Empty\"/>\n        <xsd:element name=\"pull\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"push\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"random\" type=\"CT_Empty\"/>\n        <xsd:element name=\"randomBar\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"split\" type=\"CT_SplitTransition\"/>\n        <xsd:element name=\"strips\" type=\"CT_CornerDirectionTransition\"/>\n        <xsd:element name=\"wedge\" type=\"CT_Empty\"/>\n        <xsd:element name=\"wheel\" type=\"CT_WheelTransition\"/>\n        <xsd:element name=\"wipe\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"zoom\" type=\"CT_InOutTransition\"/>\n      </xsd:choice>\n      <xsd:element name=\"sndAc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TransitionSoundAction\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"spd\" type=\"ST_TransitionSpeed\" use=\"optional\" default=\"fast\"/>\n    <xsd:attribute name=\"advClick\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"advTm\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeIndefinite\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"indefinite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTime\">\n    <xsd:union memberTypes=\"xsd:unsignedInt ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeID\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateIntervalTime\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLIterateIntervalPercentage\">\n    <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_IterateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"el\"/>\n      <xsd:enumeration value=\"wd\"/>\n      <xsd:enumeration value=\"lt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateData\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"tmAbs\" type=\"CT_TLIterateIntervalTime\"/>\n      <xsd:element name=\"tmPct\" type=\"CT_TLIterateIntervalPercentage\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_IterateType\" use=\"optional\" default=\"el\"/>\n    <xsd:attribute name=\"backwards\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSubShapeId\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTextTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"charRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"pRg\" type=\"CT_IndexRange\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLChartSubelementType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"gridLegend\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleChartTargetElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TLChartSubelementType\" use=\"required\"/>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLShapeTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"CT_Empty\"/>\n      <xsd:element name=\"subSp\" type=\"CT_TLSubShapeId\"/>\n      <xsd:element name=\"oleChartEl\" type=\"CT_TLOleChartTargetElement\"/>\n      <xsd:element name=\"txEl\" type=\"CT_TLTextTargetElement\"/>\n      <xsd:element name=\"graphicEl\" type=\"a:CT_AnimationElementChoice\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeTargetElement\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"sldTgt\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sndTgt\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"spTgt\" type=\"CT_TLShapeTargetElement\"/>\n      <xsd:element name=\"inkTgt\" type=\"CT_TLSubShapeId\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTriggerTimeNodeID\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTimeNodeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerRuntimeNode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"first\"/>\n      <xsd:enumeration value=\"last\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTriggerRuntimeNode\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTriggerRuntimeNode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerEvent\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"onBegin\"/>\n      <xsd:enumeration value=\"onEnd\"/>\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"onClick\"/>\n      <xsd:enumeration value=\"onDblClick\"/>\n      <xsd:enumeration value=\"onMouseOver\"/>\n      <xsd:enumeration value=\"onMouseOut\"/>\n      <xsd:enumeration value=\"onNext\"/>\n      <xsd:enumeration value=\"onPrev\"/>\n      <xsd:enumeration value=\"onStopAudio\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeCondition\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\"/>\n      <xsd:element name=\"tn\" type=\"CT_TLTriggerTimeNodeID\"/>\n      <xsd:element name=\"rtn\" type=\"CT_TLTriggerRuntimeNode\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"evt\" use=\"optional\" type=\"ST_TLTriggerEvent\"/>\n    <xsd:attribute name=\"delay\" type=\"ST_TLTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeConditionList\">\n    <xsd:sequence>\n      <xsd:element name=\"cond\" type=\"CT_TLTimeCondition\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TimeNodeList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"par\" type=\"CT_TLTimeNodeParallel\"/>\n      <xsd:element name=\"seq\" type=\"CT_TLTimeNodeSequence\"/>\n      <xsd:element name=\"excl\" type=\"CT_TLTimeNodeExclusive\"/>\n      <xsd:element name=\"anim\" type=\"CT_TLAnimateBehavior\"/>\n      <xsd:element name=\"animClr\" type=\"CT_TLAnimateColorBehavior\"/>\n      <xsd:element name=\"animEffect\" type=\"CT_TLAnimateEffectBehavior\"/>\n      <xsd:element name=\"animMotion\" type=\"CT_TLAnimateMotionBehavior\"/>\n      <xsd:element name=\"animRot\" type=\"CT_TLAnimateRotationBehavior\"/>\n      <xsd:element name=\"animScale\" type=\"CT_TLAnimateScaleBehavior\"/>\n      <xsd:element name=\"cmd\" type=\"CT_TLCommandBehavior\"/>\n      <xsd:element name=\"set\" type=\"CT_TLSetBehavior\"/>\n      <xsd:element name=\"audio\" type=\"CT_TLMediaNodeAudio\"/>\n      <xsd:element name=\"video\" type=\"CT_TLMediaNodeVideo\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeNodePresetClassType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"entr\"/>\n      <xsd:enumeration value=\"exit\"/>\n      <xsd:enumeration value=\"emph\"/>\n      <xsd:enumeration value=\"path\"/>\n      <xsd:enumeration value=\"verb\"/>\n      <xsd:enumeration value=\"mediacall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeRestartType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"whenNotActive\"/>\n      <xsd:enumeration value=\"never\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeFillType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"remove\"/>\n      <xsd:enumeration value=\"freeze\"/>\n      <xsd:enumeration value=\"hold\"/>\n      <xsd:enumeration value=\"transition\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeSyncType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"canSlip\"/>\n      <xsd:enumeration value=\"locked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeMasterRelation\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sameClick\"/>\n      <xsd:enumeration value=\"lastClick\"/>\n      <xsd:enumeration value=\"nextClick\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clickEffect\"/>\n      <xsd:enumeration value=\"withEffect\"/>\n      <xsd:enumeration value=\"afterEffect\"/>\n      <xsd:enumeration value=\"mainSeq\"/>\n      <xsd:enumeration value=\"interactiveSeq\"/>\n      <xsd:enumeration value=\"clickPar\"/>\n      <xsd:enumeration value=\"withGroup\"/>\n      <xsd:enumeration value=\"afterGroup\"/>\n      <xsd:enumeration value=\"tmRoot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonTimeNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"stCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endSync\" type=\"CT_TLTimeCondition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iterate\" type=\"CT_TLIterateData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"childTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"subTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_TLTimeNodeID\" use=\"optional\"/>\n    <xsd:attribute name=\"presetID\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presetClass\" type=\"ST_TLTimeNodePresetClassType\" use=\"optional\"/>\n    <xsd:attribute name=\"presetSubtype\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"dur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"repeatCount\" type=\"ST_TLTime\" use=\"optional\" default=\"1000\"/>\n    <xsd:attribute name=\"repeatDur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"spd\" type=\"a:ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"accel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"decel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"autoRev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_TLTimeNodeRestartType\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_TLTimeNodeFillType\" use=\"optional\"/>\n    <xsd:attribute name=\"syncBehavior\" type=\"ST_TLTimeNodeSyncType\" use=\"optional\"/>\n    <xsd:attribute name=\"tmFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"evtFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"masterRel\" type=\"ST_TLTimeNodeMasterRelation\" use=\"optional\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"afterEffect\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nodeType\" type=\"ST_TLTimeNodeType\" use=\"optional\"/>\n    <xsd:attribute name=\"nodePh\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeParallel\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLNextActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"seek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLPreviousActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"skipTimed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeNodeSequence\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prevCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nextCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"concurrent\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"prevAc\" type=\"ST_TLPreviousActionType\" use=\"optional\"/>\n    <xsd:attribute name=\"nextAc\" type=\"ST_TLNextActionType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeExclusive\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLBehaviorAttributeNameList\">\n    <xsd:sequence>\n      <xsd:element name=\"attrName\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLBehaviorAdditiveType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"repl\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorAccumulateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorTransformType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pt\"/>\n      <xsd:enumeration value=\"img\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorOverrideType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"childStyle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonBehaviorData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attrNameLst\" type=\"CT_TLBehaviorAttributeNameList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"additive\" type=\"ST_TLBehaviorAdditiveType\" use=\"optional\"/>\n    <xsd:attribute name=\"accumulate\" type=\"ST_TLBehaviorAccumulateType\" use=\"optional\"/>\n    <xsd:attribute name=\"xfrmType\" type=\"ST_TLBehaviorTransformType\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rctx\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"override\" type=\"ST_TLBehaviorOverrideType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantBooleanVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantIntegerVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantFloatVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:float\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantStringVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"boolVal\" type=\"CT_TLAnimVariantBooleanVal\"/>\n      <xsd:element name=\"intVal\" type=\"CT_TLAnimVariantIntegerVal\"/>\n      <xsd:element name=\"fltVal\" type=\"CT_TLAnimVariantFloatVal\"/>\n      <xsd:element name=\"strVal\" type=\"CT_TLAnimVariantStringVal\"/>\n      <xsd:element name=\"clrVal\" type=\"a:CT_Color\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeAnimateValueTime\">\n    <xsd:union memberTypes=\"a:ST_PositiveFixedPercentage ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tm\" type=\"ST_TLTimeAnimateValueTime\" use=\"optional\" default=\"indefinite\"/>\n    <xsd:attribute name=\"fmla\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValueList\">\n    <xsd:sequence>\n      <xsd:element name=\"tav\" type=\"CT_TLTimeAnimateValue\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorCalcMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"discrete\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"fmla\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorValueType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tavLst\" type=\"CT_TLTimeAnimateValueList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"calcmode\" type=\"ST_TLAnimateBehaviorCalcMode\" use=\"optional\"/>\n    <xsd:attribute name=\"valueType\" type=\"ST_TLAnimateBehaviorValueType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByRgbColorTransform\">\n    <xsd:attribute name=\"r\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByHslColorTransform\">\n    <xsd:attribute name=\"h\" type=\"a:ST_Angle\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"l\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByAnimateColorTransform\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"rgb\" type=\"CT_TLByRgbColorTransform\"/>\n      <xsd:element name=\"hsl\" type=\"CT_TLByHslColorTransform\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateColorSpace\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rgb\"/>\n      <xsd:enumeration value=\"hsl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateColorDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateColorBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLByAnimateColorTransform\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"clrSpc\" type=\"ST_TLAnimateColorSpace\" use=\"optional\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TLAnimateColorDirection\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateEffectTransition\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateEffectBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"progress\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"transition\" type=\"ST_TLAnimateEffectTransition\" default=\"in\" use=\"optional\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"prLst\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionBehaviorOrigin\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parent\"/>\n      <xsd:enumeration value=\"layout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionPathEditMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relative\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLPoint\">\n    <xsd:attribute name=\"x\" type=\"a:ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"a:ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateMotionBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rCtr\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"origin\" type=\"ST_TLAnimateMotionBehaviorOrigin\" use=\"optional\"/>\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"pathEditMode\" type=\"ST_TLAnimateMotionPathEditMode\" use=\"optional\"/>\n    <xsd:attribute name=\"rAng\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"ptsTypes\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateRotationBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"a:ST_Angle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateScaleBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zoomContents\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLCommandType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"evt\"/>\n      <xsd:enumeration value=\"call\"/>\n      <xsd:enumeration value=\"verb\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommandBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute type=\"ST_TLCommandType\" name=\"type\" use=\"optional\"/>\n    <xsd:attribute name=\"cmd\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSetBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLCommonMediaNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"vol\" type=\"a:ST_PositiveFixedPercentage\" default=\"50%\" use=\"optional\"/>\n    <xsd:attribute name=\"mute\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numSld\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showWhenStopped\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeAudio\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeVideo\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullScrn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_TLBuild\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uiExpand\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_TLTemplate\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTemplateList\">\n    <xsd:sequence>\n      <xsd:element name=\"tmpl\" type=\"CT_TLTemplate\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLParaBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"whole\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"tmplLst\" type=\"CT_TLTemplateList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"build\" type=\"ST_TLParaBuildType\" use=\"optional\" default=\"whole\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoUpdateAnimBg\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advAuto\" type=\"ST_TLTime\" use=\"optional\" default=\"indefinite\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLDiagramBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"depthByNode\"/>\n      <xsd:enumeration value=\"depthByBranch\"/>\n      <xsd:enumeration value=\"breadthByNode\"/>\n      <xsd:enumeration value=\"breadthByLvl\"/>\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"cwIn\"/>\n      <xsd:enumeration value=\"cwOut\"/>\n      <xsd:enumeration value=\"ccw\"/>\n      <xsd:enumeration value=\"ccwIn\"/>\n      <xsd:enumeration value=\"ccwOut\"/>\n      <xsd:enumeration value=\"inByRing\"/>\n      <xsd:enumeration value=\"outByRing\"/>\n      <xsd:enumeration value=\"up\"/>\n      <xsd:enumeration value=\"down\"/>\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildDiagram\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLDiagramBuildType\" use=\"optional\" default=\"whole\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLOleChartBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleBuildChart\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLOleChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLGraphicalObjectBuild\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bldAsOne\" type=\"CT_Empty\"/>\n      <xsd:element name=\"bldSub\" type=\"a:CT_AnimationGraphicalObjectBuildProperties\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BuildList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bldP\" type=\"CT_TLBuildParagraph\"/>\n      <xsd:element name=\"bldDgm\" type=\"CT_TLBuildDiagram\"/>\n      <xsd:element name=\"bldOleChart\" type=\"CT_TLOleBuildChart\"/>\n      <xsd:element name=\"bldGraphic\" type=\"CT_TLGraphicalObjectBuild\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideTiming\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bldLst\" type=\"CT_BuildList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:simpleType name=\"ST_Name\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IndexRange\">\n    <xsd:attribute name=\"st\" type=\"ST_Index\" use=\"required\"/>\n    <xsd:attribute name=\"end\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipListEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_SlideRelationshipListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowId\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SlideListChoice\">\n    <xsd:choice>\n      <xsd:element name=\"sldAll\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sldRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShowId\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CustomerData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagsData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomerDataList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"custData\" type=\"CT_CustomerData\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tags\" type=\"CT_TagsData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionListModify\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mod\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthor\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"initials\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"lastIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"clrIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthorList\">\n    <xsd:sequence>\n      <xsd:element name=\"cmAuthor\" type=\"CT_CommentAuthor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmAuthorLst\" type=\"CT_CommentAuthorList\"/>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"text\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"idx\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"cm\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmLst\" type=\"CT_CommentList\"/>\n  <xsd:attributeGroup name=\"AG_Ole\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"showAsIcon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"imgW\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"imgH\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:simpleType name=\"ST_OleObjectFollowColorScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"textAndBackground\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleObjectEmbed\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"followColorScheme\" type=\"ST_OleObjectFollowColorScheme\" use=\"optional\"\n      default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjectLink\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"updateAutomatic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"embed\" type=\"CT_OleObjectEmbed\"/>\n        <xsd:element name=\"link\" type=\"CT_OleObjectLink\"/>\n      </xsd:choice>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"oleObj\" type=\"CT_OleObject\"/>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlList\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"256\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideId\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldId\" type=\"CT_SlideIdListEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideMasterId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideMasterId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterId\" type=\"CT_SlideMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"notesMasterId\" type=\"CT_NotesMasterIdListEntry\" minOccurs=\"0\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"handoutMasterId\" type=\"CT_HandoutMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontDataId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"a:CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"regular\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bold\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"italic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"boldItalic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontList\">\n    <xsd:sequence>\n      <xsd:element name=\"embeddedFont\" type=\"CT_EmbeddedFontListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShow\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLst\" type=\"CT_SlideRelationshipList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowList\">\n    <xsd:sequence>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhotoAlbumLayout\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fitToSlide\"/>\n      <xsd:enumeration value=\"1pic\"/>\n      <xsd:enumeration value=\"2pic\"/>\n      <xsd:enumeration value=\"4pic\"/>\n      <xsd:enumeration value=\"1picTitle\"/>\n      <xsd:enumeration value=\"2picTitle\"/>\n      <xsd:enumeration value=\"4picTitle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhotoAlbumFrameShape\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"frameStyle1\"/>\n      <xsd:enumeration value=\"frameStyle2\"/>\n      <xsd:enumeration value=\"frameStyle3\"/>\n      <xsd:enumeration value=\"frameStyle4\"/>\n      <xsd:enumeration value=\"frameStyle5\"/>\n      <xsd:enumeration value=\"frameStyle6\"/>\n      <xsd:enumeration value=\"frameStyle7\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhotoAlbum\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bw\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showCaptions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"layout\" type=\"ST_PhotoAlbumLayout\" use=\"optional\" default=\"fitToSlide\"/>\n    <xsd:attribute name=\"frame\" type=\"ST_PhotoAlbumFrameShape\" use=\"optional\" default=\"frameStyle1\"\n    />\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideSizeCoordinate\">\n    <xsd:restriction base=\"a:ST_PositiveCoordinate32\">\n      <xsd:minInclusive value=\"914400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SlideSizeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"screen4x3\"/>\n      <xsd:enumeration value=\"letter\"/>\n      <xsd:enumeration value=\"A4\"/>\n      <xsd:enumeration value=\"35mm\"/>\n      <xsd:enumeration value=\"overhead\"/>\n      <xsd:enumeration value=\"banner\"/>\n      <xsd:enumeration value=\"custom\"/>\n      <xsd:enumeration value=\"ledger\"/>\n      <xsd:enumeration value=\"A3\"/>\n      <xsd:enumeration value=\"B4ISO\"/>\n      <xsd:enumeration value=\"B5ISO\"/>\n      <xsd:enumeration value=\"B4JIS\"/>\n      <xsd:enumeration value=\"B5JIS\"/>\n      <xsd:enumeration value=\"hagakiCard\"/>\n      <xsd:enumeration value=\"screen16x9\"/>\n      <xsd:enumeration value=\"screen16x10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideSize\">\n    <xsd:attribute name=\"cx\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideSizeType\" use=\"optional\" default=\"custom\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"invalStChars\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"invalEndChars\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BookmarkIdSeed\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ModifyVerifier\">\n    <xsd:attribute name=\"algorithmName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinValue\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"saltData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"hashData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Presentation\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterIdLst\" type=\"CT_SlideMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesMasterIdLst\" type=\"CT_NotesMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"handoutMasterIdLst\" type=\"CT_HandoutMasterIdList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sldIdLst\" type=\"CT_SlideIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldSz\" type=\"CT_SlideSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesSz\" type=\"a:CT_PositiveSize2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embeddedFontLst\" type=\"CT_EmbeddedFontList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custShowLst\" type=\"CT_CustomShowList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"photoAlbum\" type=\"CT_PhotoAlbum\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTextStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"modifyVerifier\" type=\"CT_ModifyVerifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverZoom\" type=\"a:ST_Percentage\" use=\"optional\" default=\"50%\"/>\n    <xsd:attribute name=\"firstSlideNum\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showSpecialPlsOnTitleSld\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removePersonalInfoOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"strictFirstAndLastChars\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"embedTrueTypeFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveSubsetFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"bookmarkIdSeed\" type=\"ST_BookmarkIdSeed\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:element name=\"presentation\" type=\"CT_Presentation\"/>\n  <xsd:complexType name=\"CT_HtmlPublishProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showSpeakerNotes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebColorType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"browser\"/>\n      <xsd:enumeration value=\"presentationText\"/>\n      <xsd:enumeration value=\"presentationAccent\"/>\n      <xsd:enumeration value=\"whiteTextOnBlack\"/>\n      <xsd:enumeration value=\"blackTextOnWhite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebScreenSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1400\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebEncoding\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"resizeGraphics\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"relyOnVml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"organizeInFolders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useLongFilenames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"imgSz\" type=\"ST_WebScreenSize\" use=\"optional\" default=\"800x600\"/>\n    <xsd:attribute name=\"encoding\" type=\"ST_WebEncoding\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"clr\" type=\"ST_WebColorType\" use=\"optional\" default=\"whiteTextOnBlack\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintWhat\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slides\"/>\n      <xsd:enumeration value=\"handouts1\"/>\n      <xsd:enumeration value=\"handouts2\"/>\n      <xsd:enumeration value=\"handouts3\"/>\n      <xsd:enumeration value=\"handouts4\"/>\n      <xsd:enumeration value=\"handouts6\"/>\n      <xsd:enumeration value=\"handouts9\"/>\n      <xsd:enumeration value=\"notes\"/>\n      <xsd:enumeration value=\"outline\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrintColorMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bw\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PrintProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prnWhat\" type=\"ST_PrintWhat\" use=\"optional\" default=\"slides\"/>\n    <xsd:attribute name=\"clrMode\" type=\"ST_PrintColorMode\" use=\"optional\" default=\"clr\"/>\n    <xsd:attribute name=\"hiddenSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scaleToFitPaper\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"frameSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoBrowse\">\n    <xsd:attribute name=\"showScrollbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoKiosk\">\n    <xsd:attribute name=\"restart\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"300000\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShowType\">\n    <xsd:choice>\n      <xsd:element name=\"present\" type=\"CT_Empty\"/>\n      <xsd:element name=\"browse\" type=\"CT_ShowInfoBrowse\"/>\n      <xsd:element name=\"kiosk\" type=\"CT_ShowInfoKiosk\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ShowProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:group ref=\"EG_ShowType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"penClr\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useTimings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"htmlPubPr\" type=\"CT_HtmlPublishProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPr\" type=\"CT_WebProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prnPr\" type=\"CT_PrintProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPr\" type=\"CT_ShowProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMru\" type=\"a:CT_ColorMRU\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"presentationPr\" type=\"CT_PresentationProperties\"/>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sldNum\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"hdr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"ftr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PlaceholderType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"body\"/>\n      <xsd:enumeration value=\"ctrTitle\"/>\n      <xsd:enumeration value=\"subTitle\"/>\n      <xsd:enumeration value=\"dt\"/>\n      <xsd:enumeration value=\"sldNum\"/>\n      <xsd:enumeration value=\"ftr\"/>\n      <xsd:enumeration value=\"hdr\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"clipArt\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"media\"/>\n      <xsd:enumeration value=\"sldImg\"/>\n      <xsd:enumeration value=\"pic\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PlaceholderSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"half\"/>\n      <xsd:enumeration value=\"quarter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_PlaceholderType\" use=\"optional\" default=\"obj\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_PlaceholderSize\" use=\"optional\" default=\"full\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hasCustomPrompt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ApplicationNonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"ph\" type=\"CT_Placeholder\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_Media\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isPhoto\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useBgFill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TopLevelSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMap\" type=\"a:CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_ChildSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMappingOverride\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_ChildSlide\">\n    <xsd:attribute name=\"showMasterSp\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showMasterPhAnim\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_BackgroundProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shadeToTitle\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Background\">\n    <xsd:choice>\n      <xsd:element name=\"bgPr\" type=\"CT_BackgroundProperties\"/>\n      <xsd:element name=\"bgRef\" type=\"a:CT_StyleMatrixReference\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Background\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\" default=\"white\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideData\">\n    <xsd:sequence>\n      <xsd:element name=\"bg\" type=\"CT_Background\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spTree\" type=\"CT_GroupShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_ControlList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Slide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sld\" type=\"CT_Slide\"/>\n  <xsd:simpleType name=\"ST_SlideLayoutType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"twoColTx\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"txAndChart\"/>\n      <xsd:enumeration value=\"chartAndTx\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"txAndClipArt\"/>\n      <xsd:enumeration value=\"clipArtAndTx\"/>\n      <xsd:enumeration value=\"titleOnly\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"txAndObj\"/>\n      <xsd:enumeration value=\"objAndTx\"/>\n      <xsd:enumeration value=\"objOnly\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"txAndMedia\"/>\n      <xsd:enumeration value=\"mediaAndTx\"/>\n      <xsd:enumeration value=\"objOverTx\"/>\n      <xsd:enumeration value=\"txOverObj\"/>\n      <xsd:enumeration value=\"txAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndTx\"/>\n      <xsd:enumeration value=\"twoObjOverTx\"/>\n      <xsd:enumeration value=\"fourObj\"/>\n      <xsd:enumeration value=\"vertTx\"/>\n      <xsd:enumeration value=\"clipArtAndVertTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTxOverChart\"/>\n      <xsd:enumeration value=\"twoObj\"/>\n      <xsd:enumeration value=\"objAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndObj\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"secHead\"/>\n      <xsd:enumeration value=\"twoTxTwoObj\"/>\n      <xsd:enumeration value=\"objTx\"/>\n      <xsd:enumeration value=\"picTx\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayout\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"matchingName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideLayoutType\" use=\"optional\" default=\"cust\"/>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldLayout\" type=\"CT_SlideLayout\"/>\n  <xsd:complexType name=\"CT_SlideMasterTextStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"titleStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"otherStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideLayoutId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayoutIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideLayoutId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideLayoutIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLayoutId\" type=\"CT_SlideLayoutIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMaster\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLayoutIdLst\" type=\"CT_SlideLayoutIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txStyles\" type=\"CT_SlideMasterTextStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldMaster\" type=\"CT_SlideMaster\"/>\n  <xsd:complexType name=\"CT_HandoutMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"handoutMaster\" type=\"CT_HandoutMaster\"/>\n  <xsd:complexType name=\"CT_NotesMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"notesMaster\" type=\"CT_NotesMaster\"/>\n  <xsd:complexType name=\"CT_NotesSlide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n  </xsd:complexType>\n  <xsd:element name=\"notes\" type=\"CT_NotesSlide\"/>\n  <xsd:complexType name=\"CT_SlideSyncProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverSldId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"serverSldModifiedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"clientInsertedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldSyncPr\" type=\"CT_SlideSyncProperties\"/>\n  <xsd:complexType name=\"CT_StringTag\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagList\">\n    <xsd:sequence>\n      <xsd:element name=\"tag\" type=\"CT_StringTag\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tagLst\" type=\"CT_TagList\"/>\n  <xsd:simpleType name=\"ST_SplitterBarState\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"minimized\"/>\n      <xsd:enumeration value=\"restored\"/>\n      <xsd:enumeration value=\"maximized\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ViewType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sldView\"/>\n      <xsd:enumeration value=\"sldMasterView\"/>\n      <xsd:enumeration value=\"notesView\"/>\n      <xsd:enumeration value=\"handoutView\"/>\n      <xsd:enumeration value=\"notesMasterView\"/>\n      <xsd:enumeration value=\"outlineView\"/>\n      <xsd:enumeration value=\"sldSorterView\"/>\n      <xsd:enumeration value=\"sldThumbnailView\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NormalViewPortion\">\n    <xsd:attribute name=\"sz\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"autoAdjust\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NormalViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"restoredLeft\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"restoredTop\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showOutlineIcons\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapVertSplitter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vertBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"horzBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"preferSingleView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"scale\" type=\"a:CT_Scale2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"origin\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"varScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesTextViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"collapse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_OutlineViewSlideEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLst\" type=\"CT_OutlineViewSlideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideSorterViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guide\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"vert\"/>\n    <xsd:attribute name=\"pos\" type=\"a:ST_Coordinate32\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GuideList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"guide\" type=\"CT_Guide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"guideLst\" type=\"CT_GuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"snapToGrid\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapToObjects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGuides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ViewProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"normalViewPr\" type=\"CT_NormalViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"slideViewPr\" type=\"CT_SlideViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlineViewPr\" type=\"CT_OutlineViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesTextViewPr\" type=\"CT_NotesTextViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sorterViewPr\" type=\"CT_SlideSorterViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"notesViewPr\" type=\"CT_NotesViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpacing\" type=\"a:CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastView\" type=\"ST_ViewType\" use=\"optional\" default=\"sldView\"/>\n    <xsd:attribute name=\"showComments\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"viewPr\" type=\"CT_ViewProperties\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_AdditionalCharacteristics\">\n    <xsd:sequence>\n      <xsd:element name=\"characteristic\" type=\"CT_Characteristic\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Characteristic\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"relation\" type=\"ST_Relation\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"vocabulary\" type=\"xsd:anyURI\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Relation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ge\"/>\n      <xsd:enumeration value=\"le\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"eq\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"additionalCharacteristics\" type=\"CT_AdditionalCharacteristics\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"s:ST_String\">\n      <xsd:enumeration value=\"ArticleInAPeriodical\"/>\n      <xsd:enumeration value=\"Book\"/>\n      <xsd:enumeration value=\"BookSection\"/>\n      <xsd:enumeration value=\"JournalArticle\"/>\n      <xsd:enumeration value=\"ConferenceProceedings\"/>\n      <xsd:enumeration value=\"Report\"/>\n      <xsd:enumeration value=\"SoundRecording\"/>\n      <xsd:enumeration value=\"Performance\"/>\n      <xsd:enumeration value=\"Art\"/>\n      <xsd:enumeration value=\"DocumentFromInternetSite\"/>\n      <xsd:enumeration value=\"InternetSite\"/>\n      <xsd:enumeration value=\"Film\"/>\n      <xsd:enumeration value=\"Interview\"/>\n      <xsd:enumeration value=\"Patent\"/>\n      <xsd:enumeration value=\"ElectronicSource\"/>\n      <xsd:enumeration value=\"Case\"/>\n      <xsd:enumeration value=\"Misc\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NameListType\">\n    <xsd:sequence>\n      <xsd:element name=\"Person\" type=\"CT_PersonType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PersonType\">\n    <xsd:sequence>\n      <xsd:element name=\"Last\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"First\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Middle\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameType\">\n    <xsd:sequence>\n      <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameOrCorporateType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"Corporate\" minOccurs=\"1\" maxOccurs=\"1\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AuthorType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"Artist\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Author\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"BookAuthor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Compiler\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Composer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Conductor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Counsel\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Director\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Editor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewee\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Inventor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Performer\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"ProducerName\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Translator\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Writer\" type=\"CT_NameType\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SourceType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"AbbreviatedCaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"AlbumTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Author\" type=\"CT_AuthorType\"/>\n        <xsd:element name=\"BookTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Broadcaster\" type=\"s:ST_String\"/>\n        <xsd:element name=\"BroadcastTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ChapterNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"City\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Comments\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ConferenceName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CountryRegion\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Court\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Day\" type=\"s:ST_String\"/>\n        <xsd:element name=\"DayAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Department\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Distributor\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Edition\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Guid\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Institution\" type=\"s:ST_String\"/>\n        <xsd:element name=\"InternetSiteTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Issue\" type=\"s:ST_String\"/>\n        <xsd:element name=\"JournalName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"LCID\" type=\"s:ST_Lang\"/>\n        <xsd:element name=\"Medium\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Month\" type=\"s:ST_String\"/>\n        <xsd:element name=\"MonthAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"NumberVolumes\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Pages\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PatentNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PeriodicalTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ProductionCompany\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PublicationTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Publisher\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RecordingNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RefOrder\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Reporter\" type=\"s:ST_String\"/>\n        <xsd:element name=\"SourceType\" type=\"ST_SourceType\"/>\n        <xsd:element name=\"ShortTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StandardNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StateProvince\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Station\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Tag\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Theater\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ThesisType\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Title\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Type\" type=\"s:ST_String\"/>\n        <xsd:element name=\"URL\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Version\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Volume\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Year\" type=\"s:ST_String\"/>\n        <xsd:element name=\"YearAccessed\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"Sources\" type=\"CT_Sources\"/>\n  <xsd:complexType name=\"CT_Sources\">\n    <xsd:sequence>\n      <xsd:element name=\"Source\" type=\"CT_SourceType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectedStyle\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"StyleName\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"URI\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\">\n  <xsd:simpleType name=\"ST_Lang\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColorRGB\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"3\" fixed=\"true\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Panose\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalendarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gregorian\"/>\n      <xsd:enumeration value=\"gregorianUs\"/>\n      <xsd:enumeration value=\"gregorianMeFrench\"/>\n      <xsd:enumeration value=\"gregorianArabic\"/>\n      <xsd:enumeration value=\"hijri\"/>\n      <xsd:enumeration value=\"hebrew\"/>\n      <xsd:enumeration value=\"taiwan\"/>\n      <xsd:enumeration value=\"japan\"/>\n      <xsd:enumeration value=\"thai\"/>\n      <xsd:enumeration value=\"korea\"/>\n      <xsd:enumeration value=\"saka\"/>\n      <xsd:enumeration value=\"gregorianXlitEnglish\"/>\n      <xsd:enumeration value=\"gregorianXlitFrench\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hash\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CryptProv\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rsaAES\"/>\n      <xsd:enumeration value=\"rsaFull\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"typeAny\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Guid\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff\">\n    <xsd:union memberTypes=\"xsd:boolean ST_OnOff1\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff1\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_String\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XmlName\">\n    <xsd:restriction base=\"xsd:NCName\">\n      <xsd:minLength value=\"1\"/>\n      <xsd:maxLength value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalse\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalseBlank\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n      <xsd:enumeration value=\"\"/>\n      <xsd:enumeration value=\"True\"/>\n      <xsd:enumeration value=\"False\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedDecimalNumber\">\n    <xsd:restriction base=\"xsd:decimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TwipsMeasure\">\n    <xsd:union memberTypes=\"ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignRun\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"superscript\"/>\n      <xsd:enumeration value=\"subscript\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Xstring\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_YAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inline\"/>\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConformanceClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"strict\"/>\n      <xsd:enumeration value=\"transitional\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UniversalMeasure\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveUniversalMeasure\">\n    <xsd:restriction base=\"ST_UniversalMeasure\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"-?((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_DatastoreSchemaRef\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreSchemaRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRef\" type=\"CT_DatastoreSchemaRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreItem\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRefs\" type=\"CT_DatastoreSchemaRefs\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"itemID\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"datastoreItem\" type=\"CT_DatastoreItem\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_Schema\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" default=\"\"/>\n    <xsd:attribute name=\"manifestLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLanguage\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SchemaLibrary\">\n    <xsd:sequence>\n      <xsd:element name=\"schema\" type=\"CT_Schema\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"schemaLibrary\" type=\"CT_SchemaLibrary\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:sequence>\n      <xsd:element name=\"property\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Property\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Property\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n      <xsd:element ref=\"vt:array\"/>\n      <xsd:element ref=\"vt:blob\"/>\n      <xsd:element ref=\"vt:oblob\"/>\n      <xsd:element ref=\"vt:empty\"/>\n      <xsd:element ref=\"vt:null\"/>\n      <xsd:element ref=\"vt:i1\"/>\n      <xsd:element ref=\"vt:i2\"/>\n      <xsd:element ref=\"vt:i4\"/>\n      <xsd:element ref=\"vt:i8\"/>\n      <xsd:element ref=\"vt:int\"/>\n      <xsd:element ref=\"vt:ui1\"/>\n      <xsd:element ref=\"vt:ui2\"/>\n      <xsd:element ref=\"vt:ui4\"/>\n      <xsd:element ref=\"vt:ui8\"/>\n      <xsd:element ref=\"vt:uint\"/>\n      <xsd:element ref=\"vt:r4\"/>\n      <xsd:element ref=\"vt:r8\"/>\n      <xsd:element ref=\"vt:decimal\"/>\n      <xsd:element ref=\"vt:lpstr\"/>\n      <xsd:element ref=\"vt:lpwstr\"/>\n      <xsd:element ref=\"vt:bstr\"/>\n      <xsd:element ref=\"vt:date\"/>\n      <xsd:element ref=\"vt:filetime\"/>\n      <xsd:element ref=\"vt:bool\"/>\n      <xsd:element ref=\"vt:cy\"/>\n      <xsd:element ref=\"vt:error\"/>\n      <xsd:element ref=\"vt:stream\"/>\n      <xsd:element ref=\"vt:ostream\"/>\n      <xsd:element ref=\"vt:storage\"/>\n      <xsd:element ref=\"vt:ostorage\"/>\n      <xsd:element ref=\"vt:vstream\"/>\n      <xsd:element ref=\"vt:clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fmtid\" use=\"required\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"pid\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"linkTarget\" use=\"optional\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  elementFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:all>\n      <xsd:element name=\"Template\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Manager\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Company\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Pages\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Words\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Characters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"PresentationFormat\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Lines\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Paragraphs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Slides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Notes\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"TotalTime\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"HiddenSlides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"MMClips\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"ScaleCrop\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HeadingPairs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"TitlesOfParts\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorLpstr\"/>\n      <xsd:element name=\"LinksUpToDate\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"CharactersWithSpaces\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"SharedDoc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HyperlinkBase\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"HLinks\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"HyperlinksChanged\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"DigSig\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DigSigBlob\"/>\n      <xsd:element name=\"Application\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"AppVersion\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"DocSecurity\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorVariant\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorLpstr\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DigSigBlob\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:blob\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_VectorBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"i8\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"ui8\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"lpstr\"/>\n      <xsd:enumeration value=\"lpwstr\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"filetime\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n      <xsd:enumeration value=\"clsid\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrayBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"int\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"uint\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Cy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*[0-9]*\\.[0-9]{4}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Error\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*0x[0-9A-Za-z]{8}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Null\"/>\n  <xsd:complexType name=\"CT_Vector\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"baseType\" type=\"ST_VectorBaseType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Array\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"cy\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"lBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"uBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"baseType\" type=\"ST_ArrayBaseType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Variant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"vector\"/>\n      <xsd:element ref=\"array\"/>\n      <xsd:element ref=\"blob\"/>\n      <xsd:element ref=\"oblob\"/>\n      <xsd:element ref=\"empty\"/>\n      <xsd:element ref=\"null\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"stream\"/>\n      <xsd:element ref=\"ostream\"/>\n      <xsd:element ref=\"storage\"/>\n      <xsd:element ref=\"ostorage\"/>\n      <xsd:element ref=\"vstream\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vstream\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:base64Binary\">\n        <xsd:attribute name=\"version\" type=\"s:ST_Guid\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:element name=\"variant\" type=\"CT_Variant\"/>\n  <xsd:element name=\"vector\" type=\"CT_Vector\"/>\n  <xsd:element name=\"array\" type=\"CT_Array\"/>\n  <xsd:element name=\"blob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"oblob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"empty\" type=\"CT_Empty\"/>\n  <xsd:element name=\"null\" type=\"CT_Null\"/>\n  <xsd:element name=\"i1\" type=\"xsd:byte\"/>\n  <xsd:element name=\"i2\" type=\"xsd:short\"/>\n  <xsd:element name=\"i4\" type=\"xsd:int\"/>\n  <xsd:element name=\"i8\" type=\"xsd:long\"/>\n  <xsd:element name=\"int\" type=\"xsd:int\"/>\n  <xsd:element name=\"ui1\" type=\"xsd:unsignedByte\"/>\n  <xsd:element name=\"ui2\" type=\"xsd:unsignedShort\"/>\n  <xsd:element name=\"ui4\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"ui8\" type=\"xsd:unsignedLong\"/>\n  <xsd:element name=\"uint\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"r4\" type=\"xsd:float\"/>\n  <xsd:element name=\"r8\" type=\"xsd:double\"/>\n  <xsd:element name=\"decimal\" type=\"xsd:decimal\"/>\n  <xsd:element name=\"lpstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"lpwstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"bstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"date\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"filetime\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"bool\" type=\"xsd:boolean\"/>\n  <xsd:element name=\"cy\" type=\"ST_Cy\"/>\n  <xsd:element name=\"error\" type=\"ST_Error\"/>\n  <xsd:element name=\"stream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"storage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostorage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"vstream\" type=\"CT_Vstream\"/>\n  <xsd:element name=\"clsid\" type=\"s:ST_Guid\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n  <xsd:simpleType name=\"ST_Integer255\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer255\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer255\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Integer2\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"-2\"/>\n      <xsd:maxInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer2\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer2\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SpacingRule\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SpacingRule\">\n    <xsd:attribute name=\"val\" type=\"ST_SpacingRule\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnSignedInteger\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnSignedInteger\">\n    <xsd:attribute name=\"val\" type=\"ST_UnSignedInteger\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Char\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Char\">\n    <xsd:attribute name=\"val\" type=\"ST_Char\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_XAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_YAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_YAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"centered\"/>\n      <xsd:enumeration value=\"match\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shp\">\n    <xsd:attribute name=\"val\" type=\"ST_Shp\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"skw\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"noBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FType\">\n    <xsd:attribute name=\"val\" type=\"ST_FType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LimLoc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"undOvr\"/>\n      <xsd:enumeration value=\"subSup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LimLoc\">\n    <xsd:attribute name=\"val\" type=\"ST_LimLoc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TopBot\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TopBot\">\n    <xsd:attribute name=\"val\" type=\"ST_TopBot\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Script\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"fraktur\"/>\n      <xsd:enumeration value=\"double-struck\"/>\n      <xsd:enumeration value=\"sans-serif\"/>\n      <xsd:enumeration value=\"monospace\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Script\">\n    <xsd:attribute name=\"val\" type=\"ST_Script\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"i\"/>\n      <xsd:enumeration value=\"bi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualBreak\">\n    <xsd:attribute name=\"alnAt\" type=\"ST_Integer255\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ScriptStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"scr\" minOccurs=\"0\" type=\"CT_Script\"/>\n      <xsd:element name=\"sty\" minOccurs=\"0\" type=\"CT_Style\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPR\">\n    <xsd:sequence>\n      <xsd:element name=\"lit\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n      <xsd:choice>\n        <xsd:element name=\"nor\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n        <xsd:sequence>\n          <xsd:group ref=\"EG_ScriptStyle\"/>\n        </xsd:sequence>\n      </xsd:choice>\n      <xsd:element name=\"brk\" minOccurs=\"0\" type=\"CT_ManualBreak\"/>\n      <xsd:element name=\"aln\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPR\" minOccurs=\"0\"/>\n      <xsd:group ref=\"w:EG_RPr\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:group ref=\"w:EG_RunInnerContent\"/>\n        <xsd:element name=\"t\" type=\"CT_Text\" minOccurs=\"0\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CtrlPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"w:EG_RPrMath\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AccPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Acc\">\n    <xsd:sequence>\n      <xsd:element name=\"accPr\" type=\"CT_AccPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarPr\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar\">\n    <xsd:sequence>\n      <xsd:element name=\"barPr\" type=\"CT_BarPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"opEmu\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBreak\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"diff\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"brk\" type=\"CT_ManualBreak\" minOccurs=\"0\"/>\n      <xsd:element name=\"aln\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Box\">\n    <xsd:sequence>\n      <xsd:element name=\"boxPr\" type=\"CT_BoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"hideTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideBot\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideLeft\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideRight\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeH\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeV\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeBLTR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeTLBR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBox\">\n    <xsd:sequence>\n      <xsd:element name=\"borderBoxPr\" type=\"CT_BorderBoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPr\">\n    <xsd:sequence>\n      <xsd:element name=\"begChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"sepChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"endChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shp\" type=\"CT_Shp\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_D\">\n    <xsd:sequence>\n      <xsd:element name=\"dPr\" type=\"CT_DPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"objDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArr\">\n    <xsd:sequence>\n      <xsd:element name=\"eqArrPr\" type=\"CT_EqArrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FPr\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FType\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:sequence>\n      <xsd:element name=\"fPr\" type=\"CT_FPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"num\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"den\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FuncPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Func\">\n    <xsd:sequence>\n      <xsd:element name=\"funcPr\" type=\"CT_FuncPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"fName\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"vertJc\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChr\">\n    <xsd:sequence>\n      <xsd:element name=\"groupChrPr\" type=\"CT_GroupChrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLowPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLow\">\n    <xsd:sequence>\n      <xsd:element name=\"limLowPr\" type=\"CT_LimLowPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUppPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUpp\">\n    <xsd:sequence>\n      <xsd:element name=\"limUppPr\" type=\"CT_LimUppPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCPr\">\n    <xsd:sequence>\n      <xsd:element name=\"count\" type=\"CT_Integer255\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcJc\" type=\"CT_XAlign\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MC\">\n    <xsd:sequence>\n      <xsd:element name=\"mcPr\" type=\"CT_MCPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCS\">\n    <xsd:sequence>\n      <xsd:element name=\"mc\" type=\"CT_MC\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"plcHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcs\" type=\"CT_MCS\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MR\">\n    <xsd:sequence>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_M\">\n    <xsd:sequence>\n      <xsd:element name=\"mPr\" type=\"CT_MPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"mr\" type=\"CT_MR\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NaryPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"limLoc\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"supHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Nary\">\n    <xsd:sequence>\n      <xsd:element name=\"naryPr\" type=\"CT_NaryPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhantPr\">\n    <xsd:sequence>\n      <xsd:element name=\"show\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroWid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroAsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroDesc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"transp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Phant\">\n    <xsd:sequence>\n      <xsd:element name=\"phantPr\" type=\"CT_PhantPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadPr\">\n    <xsd:sequence>\n      <xsd:element name=\"degHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rad\">\n    <xsd:sequence>\n      <xsd:element name=\"radPr\" type=\"CT_RadPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"deg\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPrePr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPre\">\n    <xsd:sequence>\n      <xsd:element name=\"sPrePr\" type=\"CT_SPrePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSub\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubPr\" type=\"CT_SSubPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"alnScr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubSupPr\" type=\"CT_SSubSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSupPr\" type=\"CT_SSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OMathMathElements\">\n    <xsd:choice>\n      <xsd:element name=\"acc\" type=\"CT_Acc\"/>\n      <xsd:element name=\"bar\" type=\"CT_Bar\"/>\n      <xsd:element name=\"box\" type=\"CT_Box\"/>\n      <xsd:element name=\"borderBox\" type=\"CT_BorderBox\"/>\n      <xsd:element name=\"d\" type=\"CT_D\"/>\n      <xsd:element name=\"eqArr\" type=\"CT_EqArr\"/>\n      <xsd:element name=\"f\" type=\"CT_F\"/>\n      <xsd:element name=\"func\" type=\"CT_Func\"/>\n      <xsd:element name=\"groupChr\" type=\"CT_GroupChr\"/>\n      <xsd:element name=\"limLow\" type=\"CT_LimLow\"/>\n      <xsd:element name=\"limUpp\" type=\"CT_LimUpp\"/>\n      <xsd:element name=\"m\" type=\"CT_M\"/>\n      <xsd:element name=\"nary\" type=\"CT_Nary\"/>\n      <xsd:element name=\"phant\" type=\"CT_Phant\"/>\n      <xsd:element name=\"rad\" type=\"CT_Rad\"/>\n      <xsd:element name=\"sPre\" type=\"CT_SPre\"/>\n      <xsd:element name=\"sSub\" type=\"CT_SSub\"/>\n      <xsd:element name=\"sSubSup\" type=\"CT_SSubSup\"/>\n      <xsd:element name=\"sSup\" type=\"CT_SSup\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_OMathElements\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_OMathMathElements\"/>\n      <xsd:group ref=\"w:EG_PContentMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OMathArgPr\">\n    <xsd:sequence>\n      <xsd:element name=\"argSz\" type=\"CT_Integer2\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathArg\">\n    <xsd:sequence>\n      <xsd:element name=\"argPr\" type=\"CT_OMathArgPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"centerGroup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OMathJc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathParaPr\">\n    <xsd:sequence>\n      <xsd:element name=\"jc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBin\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"before\"/>\n      <xsd:enumeration value=\"after\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBin\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBin\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBinSub\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"--\"/>\n      <xsd:enumeration value=\"-+\"/>\n      <xsd:enumeration value=\"+-\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBinSub\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBinSub\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathPr\">\n    <xsd:sequence>\n      <xsd:element name=\"mathFont\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBin\" type=\"CT_BreakBin\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBinSub\" type=\"CT_BreakBinSub\" minOccurs=\"0\"/>\n      <xsd:element name=\"smallFrac\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dispDef\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"rMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"defJc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"preSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"postSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"interSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"intraSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"wrapIndent\" type=\"CT_TwipsMeasure\"/>\n        <xsd:element name=\"wrapRight\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"intLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"naryLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"mathPr\" type=\"CT_MathPr\"/>\n  <xsd:complexType name=\"CT_OMathPara\">\n    <xsd:sequence>\n      <xsd:element name=\"oMathParaPr\" type=\"CT_OMathParaPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OMath\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMath\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"oMathPara\" type=\"CT_OMathPara\"/>\n  <xsd:element name=\"oMath\" type=\"CT_OMath\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  blockDefault=\"#all\">\n  <xsd:simpleType name=\"ST_RelationshipId\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:attribute name=\"id\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"embed\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"link\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"dm\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"lo\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"qs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"cs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"blip\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"pict\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"href\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topRight\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomRight\" type=\"ST_RelationshipId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import \n    namespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n    schemaLocation=\"dml-spreadsheetDrawing.xsd\"/>\n  <xsd:complexType name=\"CT_AutoFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"filterColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FilterColumn\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FilterColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"filters\" type=\"CT_Filters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top10\" type=\"CT_Top10\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customFilters\" type=\"CT_CustomFilters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dynamicFilter\" type=\"CT_DynamicFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colorFilter\" type=\"CT_ColorFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconFilter\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_IconFilter\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"colId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"hiddenButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showButton\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" type=\"CT_Filter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dateGroupItem\" type=\"CT_DateGroupItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n    <xsd:attribute name=\"blank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calendarType\" type=\"s:ST_CalendarType\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filter\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"customFilter\" type=\"CT_CustomFilter\" minOccurs=\"1\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"and\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilter\">\n    <xsd:attribute name=\"operator\" type=\"ST_FilterOperator\" default=\"equal\" use=\"optional\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Top10\">\n    <xsd:attribute name=\"top\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"filterVal\" type=\"xsd:double\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorFilter\">\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"cellColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconFilter\">\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"required\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FilterOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DynamicFilter\">\n    <xsd:attribute name=\"type\" type=\"ST_DynamicFilterType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"valIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxVal\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DynamicFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n      <xsd:enumeration value=\"belowAverage\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_IconSetType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"3Arrows\"/>\n      <xsd:enumeration value=\"3ArrowsGray\"/>\n      <xsd:enumeration value=\"3Flags\"/>\n      <xsd:enumeration value=\"3TrafficLights1\"/>\n      <xsd:enumeration value=\"3TrafficLights2\"/>\n      <xsd:enumeration value=\"3Signs\"/>\n      <xsd:enumeration value=\"3Symbols\"/>\n      <xsd:enumeration value=\"3Symbols2\"/>\n      <xsd:enumeration value=\"4Arrows\"/>\n      <xsd:enumeration value=\"4ArrowsGray\"/>\n      <xsd:enumeration value=\"4RedToBlack\"/>\n      <xsd:enumeration value=\"4Rating\"/>\n      <xsd:enumeration value=\"4TrafficLights\"/>\n      <xsd:enumeration value=\"5Arrows\"/>\n      <xsd:enumeration value=\"5ArrowsGray\"/>\n      <xsd:enumeration value=\"5Rating\"/>\n      <xsd:enumeration value=\"5Quarters\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SortState\">\n    <xsd:sequence>\n      <xsd:element name=\"sortCondition\" minOccurs=\"0\" maxOccurs=\"64\" type=\"CT_SortCondition\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"columnSort\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"caseSensitive\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortMethod\" type=\"ST_SortMethod\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SortCondition\">\n    <xsd:attribute name=\"descending\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortBy\" type=\"ST_SortBy\" use=\"optional\" default=\"value\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"customList\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3Arrows\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cellColor\"/>\n      <xsd:enumeration value=\"fontColor\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SortMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stroke\"/>\n      <xsd:enumeration value=\"pinYin\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DateGroupItem\">\n    <xsd:attribute name=\"year\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"month\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"day\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"hour\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"minute\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"second\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"dateTimeGrouping\" type=\"ST_DateTimeGrouping\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTimeGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"year\"/>\n      <xsd:enumeration value=\"month\"/>\n      <xsd:enumeration value=\"day\"/>\n      <xsd:enumeration value=\"hour\"/>\n      <xsd:enumeration value=\"minute\"/>\n      <xsd:enumeration value=\"second\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellRef\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ref\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefA\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Sqref\">\n    <xsd:list itemType=\"ST_Ref\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Formula\">\n    <xsd:restriction base=\"s:ST_Xstring\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedIntHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedShortHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XStringElement\">\n    <xsd:attribute name=\"v\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectAnchor\">\n    <xsd:sequence>\n      <xsd:element ref=\"xdr:from\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"xdr:to\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"moveWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sizeWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"calcChain\" type=\"CT_CalcChain\"/>\n  <xsd:complexType name=\"CT_CalcChain\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_CalcCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcCell\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"l\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"a\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"authors\" type=\"CT_Authors\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentList\" type=\"CT_CommentList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Authors\">\n    <xsd:sequence>\n      <xsd:element name=\"author\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"text\" type=\"CT_Rst\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentPr\" type=\"CT_CommentPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"textHAlign\" type=\"ST_TextHAlign\" use=\"optional\" default=\"left\"/>\n    <xsd:attribute name=\"textVAlign\" type=\"ST_TextVAlign\" use=\"optional\" default=\"top\"/>\n    <xsd:attribute name=\"lockText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"justLastX\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextHAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"MapInfo\" type=\"CT_MapInfo\"/>\n  <xsd:complexType name=\"CT_MapInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"Schema\" type=\"CT_Schema\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Map\" type=\"CT_Map\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectionNamespaces\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Schema\" mixed=\"true\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaRef\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"Namespace\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"SchemaLanguage\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Map\">\n    <xsd:sequence>\n      <xsd:element name=\"DataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"Name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"RootElement\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"ShowImportExportValidationErrors\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"AutoFit\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"Append\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveSortAFLayout\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveFormat\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"DataBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBinding\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"ConnectionID\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DataBindingLoadMode\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"connections\" type=\"CT_Connections\"/>\n  <xsd:complexType name=\"CT_Connections\">\n    <xsd:sequence>\n      <xsd:element name=\"connection\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Connection\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:sequence>\n      <xsd:element name=\"dbPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DbPr\"/>\n      <xsd:element name=\"olapPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_OlapPr\"/>\n      <xsd:element name=\"webPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_WebPr\"/>\n      <xsd:element name=\"textPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextPr\"/>\n      <xsd:element name=\"parameters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Parameters\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"odcFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"keepAlive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"interval\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"reconnectionMethod\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"refreshedVersion\" use=\"required\" type=\"xsd:unsignedByte\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" use=\"optional\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"savePassword\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"new\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"deleted\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"onlyUseConnectionFile\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"background\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"credentials\" use=\"optional\" type=\"ST_CredMethod\" default=\"integrated\"/>\n    <xsd:attribute name=\"singleSignOnId\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CredMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"integrated\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"stored\"/>\n      <xsd:enumeration value=\"prompt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DbPr\">\n    <xsd:attribute name=\"connection\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"command\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"serverCommand\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"commandType\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OlapPr\">\n    <xsd:attribute name=\"local\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"localConnection\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"localRefresh\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sendLocale\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowDrillCount\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"serverFill\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverNumberFormat\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFont\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFontColor\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tables\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Tables\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"xml\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sourceData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parsePre\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl97\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"textDates\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl2000\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"url\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"post\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"htmlTables\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"htmlFormat\" use=\"optional\" type=\"ST_HtmlFmt\" default=\"none\"/>\n    <xsd:attribute name=\"editPage\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HtmlFmt\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rtf\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Parameters\">\n    <xsd:sequence>\n      <xsd:element name=\"parameter\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Parameter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sqlType\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"parameterType\" use=\"optional\" type=\"ST_ParameterType\" default=\"prompt\"/>\n    <xsd:attribute name=\"refreshOnChange\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"boolean\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"double\" use=\"optional\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"integer\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"string\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cell\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ParameterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"prompt\"/>\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Tables\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_TableMissing\"/>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableMissing\"/>\n  <xsd:complexType name=\"CT_TextPr\">\n    <xsd:sequence>\n      <xsd:element name=\"textFields\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextFields\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fileType\" use=\"optional\" type=\"ST_FileType\" default=\"win\"/>\n    <xsd:attribute name=\"codePage\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1252\"/>\n    <xsd:attribute name=\"characterSet\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\" default=\"\"/>\n    <xsd:attribute name=\"delimited\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"decimal\" use=\"optional\" type=\"s:ST_Xstring\" default=\".\"/>\n    <xsd:attribute name=\"thousands\" use=\"optional\" type=\"s:ST_Xstring\" default=\",\"/>\n    <xsd:attribute name=\"tab\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"space\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"comma\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"semicolon\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"qualifier\" use=\"optional\" type=\"ST_Qualifier\" default=\"doubleQuote\"/>\n    <xsd:attribute name=\"delimiter\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FileType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"mac\"/>\n      <xsd:enumeration value=\"win\"/>\n      <xsd:enumeration value=\"dos\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"other\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Qualifier\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doubleQuote\"/>\n      <xsd:enumeration value=\"singleQuote\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextFields\">\n    <xsd:sequence>\n      <xsd:element name=\"textField\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_TextField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"ST_ExternalConnectionType\" default=\"general\"/>\n    <xsd:attribute name=\"position\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ExternalConnectionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"MDY\"/>\n      <xsd:enumeration value=\"DMY\"/>\n      <xsd:enumeration value=\"YMD\"/>\n      <xsd:enumeration value=\"MYD\"/>\n      <xsd:enumeration value=\"DYM\"/>\n      <xsd:enumeration value=\"YDM\"/>\n      <xsd:enumeration value=\"skip\"/>\n      <xsd:enumeration value=\"EMD\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"pivotCacheDefinition\" type=\"CT_PivotCacheDefinition\"/>\n  <xsd:element name=\"pivotCacheRecords\" type=\"CT_PivotCacheRecords\"/>\n  <xsd:element name=\"pivotTableDefinition\" type=\"CT_pivotTableDefinition\"/>\n  <xsd:complexType name=\"CT_PivotCacheDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheSource\" type=\"CT_CacheSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheFields\" type=\"CT_CacheFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheHierarchies\" minOccurs=\"0\" type=\"CT_CacheHierarchies\"/>\n      <xsd:element name=\"kpis\" minOccurs=\"0\" type=\"CT_PCDKPIs\"/>\n      <xsd:element name=\"tupleCache\" minOccurs=\"0\" type=\"CT_TupleCache\"/>\n      <xsd:element name=\"calculatedItems\" minOccurs=\"0\" type=\"CT_CalculatedItems\"/>\n      <xsd:element name=\"calculatedMembers\" type=\"CT_CalculatedMembers\" minOccurs=\"0\"/>\n      <xsd:element name=\"dimensions\" type=\"CT_Dimensions\" minOccurs=\"0\"/>\n      <xsd:element name=\"measureGroups\" type=\"CT_MeasureGroups\" minOccurs=\"0\"/>\n      <xsd:element name=\"maps\" type=\"CT_MeasureDimensionMaps\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalid\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"optimizeMemory\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshedBy\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDate\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDateIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"backgroundQuery\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingItemsLimit\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"refreshedVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"recordCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"upgradeOnRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tupleCache\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportSubquery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportAdvancedDrill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheFields\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheField\" type=\"CT_CacheField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheField\">\n    <xsd:sequence>\n      <xsd:element name=\"sharedItems\" type=\"CT_SharedItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fieldGroup\" minOccurs=\"0\" type=\"CT_FieldGroup\"/>\n      <xsd:element name=\"mpMap\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"propertyName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueList\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqlType\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"databaseField\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"mappingCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"memberPropertyField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheSource\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"worksheetSource\" type=\"CT_WorksheetSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"consolidation\" type=\"CT_Consolidation\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_SourceType\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" default=\"0\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"external\"/>\n      <xsd:enumeration value=\"consolidation\"/>\n      <xsd:enumeration value=\"scenario\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorksheetSource\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Consolidation\">\n    <xsd:sequence>\n      <xsd:element name=\"pages\" type=\"CT_Pages\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rangeSets\" type=\"CT_RangeSets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"autoPage\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pages\">\n    <xsd:sequence>\n      <xsd:element name=\"page\" type=\"CT_PCDSCPage\" minOccurs=\"1\" maxOccurs=\"4\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSCPage\">\n    <xsd:sequence>\n      <xsd:element name=\"pageItem\" type=\"CT_PageItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSets\">\n    <xsd:sequence>\n      <xsd:element name=\"rangeSet\" type=\"CT_RangeSet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSet\">\n    <xsd:attribute name=\"i1\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i2\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i3\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i4\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedItems\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"s\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"containsSemiMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsNonDate\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsDate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsString\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsInteger\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"minDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"longText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Missing\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Number\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Error\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateTime\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"rangePr\" minOccurs=\"0\" type=\"CT_RangePr\"/>\n      <xsd:element name=\"discretePr\" minOccurs=\"0\" type=\"CT_DiscretePr\"/>\n      <xsd:element name=\"groupItems\" minOccurs=\"0\" type=\"CT_GroupItems\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"par\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"base\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangePr\">\n    <xsd:attribute name=\"autoStart\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"autoEnd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"groupBy\" type=\"ST_GroupBy\" default=\"range\"/>\n    <xsd:attribute name=\"startNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"endNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"startDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"endDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"groupInterval\" type=\"xsd:double\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GroupBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"seconds\"/>\n      <xsd:enumeration value=\"minutes\"/>\n      <xsd:enumeration value=\"hours\"/>\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"quarters\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DiscretePr\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupItems\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCacheRecords\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Record\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Record\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPIs\">\n    <xsd:sequence>\n      <xsd:element name=\"kpi\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PCDKPI\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPI\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"value\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"goal\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"status\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"trend\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"weight\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"time\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheHierarchy\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CacheHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldsUsage\" minOccurs=\"0\" type=\"CT_FieldsUsage\"/>\n      <xsd:element name=\"groupLevels\" minOccurs=\"0\" type=\"CT_GroupLevels\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parentSet\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"attribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"keyAttribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultMemberUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"dimensionUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measures\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"oneField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"memberValueDatatype\" use=\"optional\" type=\"xsd:unsignedShort\"/>\n    <xsd:attribute name=\"unbalanced\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"unbalancedGroup\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldsUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldUsage\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FieldUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldUsage\">\n    <xsd:attribute name=\"x\" use=\"required\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevels\">\n    <xsd:sequence>\n      <xsd:element name=\"groupLevel\" maxOccurs=\"unbounded\" type=\"CT_GroupLevel\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevel\">\n    <xsd:sequence>\n      <xsd:element name=\"groups\" minOccurs=\"0\" type=\"CT_Groups\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"user\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customRollUp\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Groups\">\n    <xsd:sequence>\n      <xsd:element name=\"group\" maxOccurs=\"unbounded\" type=\"CT_LevelGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMembers\" type=\"CT_GroupMembers\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueParent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMember\" maxOccurs=\"unbounded\" type=\"CT_GroupMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMember\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"group\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TupleCache\">\n    <xsd:sequence>\n      <xsd:element name=\"entries\" minOccurs=\"0\" type=\"CT_PCDSDTCEntries\"/>\n      <xsd:element name=\"sets\" minOccurs=\"0\" type=\"CT_Sets\"/>\n      <xsd:element name=\"queryCache\" minOccurs=\"0\" type=\"CT_QueryCache\"/>\n      <xsd:element name=\"serverFormats\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ServerFormats\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormat\">\n    <xsd:attribute name=\"culture\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"format\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"serverFormat\" type=\"CT_ServerFormat\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSDTCEntries\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuples\">\n    <xsd:sequence>\n      <xsd:element name=\"tpl\" type=\"CT_Tuple\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuple\">\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"item\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sets\">\n    <xsd:sequence>\n      <xsd:element name=\"set\" maxOccurs=\"unbounded\" type=\"CT_Set\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Set\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"sortByTuple\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"maxRank\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"setDefinition\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_SortType\" default=\"none\"/>\n    <xsd:attribute name=\"queryFailed\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n      <xsd:enumeration value=\"ascendingAlpha\"/>\n      <xsd:enumeration value=\"descendingAlpha\"/>\n      <xsd:enumeration value=\"ascendingNatural\"/>\n      <xsd:enumeration value=\"descendingNatural\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_QueryCache\">\n    <xsd:sequence>\n      <xsd:element name=\"query\" maxOccurs=\"unbounded\" type=\"CT_Query\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Query\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItems\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedItem\" maxOccurs=\"unbounded\" type=\"CT_CalculatedItem\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItem\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedMember\" maxOccurs=\"unbounded\" type=\"CT_CalculatedMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMember\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"memberName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"solveOrder\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_pivotTableDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"location\" type=\"CT_Location\"/>\n      <xsd:element name=\"pivotFields\" type=\"CT_PivotFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowFields\" type=\"CT_RowFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowItems\" type=\"CT_rowItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"colFields\" type=\"CT_ColFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"colItems\" type=\"CT_colItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageFields\" type=\"CT_PageFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataFields\" type=\"CT_DataFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"formats\" type=\"CT_Formats\" minOccurs=\"0\"/>\n      <xsd:element name=\"conditionalFormats\" type=\"CT_ConditionalFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"chartFormats\" type=\"CT_ChartFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotHierarchies\" type=\"CT_PivotHierarchies\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotTableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotTableStyle\"/>\n      <xsd:element name=\"filters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotFilters\"/>\n      <xsd:element name=\"rowHierarchiesUsage\" type=\"CT_RowHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"colHierarchiesUsage\" type=\"CT_ColHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cacheId\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dataOnRows\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dataPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"dataCaption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"grandTotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"errorCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showError\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showMissing\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"pageStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"pivotTableStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"vacatedStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"tag\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"updatedVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"asteriskTotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showItems\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"editData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"disableFieldList\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showCalcMbrs\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"visualTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showMultipleLabel\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataDropDown\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"printDrill\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showMemberPropertyTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableWizard\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableFieldProperties\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"useAutoFormatting\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"pageWrap\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"pageOverThenDown\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalHiddenItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"colGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fieldPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mergeItem\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showDropZones\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"showEmptyRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showEmptyCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showHeaders\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outlineData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"compactData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"gridDropZones\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"immersive\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleFieldFilters\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"chartFormat\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"rowHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"colHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fieldListSortAscending\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mdxSubqueries\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customListSort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Location\">\n    <xsd:attribute name=\"ref\" use=\"required\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"firstHeaderRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataCol\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"rowPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"colPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotField\" maxOccurs=\"unbounded\" type=\"CT_PivotField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotField\">\n    <xsd:sequence>\n      <xsd:element name=\"items\" minOccurs=\"0\" type=\"CT_Items\"/>\n      <xsd:element name=\"autoSortScope\" minOccurs=\"0\" type=\"CT_AutoSortScope\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"axis\" use=\"optional\" type=\"ST_Axis\"/>\n    <xsd:attribute name=\"dataField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showDropDowns\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hiddenLevel\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueMemberProperty\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"allDrilled\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showAll\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"insertBlankRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"insertPageBreak\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"autoShow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"topAutoShow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hideNewItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"measureFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPageCount\" type=\"xsd:unsignedInt\" default=\"10\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_FieldSortType\" default=\"manual\"/>\n    <xsd:attribute name=\"dataSourceSort\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nonAutoSortDefault\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rankBy\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showPropCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultAttributeDrillState\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoSortScope\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Items\">\n    <xsd:sequence>\n      <xsd:element name=\"item\" maxOccurs=\"unbounded\" type=\"CT_Item\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Item\">\n    <xsd:attribute name=\"n\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"h\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"m\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"e\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pageField\" maxOccurs=\"unbounded\" type=\"CT_PageField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"item\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cap\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataFields\">\n    <xsd:sequence>\n      <xsd:element name=\"dataField\" maxOccurs=\"unbounded\" type=\"CT_DataField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataField\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"subtotal\" type=\"ST_DataConsolidateFunction\" default=\"sum\"/>\n    <xsd:attribute name=\"showDataAs\" type=\"ST_ShowDataAs\" default=\"normal\"/>\n    <xsd:attribute name=\"baseField\" type=\"xsd:int\" default=\"-1\"/>\n    <xsd:attribute name=\"baseItem\" type=\"xsd:unsignedInt\" default=\"1048832\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_rowItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_colItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_I\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_X\">\n    <xsd:attribute name=\"v\" type=\"xsd:int\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Field\">\n    <xsd:attribute name=\"x\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formats\">\n    <xsd:sequence>\n      <xsd:element name=\"format\" maxOccurs=\"unbounded\" type=\"CT_Format\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Format\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"action\" type=\"ST_FormatAction\" default=\"formatting\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"conditionalFormat\" maxOccurs=\"unbounded\" type=\"CT_ConditionalFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotAreas\" type=\"CT_PivotAreas\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"scope\" type=\"ST_Scope\" default=\"selection\"/>\n    <xsd:attribute name=\"type\" type=\"ST_Type\" default=\"none\"/>\n    <xsd:attribute name=\"priority\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreas\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Scope\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"selection\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"field\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Type\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"column\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChartFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"chartFormat\" maxOccurs=\"unbounded\" type=\"CT_ChartFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"chart\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"format\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"series\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotHierarchy\" maxOccurs=\"unbounded\" type=\"CT_PivotHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"mps\" minOccurs=\"0\" type=\"CT_MemberProperties\"/>\n      <xsd:element name=\"members\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Members\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showInFieldList\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"rowHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"colHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierarchyUsage\">\n    <xsd:attribute name=\"hierarchyUsage\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"mp\" maxOccurs=\"unbounded\" type=\"CT_MemberProperty\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nameLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pPos\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"field\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Members\">\n    <xsd:sequence>\n      <xsd:element name=\"member\" maxOccurs=\"unbounded\" type=\"CT_Member\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"level\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Member\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dimensions\">\n    <xsd:sequence>\n      <xsd:element name=\"dimension\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotDimension\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotDimension\">\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroups\">\n    <xsd:sequence>\n      <xsd:element name=\"measureGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMaps\">\n    <xsd:sequence>\n      <xsd:element name=\"map\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureDimensionMap\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroup\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMap\">\n    <xsd:attribute name=\"measureGroup\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dimension\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotTableStyle\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"showRowHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotFilter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_AutoFilter\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"mpFld\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" use=\"required\" type=\"ST_PivotFilterType\"/>\n    <xsd:attribute name=\"evalOrder\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureHier\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureFld\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue1\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue2\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShowDataAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"difference\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"percentDiff\"/>\n      <xsd:enumeration value=\"runTotal\"/>\n      <xsd:enumeration value=\"percentOfRow\"/>\n      <xsd:enumeration value=\"percentOfCol\"/>\n      <xsd:enumeration value=\"percentOfTotal\"/>\n      <xsd:enumeration value=\"index\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ItemType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"countA\"/>\n      <xsd:enumeration value=\"avg\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevP\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varP\"/>\n      <xsd:enumeration value=\"grand\"/>\n      <xsd:enumeration value=\"blank\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormatAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"formatting\"/>\n      <xsd:enumeration value=\"drill\"/>\n      <xsd:enumeration value=\"formula\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FieldSortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PivotFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"unknown\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"captionEqual\"/>\n      <xsd:enumeration value=\"captionNotEqual\"/>\n      <xsd:enumeration value=\"captionBeginsWith\"/>\n      <xsd:enumeration value=\"captionNotBeginsWith\"/>\n      <xsd:enumeration value=\"captionEndsWith\"/>\n      <xsd:enumeration value=\"captionNotEndsWith\"/>\n      <xsd:enumeration value=\"captionContains\"/>\n      <xsd:enumeration value=\"captionNotContains\"/>\n      <xsd:enumeration value=\"captionGreaterThan\"/>\n      <xsd:enumeration value=\"captionGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"captionLessThan\"/>\n      <xsd:enumeration value=\"captionLessThanOrEqual\"/>\n      <xsd:enumeration value=\"captionBetween\"/>\n      <xsd:enumeration value=\"captionNotBetween\"/>\n      <xsd:enumeration value=\"valueEqual\"/>\n      <xsd:enumeration value=\"valueNotEqual\"/>\n      <xsd:enumeration value=\"valueGreaterThan\"/>\n      <xsd:enumeration value=\"valueGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"valueLessThan\"/>\n      <xsd:enumeration value=\"valueLessThanOrEqual\"/>\n      <xsd:enumeration value=\"valueBetween\"/>\n      <xsd:enumeration value=\"valueNotBetween\"/>\n      <xsd:enumeration value=\"dateEqual\"/>\n      <xsd:enumeration value=\"dateNotEqual\"/>\n      <xsd:enumeration value=\"dateOlderThan\"/>\n      <xsd:enumeration value=\"dateOlderThanOrEqual\"/>\n      <xsd:enumeration value=\"dateNewerThan\"/>\n      <xsd:enumeration value=\"dateNewerThanOrEqual\"/>\n      <xsd:enumeration value=\"dateBetween\"/>\n      <xsd:enumeration value=\"dateNotBetween\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"references\" minOccurs=\"0\" type=\"CT_PivotAreaReferences\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PivotAreaType\" default=\"normal\"/>\n    <xsd:attribute name=\"dataOnly\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"labelOnly\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"cacheIndex\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"offset\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"collapsedLevelsAreSubtotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PivotAreaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"origin\"/>\n      <xsd:enumeration value=\"button\"/>\n      <xsd:enumeration value=\"topEnd\"/>\n      <xsd:enumeration value=\"topRight\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotAreaReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"reference\" maxOccurs=\"unbounded\" type=\"CT_PivotAreaReference\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreaReference\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"selected\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"byPosition\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"relative\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Index\">\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Axis\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"axisRow\"/>\n      <xsd:enumeration value=\"axisCol\"/>\n      <xsd:enumeration value=\"axisPage\"/>\n      <xsd:enumeration value=\"axisValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"queryTable\" type=\"CT_QueryTable\"/>\n  <xsd:complexType name=\"CT_QueryTable\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableRefresh\" type=\"CT_QueryTableRefresh\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"headers\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"backgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"firstBackgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"growShrinkType\" type=\"ST_GrowShrinkType\" use=\"optional\"\n      default=\"insertDelete\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removeDataOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"adjustColumnWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"intermediate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableRefresh\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableFields\" type=\"CT_QueryTableFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"queryTableDeletedFields\" type=\"CT_QueryTableDeletedFields\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserveSortFilterLayout\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fieldIdWrapped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headersInLastRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"minimumVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"nextId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"unboundColumnsLeft\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"unboundColumnsRight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableDeletedFields\">\n    <xsd:sequence>\n      <xsd:element name=\"deletedField\" type=\"CT_DeletedField\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DeletedField\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableFields\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableField\" type=\"CT_QueryTableField\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataBound\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clipped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tableColumnId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GrowShrinkType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertDelete\"/>\n      <xsd:enumeration value=\"insertClear\"/>\n      <xsd:enumeration value=\"overwriteClear\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"sst\" type=\"CT_Sst\"/>\n  <xsd:complexType name=\"CT_Sst\">\n    <xsd:sequence>\n      <xsd:element name=\"si\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"uniqueCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhoneticType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"halfwidthKatakana\"/>\n      <xsd:enumeration value=\"fullwidthKatakana\"/>\n      <xsd:enumeration value=\"Hiragana\"/>\n      <xsd:enumeration value=\"noConversion\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhoneticAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhoneticRun\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RElt\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPrElt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrElt\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rFont\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rst\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"r\" type=\"CT_RElt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPh\" type=\"CT_PhoneticRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"phoneticPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PhoneticPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhoneticPr\">\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PhoneticType\" use=\"optional\" default=\"fullwidthKatakana\"/>\n    <xsd:attribute name=\"alignment\" type=\"ST_PhoneticAlignment\" use=\"optional\" default=\"left\"/>\n  </xsd:complexType>\n  <xsd:element name=\"headers\" type=\"CT_RevisionHeaders\"/>\n  <xsd:element name=\"revisions\" type=\"CT_Revisions\"/>\n  <xsd:complexType name=\"CT_RevisionHeaders\">\n    <xsd:sequence>\n      <xsd:element name=\"header\" type=\"CT_RevisionHeader\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"lastGuid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shared\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"diskRevisions\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"trackRevisions\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"exclusive\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"revisionId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"version\" type=\"xsd:int\" default=\"1\"/>\n    <xsd:attribute name=\"keepChangeHistory\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"protected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveHistory\" type=\"xsd:unsignedInt\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Revisions\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rrc\" type=\"CT_RevisionRowColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rm\" type=\"CT_RevisionMove\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcv\" type=\"CT_RevisionCustomView\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rsnm\" type=\"CT_RevisionSheetRename\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ris\" type=\"CT_RevisionInsertSheet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"raf\" type=\"CT_RevisionAutoFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rdn\" type=\"CT_RevisionDefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcmt\" type=\"CT_RevisionComment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rqt\" type=\"CT_RevisionQueryTableField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcft\" type=\"CT_RevisionConflict\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_RevData\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ua\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ra\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_RevisionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetIdMap\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_SheetIdMap\"/>\n      <xsd:element name=\"reviewedList\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ReviewedRevisions\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"maxSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"minRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"maxRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetIdMap\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetId\" type=\"CT_SheetId\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetId\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReviewedRevisions\">\n    <xsd:sequence>\n      <xsd:element name=\"reviewed\" type=\"CT_Reviewed\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Reviewed\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UndoInfo\">\n    <xsd:attribute name=\"index\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"exp\" type=\"ST_FormulaExpression\" use=\"required\"/>\n    <xsd:attribute name=\"ref3D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"array\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cs\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dr\" type=\"ST_RefA\" use=\"required\"/>\n    <xsd:attribute name=\"dn\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionRowColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_rwColActionType\" use=\"required\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionMove\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"source\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"destination\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"sourceSheetId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCustomView\">\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionSheetRename\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"oldName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"newName\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionInsertSheet\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetPosition\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCellChange\">\n    <xsd:sequence>\n      <xsd:element name=\"oc\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nc\" type=\"CT_Cell\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"odxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ndxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"odxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldQuotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"oldPh\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"endOfListFormulaUpdate\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionAutoFormatting\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionComment\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"cell\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" default=\"add\"/>\n    <xsd:attribute name=\"alwaysShow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"author\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"oldLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"newLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionDefinedName\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oldFormula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"customView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldFunction\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldFunctionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"shortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldShortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldHidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldCustomMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldDescription\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldHelp\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldStatusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldComment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionConflict\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionQueryTableField\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"fieldId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_rwColActionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertRow\"/>\n      <xsd:enumeration value=\"deleteRow\"/>\n      <xsd:enumeration value=\"insertCol\"/>\n      <xsd:enumeration value=\"deleteCol\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RevisionAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"add\"/>\n      <xsd:enumeration value=\"delete\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormulaExpression\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ref\"/>\n      <xsd:enumeration value=\"refError\"/>\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"areaError\"/>\n      <xsd:enumeration value=\"computedArea\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"users\" type=\"CT_Users\"/>\n  <xsd:complexType name=\"CT_Users\">\n    <xsd:sequence>\n      <xsd:element name=\"userInfo\" minOccurs=\"0\" maxOccurs=\"256\" type=\"CT_SharedUser\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedUser\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"worksheet\" type=\"CT_Worksheet\"/>\n  <xsd:element name=\"chartsheet\" type=\"CT_Chartsheet\"/>\n  <xsd:element name=\"dialogsheet\" type=\"CT_Dialogsheet\"/>\n  <xsd:complexType name=\"CT_Macrosheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dialogsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" minOccurs=\"0\" type=\"CT_SheetPr\"/>\n      <xsd:element name=\"sheetViews\" minOccurs=\"0\" type=\"CT_SheetViews\"/>\n      <xsd:element name=\"sheetFormatPr\" minOccurs=\"0\" type=\"CT_SheetFormatPr\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" minOccurs=\"0\" type=\"CT_CustomSheetViews\"/>\n      <xsd:element name=\"printOptions\" minOccurs=\"0\" type=\"CT_PrintOptions\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" minOccurs=\"0\" type=\"CT_PageSetup\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" minOccurs=\"0\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"legacyDrawing\" minOccurs=\"0\" type=\"CT_LegacyDrawing\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Worksheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetCalcPr\" type=\"CT_SheetCalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protectedRanges\" type=\"CT_ProtectedRanges\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scenarios\" type=\"CT_Scenarios\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mergeCells\" type=\"CT_MergeCells\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dataValidations\" type=\"CT_DataValidations\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hyperlinks\" type=\"CT_Hyperlinks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellWatches\" type=\"CT_CellWatches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ignoredErrors\" type=\"CT_IgnoredErrors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableParts\" type=\"CT_TableParts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetCalcPr\">\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetFormatPr\">\n    <xsd:attribute name=\"baseColWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"8\"/>\n    <xsd:attribute name=\"defaultColWidth\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultRowHeight\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zeroHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevelRow\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"outlineLevelCol\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cols\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"CT_Col\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Col\">\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bestFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"phonetic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellSpan\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellSpans\">\n    <xsd:list itemType=\"ST_CellSpan\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spans\" type=\"ST_CellSpans\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"customFormat\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ht\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cell\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_CellFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"is\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"cm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"inlineStr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellFormulaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"array\"/>\n      <xsd:enumeration value=\"dataTable\"/>\n      <xsd:enumeration value=\"shared\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlinePr\" type=\"CT_OutlinePr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetUpPr\" type=\"CT_PageSetUpPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"syncHorizontal\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncVertical\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"transitionEvaluation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"transitionEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filterMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableFormatConditionsCalculation\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetDimension\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_SheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"pivotSelection\" type=\"CT_PivotSelection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"windowProtection\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowColHeaders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showZeros\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rightToLeft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultGridColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showWhiteSpace\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" use=\"optional\" default=\"normal\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"64\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"zoomScaleNormal\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScaleSheetLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScalePageLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pane\">\n    <xsd:attribute name=\"xSplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ySplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activePane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"state\" type=\"ST_PaneState\" use=\"optional\" default=\"split\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSelection\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"showHeader\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"label\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"extendable\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"dimension\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"click\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Selection\">\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"activeCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activeCellId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\" default=\"A1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bottomRight\"/>\n      <xsd:enumeration value=\"topRight\"/>\n      <xsd:enumeration value=\"bottomLeft\"/>\n      <xsd:enumeration value=\"topLeft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"brk\" type=\"CT_Break\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"manualBreakCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Break\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"man\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetViewType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"pageBreakPreview\"/>\n      <xsd:enumeration value=\"pageLayout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OutlinePr\">\n    <xsd:attribute name=\"applyStyles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"summaryBelow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"summaryRight\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetUpPr\">\n    <xsd:attribute name=\"autoPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataConsolidate\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRefs\" type=\"CT_DataRefs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"function\" type=\"ST_DataConsolidateFunction\" use=\"optional\" default=\"sum\"/>\n    <xsd:attribute name=\"startLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"leftLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"topLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"link\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataConsolidateFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevp\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varp\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DataRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRef\" type=\"CT_DataRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataRef\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCells\">\n    <xsd:sequence>\n      <xsd:element name=\"mergeCell\" type=\"CT_MergeCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCell\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTags\" type=\"CT_CellSmartTags\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTag\" type=\"CT_CellSmartTag\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTag\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTagPr\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CellSmartTagPr\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlBased\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTagPr\">\n    <xsd:attribute name=\"key\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LegacyDrawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DrawingHF\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"lho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"che\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"chf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomSheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" default=\"64\"/>\n    <xsd:attribute name=\"showPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"outlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"zeroValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"printArea\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAutoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"filterUnique\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" default=\"normal\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidations\">\n    <xsd:sequence>\n      <xsd:element name=\"dataValidation\" type=\"CT_DataValidation\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"disablePrompts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidation\">\n    <xsd:sequence>\n      <xsd:element name=\"formula1\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formula2\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_DataValidationType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"errorStyle\" type=\"ST_DataValidationErrorStyle\" use=\"optional\"\n      default=\"stop\"/>\n    <xsd:attribute name=\"imeMode\" type=\"ST_DataValidationImeMode\" use=\"optional\" default=\"noControl\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_DataValidationOperator\" use=\"optional\" default=\"between\"/>\n    <xsd:attribute name=\"allowBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showDropDown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInputMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showErrorMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errorTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"error\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"promptTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"prompt\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataValidationType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"list\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"time\"/>\n      <xsd:enumeration value=\"textLength\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationErrorStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stop\"/>\n      <xsd:enumeration value=\"warning\"/>\n      <xsd:enumeration value=\"information\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationImeMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"disabled\"/>\n      <xsd:enumeration value=\"hiragana\"/>\n      <xsd:enumeration value=\"fullKatakana\"/>\n      <xsd:enumeration value=\"halfKatakana\"/>\n      <xsd:enumeration value=\"fullAlpha\"/>\n      <xsd:enumeration value=\"halfAlpha\"/>\n      <xsd:enumeration value=\"fullHangul\"/>\n      <xsd:enumeration value=\"halfHangul\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"expression\"/>\n      <xsd:enumeration value=\"cellIs\"/>\n      <xsd:enumeration value=\"colorScale\"/>\n      <xsd:enumeration value=\"dataBar\"/>\n      <xsd:enumeration value=\"iconSet\"/>\n      <xsd:enumeration value=\"top10\"/>\n      <xsd:enumeration value=\"uniqueValues\"/>\n      <xsd:enumeration value=\"duplicateValues\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContainsText\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n      <xsd:enumeration value=\"containsBlanks\"/>\n      <xsd:enumeration value=\"notContainsBlanks\"/>\n      <xsd:enumeration value=\"containsErrors\"/>\n      <xsd:enumeration value=\"notContainsErrors\"/>\n      <xsd:enumeration value=\"timePeriod\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TimePeriod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"last7Days\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConditionalFormattingOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContains\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfvoType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"formula\"/>\n      <xsd:enumeration value=\"percentile\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ConditionalFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"cfRule\" type=\"CT_CfRule\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CfRule\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"3\"/>\n      <xsd:element name=\"colorScale\" type=\"CT_ColorScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataBar\" type=\"CT_DataBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconSet\" type=\"CT_IconSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfType\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"priority\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"stopIfTrue\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"aboveAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_ConditionalFormattingOperator\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"timePeriod\" type=\"ST_TimePeriod\" use=\"optional\"/>\n    <xsd:attribute name=\"rank\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"stdDev\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"equalAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlinks\">\n    <xsd:sequence>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"location\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"t\" type=\"ST_CellFormulaType\" use=\"optional\" default=\"normal\"/>\n        <xsd:attribute name=\"aca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n        <xsd:attribute name=\"dt2D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"dtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del1\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del2\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"r1\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"r2\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"ca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"bx\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorScale\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBar\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"minLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"10\"/>\n    <xsd:attribute name=\"maxLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"90\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconSet\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3TrafficLights1\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"reverse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cfvo\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfvoType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"gte\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintOptions\">\n    <xsd:attribute name=\"horizontalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"verticalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headings\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLinesSet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToHeight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"pageOrder\" type=\"ST_PageOrder\" use=\"optional\" default=\"downThenOver\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellComments\" type=\"ST_CellComments\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errors\" type=\"ST_PrintError\" use=\"optional\" default=\"displayed\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"downThenOver\"/>\n      <xsd:enumeration value=\"overThenDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellComments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"asDisplayed\"/>\n      <xsd:enumeration value=\"atEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"scaleWithDoc\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintError\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"displayed\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"NA\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Scenarios\">\n    <xsd:sequence>\n      <xsd:element name=\"scenario\" type=\"CT_Scenario\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"current\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scenarios\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formatCells\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertHyperlinks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectLockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"pivotTables\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectUnlockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRanges\">\n    <xsd:sequence>\n      <xsd:element name=\"protectedRange\" type=\"CT_ProtectedRange\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRange\">\n    <xsd:sequence>\n      <xsd:element name=\"securityDescriptor\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"securityDescriptor\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scenario\">\n    <xsd:sequence>\n      <xsd:element name=\"inputCells\" type=\"CT_InputCells\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"user\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InputCells\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"undone\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatches\">\n    <xsd:sequence>\n      <xsd:element name=\"cellWatch\" type=\"CT_CellWatch\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatch\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chartsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_ChartsheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_ChartsheetViews\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_ChartsheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomChartsheetViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_ChartsheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" default=\"100\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"content\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CsPageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomChartsheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"customPr\" type=\"CT_CustomProperty\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"oleObject\" type=\"CT_OleObject\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:element name=\"objectPr\" type=\"CT_ObjectPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dvAspect\" type=\"ST_DvAspect\" use=\"optional\" default=\"DVASPECT_CONTENT\"/>\n    <xsd:attribute name=\"link\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oleUpdate\" type=\"ST_OleUpdate\" use=\"optional\"/>\n    <xsd:attribute name=\"autoLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dde\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DvAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"DVASPECT_CONTENT\"/>\n      <xsd:enumeration value=\"DVASPECT_ICON\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OleUpdate\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"OLEUPDATE_ALWAYS\"/>\n      <xsd:enumeration value=\"OLEUPDATE_ONCALL\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebPublishItems\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishItem\" type=\"CT_WebPublishItem\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishItem\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceType\" type=\"ST_WebSourceType\" use=\"required\"/>\n    <xsd:attribute name=\"sourceRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Controls\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"controlPr\" type=\"CT_ControlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"recalcAlways\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"linkedCell\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"listFillRange\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"cf\" type=\"s:ST_Xstring\" use=\"optional\" default=\"pict\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sheet\"/>\n      <xsd:enumeration value=\"printArea\"/>\n      <xsd:enumeration value=\"autoFilter\"/>\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"pivotTable\"/>\n      <xsd:enumeration value=\"query\"/>\n      <xsd:enumeration value=\"label\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IgnoredErrors\">\n    <xsd:sequence>\n      <xsd:element name=\"ignoredError\" type=\"CT_IgnoredError\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IgnoredError\">\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"evalError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"twoDigitTextYear\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numberStoredAsText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formulaRange\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"unlockedFormula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"emptyCellReference\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"listDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calculatedColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PaneState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"split\"/>\n      <xsd:enumeration value=\"frozen\"/>\n      <xsd:enumeration value=\"frozenSplit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableParts\">\n    <xsd:sequence>\n      <xsd:element name=\"tablePart\" type=\"CT_TablePart\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePart\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"metadata\" type=\"CT_Metadata\"/>\n  <xsd:complexType name=\"CT_Metadata\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataTypes\" type=\"CT_MetadataTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"metadataStrings\" type=\"CT_MetadataStrings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mdxMetadata\" type=\"CT_MdxMetadata\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"futureMetadata\" type=\"CT_FutureMetadata\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"cellMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"valueMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataType\" type=\"CT_MetadataType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataType\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"minSupportedVersion\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ghostRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ghostCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"edit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"delete\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"copy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteValues\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteBorders\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteColWidths\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteNumberFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"merge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitFirst\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"rowColShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearAll\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"clearFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearContents\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"assign\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"coerce\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"adjust\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellMeta\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlocks\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_MetadataBlock\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"rc\" type=\"CT_MetadataRecord\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataRecord\">\n    <xsd:attribute name=\"t\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_FutureMetadataBlock\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"mdx\" type=\"CT_Mdx\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Mdx\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"t\" type=\"CT_MdxTuple\"/>\n      <xsd:element name=\"ms\" type=\"CT_MdxSet\"/>\n      <xsd:element name=\"p\" type=\"CT_MdxMemeberProp\"/>\n      <xsd:element name=\"k\" type=\"CT_MdxKPI\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"f\" type=\"ST_MdxFunctionType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxFunctionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"m\"/>\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"c\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"k\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxTuple\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ct\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"fi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxSet\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ns\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"o\" type=\"ST_MdxSetOrder\" use=\"optional\" default=\"u\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxSetOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"a\"/>\n      <xsd:enumeration value=\"d\"/>\n      <xsd:enumeration value=\"aa\"/>\n      <xsd:enumeration value=\"ad\"/>\n      <xsd:enumeration value=\"na\"/>\n      <xsd:enumeration value=\"nd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxMemeberProp\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxKPI\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"p\" type=\"ST_MdxKPIProperty\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxKPIProperty\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"g\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"m\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MetadataStringIndex\">\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataStrings\">\n    <xsd:sequence>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"singleXmlCells\" type=\"CT_SingleXmlCells\"/>\n  <xsd:complexType name=\"CT_SingleXmlCells\">\n    <xsd:sequence>\n      <xsd:element name=\"singleXmlCell\" type=\"CT_SingleXmlCell\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SingleXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlCellPr\" type=\"CT_XmlCellPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlCellPr\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlPr\" type=\"CT_XmlPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleSheet\" type=\"CT_Stylesheet\"/>\n  <xsd:complexType name=\"CT_Stylesheet\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmts\" type=\"CT_NumFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fonts\" type=\"CT_Fonts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fills\" type=\"CT_Fills\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"borders\" type=\"CT_Borders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyleXfs\" type=\"CT_CellStyleXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellXfs\" type=\"CT_CellXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyles\" type=\"CT_CellStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dxfs\" type=\"CT_Dxfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyles\" type=\"CT_TableStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colors\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellAlignment\">\n    <xsd:attribute name=\"horizontal\" type=\"ST_HorizontalAlignment\" use=\"optional\"/>\n    <xsd:attribute name=\"vertical\" type=\"ST_VerticalAlignment\" default=\"bottom\" use=\"optional\"/>\n    <xsd:attribute name=\"textRotation\" type=\"ST_TextRotation\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapText\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"relativeIndent\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"justifyLastLine\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"shrinkToFit\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"readingOrder\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextRotation\">\n    <xsd:union>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:maxInclusive value=\"180\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:enumeration value=\"255\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:union>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"thin\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hair\"/>\n      <xsd:enumeration value=\"mediumDashed\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"mediumDashDot\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"mediumDashDotDot\"/>\n      <xsd:enumeration value=\"slantDashDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Borders\">\n    <xsd:sequence>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"top\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"diagonal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertical\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"horizontal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"diagonalUp\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"diagonalDown\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderPr\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"style\" type=\"ST_BorderStyle\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellProtection\">\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fills\">\n    <xsd:sequence>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"patternFill\" type=\"CT_PatternFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradientFill\" type=\"CT_GradientFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PatternFill\">\n    <xsd:sequence>\n      <xsd:element name=\"fgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"patternType\" type=\"ST_PatternType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"auto\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indexed\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"theme\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tint\" type=\"xsd:double\" use=\"optional\" default=\"0.0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PatternType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"mediumGray\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"darkHorizontal\"/>\n      <xsd:enumeration value=\"darkVertical\"/>\n      <xsd:enumeration value=\"darkDown\"/>\n      <xsd:enumeration value=\"darkUp\"/>\n      <xsd:enumeration value=\"darkGrid\"/>\n      <xsd:enumeration value=\"darkTrellis\"/>\n      <xsd:enumeration value=\"lightHorizontal\"/>\n      <xsd:enumeration value=\"lightVertical\"/>\n      <xsd:enumeration value=\"lightDown\"/>\n      <xsd:enumeration value=\"lightUp\"/>\n      <xsd:enumeration value=\"lightGrid\"/>\n      <xsd:enumeration value=\"lightTrellis\"/>\n      <xsd:enumeration value=\"gray125\"/>\n      <xsd:enumeration value=\"gray0625\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientFill\">\n    <xsd:sequence>\n      <xsd:element name=\"stop\" type=\"CT_GradientStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_GradientType\" use=\"optional\" default=\"linear\"/>\n    <xsd:attribute name=\"degree\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"position\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GradientType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"path\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"fill\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"centerContinuous\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyleXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Xf\">\n    <xsd:sequence>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"optional\"/>\n    <xsd:attribute name=\"fillId\" type=\"ST_FillId\" use=\"optional\"/>\n    <xsd:attribute name=\"borderId\" type=\"ST_BorderId\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pivotButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"applyNumberFormat\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFont\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFill\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyBorder\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyAlignment\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyProtection\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"cellStyle\" type=\"CT_CellStyle\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"required\"/>\n    <xsd:attribute name=\"builtinId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iLevel\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"customBuiltin\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxfs\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxf\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumFmtId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellStyleXfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DxfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:element name=\"indexedColors\" type=\"CT_IndexedColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mruColors\" type=\"CT_MRUColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IndexedColors\">\n    <xsd:sequence>\n      <xsd:element name=\"rgbColor\" type=\"CT_RgbColor\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MRUColors\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RgbColor\">\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultTableStyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultPivotStyle\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyleElement\" type=\"CT_TableStyleElement\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"table\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TableStyleType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableStyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"headerRow\"/>\n      <xsd:enumeration value=\"totalRow\"/>\n      <xsd:enumeration value=\"firstColumn\"/>\n      <xsd:enumeration value=\"lastColumn\"/>\n      <xsd:enumeration value=\"firstRowStripe\"/>\n      <xsd:enumeration value=\"secondRowStripe\"/>\n      <xsd:enumeration value=\"firstColumnStripe\"/>\n      <xsd:enumeration value=\"secondColumnStripe\"/>\n      <xsd:enumeration value=\"firstHeaderCell\"/>\n      <xsd:enumeration value=\"lastHeaderCell\"/>\n      <xsd:enumeration value=\"firstTotalCell\"/>\n      <xsd:enumeration value=\"lastTotalCell\"/>\n      <xsd:enumeration value=\"firstSubtotalColumn\"/>\n      <xsd:enumeration value=\"secondSubtotalColumn\"/>\n      <xsd:enumeration value=\"thirdSubtotalColumn\"/>\n      <xsd:enumeration value=\"firstSubtotalRow\"/>\n      <xsd:enumeration value=\"secondSubtotalRow\"/>\n      <xsd:enumeration value=\"thirdSubtotalRow\"/>\n      <xsd:enumeration value=\"blankRow\"/>\n      <xsd:enumeration value=\"firstColumnSubheading\"/>\n      <xsd:enumeration value=\"secondColumnSubheading\"/>\n      <xsd:enumeration value=\"thirdColumnSubheading\"/>\n      <xsd:enumeration value=\"firstRowSubheading\"/>\n      <xsd:enumeration value=\"secondRowSubheading\"/>\n      <xsd:enumeration value=\"thirdRowSubheading\"/>\n      <xsd:enumeration value=\"pageFieldLabels\"/>\n      <xsd:enumeration value=\"pageFieldValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BooleanProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSize\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IntProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignFontProperty\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:attribute name=\"val\" type=\"ST_FontScheme\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontScheme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnderlineProperty\">\n    <xsd:attribute name=\"val\" type=\"ST_UnderlineValues\" use=\"optional\" default=\"single\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnderlineValues\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"singleAccounting\"/>\n      <xsd:enumeration value=\"doubleAccounting\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"14\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_AutoFormat\">\n    <xsd:attribute name=\"autoFormatId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"applyNumberFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyBorderFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyFontFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyPatternFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyAlignmentFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyWidthHeightFormats\" type=\"xsd:boolean\"/>\n  </xsd:attributeGroup>\n  <xsd:element name=\"externalLink\" type=\"CT_ExternalLink\"/>\n  <xsd:complexType name=\"CT_ExternalLink\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"externalBook\" type=\"CT_ExternalBook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ddeLink\" type=\"CT_DdeLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"oleLink\" type=\"CT_OleLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalBook\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetNames\" type=\"CT_ExternalSheetNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_ExternalDefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetDataSet\" type=\"CT_ExternalSheetDataSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetNames\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetName\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_ExternalSheetName\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_ExternalDefinedName\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedName\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"refersTo\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetDataSet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetData\" type=\"CT_ExternalSheetData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_ExternalRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"refreshError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalRow\">\n    <xsd:sequence>\n      <xsd:element name=\"cell\" type=\"CT_ExternalCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalCell\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeLink\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItems\" type=\"CT_DdeItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ddeService\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"ddeTopic\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItems\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItem\" type=\"CT_DdeItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItem\">\n    <xsd:sequence>\n      <xsd:element name=\"values\" type=\"CT_DdeValues\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" default=\"0\"/>\n    <xsd:attribute name=\"ole\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValues\">\n    <xsd:sequence>\n      <xsd:element name=\"value\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_DdeValue\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rows\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cols\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_DdeValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DdeValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"str\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleLink\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItems\" type=\"CT_OleItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItems\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItem\" type=\"CT_OleItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"icon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"table\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableColumns\" type=\"CT_TableColumns\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyleInfo\" type=\"CT_TableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"displayName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"tableType\" type=\"ST_TableType\" use=\"optional\" default=\"worksheet\"/>\n    <xsd:attribute name=\"headerRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"insertRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"insertRowShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"totalsRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"totalsRowShown\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"tableBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"xml\"/>\n      <xsd:enumeration value=\"queryTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleInfo\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showFirstColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showColumnStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumns\">\n    <xsd:sequence>\n      <xsd:element name=\"tableColumn\" type=\"CT_TableColumn\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumn\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedColumnFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"totalsRowFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xmlColumnPr\" type=\"CT_XmlColumnPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"totalsRowFunction\" type=\"ST_TotalsRowFunction\" use=\"optional\"\n      default=\"none\"/>\n    <xsd:attribute name=\"totalsRowLabel\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"queryTableFieldId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"array\" type=\"xsd:boolean\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TotalsRowFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XmlColumnPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"denormalized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_XmlDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:element name=\"volTypes\" type=\"CT_VolTypes\"/>\n  <xsd:complexType name=\"CT_VolTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"volType\" type=\"CT_VolType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolType\">\n    <xsd:sequence>\n      <xsd:element name=\"main\" type=\"CT_VolMain\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_VolDepType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolMain\">\n    <xsd:sequence>\n      <xsd:element name=\"tp\" type=\"CT_VolTopic\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"first\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopic\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stp\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tr\" type=\"CT_VolTopicRef\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_VolValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopicRef\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VolDepType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"realTimeData\"/>\n      <xsd:enumeration value=\"olapFunctions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VolValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"workbook\" type=\"CT_Workbook\"/>\n  <xsd:complexType name=\"CT_Workbook\">\n    <xsd:sequence>\n      <xsd:element name=\"fileVersion\" type=\"CT_FileVersion\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileSharing\" type=\"CT_FileSharing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookPr\" type=\"CT_WorkbookPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookProtection\" type=\"CT_WorkbookProtection\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"bookViews\" type=\"CT_BookViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheets\" type=\"CT_Sheets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"functionGroups\" type=\"CT_FunctionGroups\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalReferences\" type=\"CT_ExternalReferences\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_DefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"calcPr\" type=\"CT_CalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleSize\" type=\"CT_OleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customWorkbookViews\" type=\"CT_CustomWorkbookViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotCaches\" type=\"CT_PivotCaches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagTypes\" type=\"CT_SmartTagTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishing\" type=\"CT_WebPublishing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileRecoveryPr\" type=\"CT_FileRecoveryPr\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"webPublishObjects\" type=\"CT_WebPublishObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileVersion\">\n    <xsd:attribute name=\"appName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lastEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lowestEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rupBuild\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"codeName\" type=\"s:ST_Guid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"workbookView\" type=\"CT_BookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"visibility\" type=\"ST_Visibility\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"firstSheet\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"activeTab\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"autoFilterDateGrouping\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Visibility\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CustomWorkbookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customWorkbookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomWorkbookView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomWorkbookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"autoUpdate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"mergeInterval\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"changesSavedWin\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"onlySync\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"personalView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"includePrintSettings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"includeHiddenRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"maximized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"activeSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"showFormulaBar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showStatusbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showComments\" type=\"ST_Comments\" use=\"optional\" default=\"commIndicator\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Comments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"commNone\"/>\n      <xsd:enumeration value=\"commIndicator\"/>\n      <xsd:enumeration value=\"commIndAndComment\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Objects\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"placeholders\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Sheets\">\n    <xsd:sequence>\n      <xsd:element name=\"sheet\" type=\"CT_Sheet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sheet\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorkbookPr\">\n    <xsd:attribute name=\"date1904\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"showBorderUnselectedTables\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n    <xsd:attribute name=\"filterPrivacy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"promptedSolutions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInkAnnotation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"backupFile\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveExternalLinkValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"updateLinks\" type=\"ST_UpdateLinks\" use=\"optional\" default=\"userSet\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hidePivotFieldList\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPivotChartFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"allowRefreshQuery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"publishItems\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"checkCompatibility\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshAllConnections\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultThemeVersion\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UpdateLinks\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"userSet\"/>\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:attribute name=\"embed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"show\" type=\"ST_SmartTagShow\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SmartTagShow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"noIndicator\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceUri\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileRecoveryPr\">\n    <xsd:attribute name=\"autoRecover\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"crashSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dataExtractLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"repairLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcPr\">\n    <xsd:attribute name=\"calcId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"calcMode\" type=\"ST_CalcMode\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refMode\" type=\"ST_RefMode\" use=\"optional\" default=\"A1\"/>\n    <xsd:attribute name=\"iterate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"iterateCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"iterateDelta\" type=\"xsd:double\" use=\"optional\" default=\"0.001\"/>\n    <xsd:attribute name=\"fullPrecision\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcCompleted\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentCalc\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentManualCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"forceFullCalc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CalcMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"autoNoTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"A1\"/>\n      <xsd:enumeration value=\"R1C1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_DefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefinedName\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n        <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"vbProcedure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"xlm\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"shortcutKey\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"publishToServer\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"workbookParameter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"externalReference\" type=\"CT_ExternalReference\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReference\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetBackgroundPicture\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCaches\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotCache\" type=\"CT_PivotCache\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCache\">\n    <xsd:attribute name=\"cacheId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileSharing\">\n    <xsd:attribute name=\"readOnlyRecommended\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"reservationPassword\" type=\"ST_UnsignedShortHex\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleSize\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WorkbookProtection\">\n    <xsd:attribute name=\"workbookPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lockStructure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockWindows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockRevision\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"revisionsAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishing\">\n    <xsd:attribute name=\"css\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"thicket\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"longFileNames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"vml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"targetScreenSize\" type=\"ST_TargetScreenSize\" use=\"optional\"\n      default=\"800x600\"/>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"96\"/>\n    <xsd:attribute name=\"codePage\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FunctionGroups\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"functionGroup\" type=\"CT_FunctionGroup\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"builtInGroupCount\" type=\"xsd:unsignedInt\" default=\"16\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FunctionGroup\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishObject\" type=\"CT_WebPublishObject\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObject\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:schemas-microsoft-com:vml\"\n  xmlns:pvml=\"urn:schemas-microsoft-com:office:powerpoint\"\n  xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:w10=\"urn:schemas-microsoft-com:office:word\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:vml\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:office\"\n    schemaLocation=\"vml-officeDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:word\"\n    schemaLocation=\"vml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:excel\"\n    schemaLocation=\"vml-spreadsheetDrawing.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:powerpoint\"\n    schemaLocation=\"vml-presentationDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attributeGroup name=\"AG_Id\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Style\">\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Type\">\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Adj\">\n    <xsd:attribute name=\"adj\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Path\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Fill\">\n    <xsd:attribute name=\"filled\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Chromakey\">\n    <xsd:attribute name=\"chromakey\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Ext\">\n    <xsd:attribute name=\"ext\" form=\"qualified\" type=\"ST_Ext\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_CoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"href\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"class\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"alt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordsize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"print\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"stroked\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeweight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeCoreAttributes\">\n    <xsd:attribute ref=\"o:spid\"/>\n    <xsd:attribute ref=\"o:oned\"/>\n    <xsd:attribute ref=\"o:regroupid\"/>\n    <xsd:attribute ref=\"o:doubleclicknotify\"/>\n    <xsd:attribute ref=\"o:button\"/>\n    <xsd:attribute ref=\"o:userhidden\"/>\n    <xsd:attribute ref=\"o:bullet\"/>\n    <xsd:attribute ref=\"o:hr\"/>\n    <xsd:attribute ref=\"o:hrstd\"/>\n    <xsd:attribute ref=\"o:hrnoshade\"/>\n    <xsd:attribute ref=\"o:hrpct\"/>\n    <xsd:attribute ref=\"o:hralign\"/>\n    <xsd:attribute ref=\"o:allowincell\"/>\n    <xsd:attribute ref=\"o:allowoverlap\"/>\n    <xsd:attribute ref=\"o:userdrawn\"/>\n    <xsd:attribute ref=\"o:bordertopcolor\"/>\n    <xsd:attribute ref=\"o:borderleftcolor\"/>\n    <xsd:attribute ref=\"o:borderbottomcolor\"/>\n    <xsd:attribute ref=\"o:borderrightcolor\"/>\n    <xsd:attribute ref=\"o:dgmlayout\"/>\n    <xsd:attribute ref=\"o:dgmnodekind\"/>\n    <xsd:attribute ref=\"o:dgmlayoutmru\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeShapeAttributes\">\n    <xsd:attribute ref=\"o:spt\"/>\n    <xsd:attribute ref=\"o:connectortype\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"o:oleicon\"/>\n    <xsd:attribute ref=\"o:ole\"/>\n    <xsd:attribute ref=\"o:preferrelative\"/>\n    <xsd:attribute ref=\"o:cliptowrap\"/>\n    <xsd:attribute ref=\"o:clip\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllCoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_CoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeCoreAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_ShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeShapeAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ImageAttributes\">\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropleft\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"croptop\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropright\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropbottom\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gain\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"blacklevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gamma\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"grayscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"bilevel\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_StrokeAttributes\">\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n  </xsd:attributeGroup>\n  <xsd:group name=\"EG_ShapeElements\">\n    <xsd:choice>\n      <xsd:element ref=\"path\"/>\n      <xsd:element ref=\"formulas\"/>\n      <xsd:element ref=\"handles\"/>\n      <xsd:element ref=\"fill\"/>\n      <xsd:element ref=\"stroke\"/>\n      <xsd:element ref=\"shadow\"/>\n      <xsd:element ref=\"textbox\"/>\n      <xsd:element ref=\"textpath\"/>\n      <xsd:element ref=\"imagedata\"/>\n      <xsd:element ref=\"o:skew\"/>\n      <xsd:element ref=\"o:extrusion\"/>\n      <xsd:element ref=\"o:callout\"/>\n      <xsd:element ref=\"o:lock\"/>\n      <xsd:element ref=\"o:clippath\"/>\n      <xsd:element ref=\"o:signatureline\"/>\n      <xsd:element ref=\"w10:wrap\"/>\n      <xsd:element ref=\"w10:anchorlock\"/>\n      <xsd:element ref=\"w10:bordertop\"/>\n      <xsd:element ref=\"w10:borderbottom\"/>\n      <xsd:element ref=\"w10:borderleft\"/>\n      <xsd:element ref=\"w10:borderright\"/>\n      <xsd:element ref=\"x:ClientData\" minOccurs=\"0\"/>\n      <xsd:element ref=\"pvml:textdata\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"shape\" type=\"CT_Shape\"/>\n  <xsd:element name=\"shapetype\" type=\"CT_Shapetype\"/>\n  <xsd:element name=\"group\" type=\"CT_Group\"/>\n  <xsd:element name=\"background\" type=\"CT_Background\"/>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n      <xsd:element ref=\"pvml:iscomment\"/>\n      <xsd:element ref=\"o:equationxml\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Type\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:gfxdata\"/>\n    <xsd:attribute name=\"equationxml\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shapetype\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"o:complex\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:master\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Group\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"group\"/>\n      <xsd:element ref=\"shape\"/>\n      <xsd:element ref=\"shapetype\"/>\n      <xsd:element ref=\"arc\"/>\n      <xsd:element ref=\"curve\"/>\n      <xsd:element ref=\"image\"/>\n      <xsd:element ref=\"line\"/>\n      <xsd:element ref=\"oval\"/>\n      <xsd:element ref=\"polyline\"/>\n      <xsd:element ref=\"rect\"/>\n      <xsd:element ref=\"roundrect\"/>\n      <xsd:element ref=\"o:diagram\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"editas\" type=\"ST_EditAs\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:tableproperties\"/>\n    <xsd:attribute ref=\"o:tablelimits\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:element ref=\"fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:targetscreensize\"/>\n  </xsd:complexType>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:element name=\"formulas\" type=\"CT_Formulas\"/>\n  <xsd:element name=\"handles\" type=\"CT_Handles\"/>\n  <xsd:element name=\"imagedata\" type=\"CT_ImageData\"/>\n  <xsd:element name=\"path\" type=\"CT_Path\"/>\n  <xsd:element name=\"textbox\" type=\"CT_Textbox\"/>\n  <xsd:element name=\"shadow\" type=\"CT_Shadow\"/>\n  <xsd:element name=\"stroke\" type=\"CT_Stroke\"/>\n  <xsd:element name=\"textpath\" type=\"CT_TextPath\"/>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"position\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"aspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"alignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"focus\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focussize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focusposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"method\" type=\"ST_FillMethod\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:opacity2\"/>\n    <xsd:attribute name=\"recolor\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotate\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formulas\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_F\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:attribute name=\"eqn\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Handles\">\n    <xsd:sequence>\n      <xsd:element name=\"h\" type=\"CT_H\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_H\">\n    <xsd:attribute name=\"position\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"polar\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"map\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"invx\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"invy\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"switch\" type=\"s:ST_TrueFalseBlank\"/>\n    <xsd:attribute name=\"xrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"yrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"radiusrange\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ImageData\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attribute name=\"embosscolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"recolortarget\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:oleid\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:movie\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n    <xsd:attribute ref=\"r:id\"/>\n    <xsd:attribute ref=\"r:pict\"/>\n    <xsd:attribute ref=\"r:href\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"limo\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textboxrect\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fillok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shadowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"arrowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"gradientshapeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textpathok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpenok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:connecttype\"/>\n    <xsd:attribute ref=\"o:connectlocs\"/>\n    <xsd:attribute ref=\"o:connectangles\"/>\n    <xsd:attribute ref=\"o:extrusionok\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shadow\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ShadowType\" use=\"optional\"/>\n    <xsd:attribute name=\"obscured\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"offset2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Stroke\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:left\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:top\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:right\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:bottom\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:column\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_StrokeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Textbox\">\n    <xsd:choice>\n      <xsd:element ref=\"w:txbxContent\" minOccurs=\"0\"/>\n      <xsd:any namespace=\"##local\" processContents=\"skip\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"inset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:singleclick\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextPath\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitpath\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"trim\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"xscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"string\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"arc\" type=\"CT_Arc\"/>\n  <xsd:element name=\"curve\" type=\"CT_Curve\"/>\n  <xsd:element name=\"image\" type=\"CT_Image\"/>\n  <xsd:element name=\"line\" type=\"CT_Line\"/>\n  <xsd:element name=\"oval\" type=\"CT_Oval\"/>\n  <xsd:element name=\"polyline\" type=\"CT_PolyLine\"/>\n  <xsd:element name=\"rect\" type=\"CT_Rect\"/>\n  <xsd:element name=\"roundrect\" type=\"CT_RoundRect\"/>\n  <xsd:complexType name=\"CT_Arc\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"startAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"endAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Curve\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control1\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Image\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Oval\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolyLine\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"points\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RoundRect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"arcsize\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Ext\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"view\"/>\n      <xsd:enumeration value=\"edit\"/>\n      <xsd:enumeration value=\"backwardCompatible\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"frame\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"sigma\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"linear sigma\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ShadowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"emboss\"/>\n      <xsd:enumeration value=\"perspective\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeLineStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thinThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeJoinStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"miter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeEndCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"round\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowLength\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"short\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"long\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"narrow\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"wide\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"block\"/>\n      <xsd:enumeration value=\"classic\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"open\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ImageAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ignore\"/>\n      <xsd:enumeration value=\"atMost\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"canvas\"/>\n      <xsd:enumeration value=\"orgchart\"/>\n      <xsd:enumeration value=\"radial\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"stacked\"/>\n      <xsd:enumeration value=\"venn\"/>\n      <xsd:enumeration value=\"bullseye\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:office\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:vml\" schemaLocation=\"vml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attribute name=\"bwmode\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwpure\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwnormal\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"targetscreensize\" type=\"ST_ScreenSize\"/>\n  <xsd:attribute name=\"insetmode\" type=\"ST_InsetMode\" default=\"custom\"/>\n  <xsd:attribute name=\"spt\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"oned\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"regroupid\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"doubleclicknotify\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"connectortype\" type=\"ST_ConnectorType\" default=\"straight\"/>\n  <xsd:attribute name=\"button\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userhidden\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"forcedash\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleicon\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"ole\" type=\"s:ST_TrueFalseBlank\"/>\n  <xsd:attribute name=\"preferrelative\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"cliptowrap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"clip\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bullet\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hr\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrstd\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrnoshade\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrpct\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"hralign\" type=\"ST_HrAlign\" default=\"left\"/>\n  <xsd:attribute name=\"allowincell\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"allowoverlap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userdrawn\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bordertopcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderleftcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderbottomcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderrightcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connecttype\" type=\"ST_ConnectType\"/>\n  <xsd:attribute name=\"connectlocs\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connectangles\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"master\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"extrusionok\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"href\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"althref\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"title\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"singleclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleid\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"detectmouseclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"movie\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"spid\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"opacity2\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"relid\" type=\"r:ST_RelationshipId\"/>\n  <xsd:attribute name=\"dgmlayout\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"dgmnodekind\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"dgmlayoutmru\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"gfxdata\" type=\"xsd:base64Binary\"/>\n  <xsd:attribute name=\"tableproperties\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"tablelimits\" type=\"xsd:string\"/>\n  <xsd:element name=\"shapedefaults\" type=\"CT_ShapeDefaults\"/>\n  <xsd:element name=\"shapelayout\" type=\"CT_ShapeLayout\"/>\n  <xsd:element name=\"signatureline\" type=\"CT_SignatureLine\"/>\n  <xsd:element name=\"ink\" type=\"CT_Ink\"/>\n  <xsd:element name=\"diagram\" type=\"CT_Diagram\"/>\n  <xsd:element name=\"equationxml\" type=\"CT_EquationXml\"/>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:all minOccurs=\"0\">\n      <xsd:element ref=\"v:fill\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:stroke\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:textbox\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:shadow\" minOccurs=\"0\"/>\n      <xsd:element ref=\"skew\" minOccurs=\"0\"/>\n      <xsd:element ref=\"extrusion\" minOccurs=\"0\"/>\n      <xsd:element ref=\"callout\" minOccurs=\"0\"/>\n      <xsd:element ref=\"lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"colormru\" minOccurs=\"0\" type=\"CT_ColorMru\"/>\n      <xsd:element name=\"colormenu\" minOccurs=\"0\" type=\"CT_ColorMenu\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"spidmax\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"stroke\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"allowincell\" form=\"qualified\" type=\"s:ST_TrueFalse\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ink\">\n    <xsd:sequence/>\n    <xsd:attribute name=\"i\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"annotation\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"contentType\" type=\"ST_ContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SignatureLine\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"issignatureline\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"provid\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"signinginstructionsset\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"allowcomments\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"showsigndate\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"suggestedsigner\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigner2\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigneremail\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"signinginstructions\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"addlxml\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"sigprovurl\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLayout\">\n    <xsd:all>\n      <xsd:element name=\"idmap\" type=\"CT_IdMap\" minOccurs=\"0\"/>\n      <xsd:element name=\"regrouptable\" type=\"CT_RegroupTable\" minOccurs=\"0\"/>\n      <xsd:element name=\"rules\" type=\"CT_Rules\" minOccurs=\"0\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IdMap\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RegroupTable\">\n    <xsd:sequence>\n      <xsd:element name=\"entry\" type=\"CT_Entry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Entry\">\n    <xsd:attribute name=\"new\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" type=\"CT_R\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"proxy\" type=\"CT_Proxy\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_RType\" use=\"optional\"/>\n    <xsd:attribute name=\"how\" type=\"ST_How\" use=\"optional\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Proxy\">\n    <xsd:attribute name=\"start\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"end\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"connectloc\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Diagram\">\n    <xsd:sequence>\n      <xsd:element name=\"relationtable\" type=\"CT_RelationTable\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"dgmstyle\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"autoformat\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"reverse\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autolayout\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscalex\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscaley\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmfontsize\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"constrainbounds\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmbasetextscale\" type=\"xsd:integer\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EquationXml\">\n    <xsd:sequence>\n      <xsd:any namespace=\"##any\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"contentType\" type=\"ST_AlternateMathContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlternateMathContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RelationTable\">\n    <xsd:sequence>\n      <xsd:element name=\"rel\" type=\"CT_Relation\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Relation\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"idsrc\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"iddest\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"idcntr\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMru\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMenu\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"shadowcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"extrusioncolor\" type=\"s:ST_ColorType\"/>\n  </xsd:complexType>\n  <xsd:element name=\"skew\" type=\"CT_Skew\"/>\n  <xsd:element name=\"extrusion\" type=\"CT_Extrusion\"/>\n  <xsd:element name=\"callout\" type=\"CT_Callout\"/>\n  <xsd:element name=\"lock\" type=\"CT_Lock\"/>\n  <xsd:element name=\"OLEObject\" type=\"CT_OLEObject\"/>\n  <xsd:element name=\"complex\" type=\"CT_Complex\"/>\n  <xsd:element name=\"left\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"top\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"right\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"bottom\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"column\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"clippath\" type=\"CT_ClipPath\"/>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:complexType name=\"CT_Skew\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extrusion\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ExtrusionType\" default=\"parallel\" use=\"optional\"/>\n    <xsd:attribute name=\"render\" type=\"ST_ExtrusionRender\" default=\"solid\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpointorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpoint\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"plane\" type=\"ST_ExtrusionPlane\" default=\"XY\" use=\"optional\"/>\n    <xsd:attribute name=\"skewangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"skewamt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"foredepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"backdepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientation\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientationangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"lockrotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autorotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationcenter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationangle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"colormode\" type=\"ST_ColorMode\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"shininess\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"specularity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"diffusity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"metal\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"facet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightface\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"brightness\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh2\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Callout\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gap\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"dropauto\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"drop\" type=\"ST_CalloutDrop\" use=\"optional\"/>\n    <xsd:attribute name=\"distance\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lengthspecified\" type=\"s:ST_TrueFalse\" default=\"f\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"accentbar\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textborder\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusx\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusy\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"position\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"selection\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"grouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"ungrouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotation\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"cropping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"verticies\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"adjusthandles\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"aspectratio\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shapetype\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OLEObject\">\n    <xsd:sequence>\n      <xsd:element name=\"LinkType\" type=\"ST_OLELinkType\" minOccurs=\"0\"/>\n      <xsd:element name=\"LockedField\" type=\"s:ST_TrueFalseBlank\" minOccurs=\"0\"/>\n      <xsd:element name=\"FieldCodes\" type=\"xsd:string\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"Type\" type=\"ST_OLEType\" use=\"optional\"/>\n    <xsd:attribute name=\"ProgID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"ShapeID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DrawAspect\" type=\"ST_OLEDrawAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"ObjectID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"UpdateMode\" type=\"ST_OLEUpdateMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Complex\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrokeChild\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"v:ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"v:ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"v:ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"v:ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"v:ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"href\"/>\n    <xsd:attribute ref=\"althref\"/>\n    <xsd:attribute ref=\"title\"/>\n    <xsd:attribute ref=\"forcedash\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipPath\">\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"required\" form=\"qualified\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"callout\"/>\n      <xsd:enumeration value=\"connector\"/>\n      <xsd:enumeration value=\"align\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_How\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"middle\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BWMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"color\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"grayScale\"/>\n      <xsd:enumeration value=\"lightGrayscale\"/>\n      <xsd:enumeration value=\"inverseGray\"/>\n      <xsd:enumeration value=\"grayOutline\"/>\n      <xsd:enumeration value=\"highContrast\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hide\"/>\n      <xsd:enumeration value=\"undrawn\"/>\n      <xsd:enumeration value=\"blackTextAndLines\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544,376\"/>\n      <xsd:enumeration value=\"640,480\"/>\n      <xsd:enumeration value=\"720,512\"/>\n      <xsd:enumeration value=\"800,600\"/>\n      <xsd:enumeration value=\"1024,768\"/>\n      <xsd:enumeration value=\"1152,862\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InsetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramLayout\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:enumeration value=\"0\"/>\n      <xsd:enumeration value=\"1\"/>\n      <xsd:enumeration value=\"2\"/>\n      <xsd:enumeration value=\"3\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"perspective\"/>\n      <xsd:enumeration value=\"parallel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionRender\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"wireFrame\"/>\n      <xsd:enumeration value=\"boundingCube\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionPlane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"XY\"/>\n      <xsd:enumeration value=\"ZX\"/>\n      <xsd:enumeration value=\"YZ\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"30\"/>\n      <xsd:enumeration value=\"45\"/>\n      <xsd:enumeration value=\"60\"/>\n      <xsd:enumeration value=\"90\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutDrop\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutPlacement\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"user\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"straight\"/>\n      <xsd:enumeration value=\"elbow\"/>\n      <xsd:enumeration value=\"curved\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HrAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"segments\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLELinkType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Embed\"/>\n      <xsd:enumeration value=\"Link\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Content\"/>\n      <xsd:enumeration value=\"Icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Always\"/>\n      <xsd:enumeration value=\"OnCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gradientCenter\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"gradientUnscaled\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"background\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:powerpoint\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:powerpoint\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"iscomment\" type=\"CT_Empty\"/>\n  <xsd:element name=\"textdata\" type=\"CT_Rel\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:excel\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"ClientData\" type=\"CT_ClientData\"/>\n  <xsd:complexType name=\"CT_ClientData\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"MoveWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SizeWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Anchor\" type=\"xsd:string\"/>\n      <xsd:element name=\"Locked\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DefaultSize\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"PrintObject\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Disabled\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoFill\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoPict\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaMacro\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextHAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextVAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"LockText\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"JustLastX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SecretEdit\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Default\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Help\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Cancel\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dismiss\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Accel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Accel2\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Row\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Column\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Visible\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RowHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ColHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VTEdit\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MultiLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VScroll\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ValidIds\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaRange\" type=\"xsd:string\"/>\n      <xsd:element name=\"WidthMin\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Sel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"NoThreeD2\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SelType\" type=\"xsd:string\"/>\n      <xsd:element name=\"MultiSel\" type=\"xsd:string\"/>\n      <xsd:element name=\"LCT\" type=\"xsd:string\"/>\n      <xsd:element name=\"ListItem\" type=\"xsd:string\"/>\n      <xsd:element name=\"DropStyle\" type=\"xsd:string\"/>\n      <xsd:element name=\"Colored\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DropLines\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Checked\" type=\"xsd:integer\"/>\n      <xsd:element name=\"FmlaLink\" type=\"xsd:string\"/>\n      <xsd:element name=\"FmlaPict\" type=\"xsd:string\"/>\n      <xsd:element name=\"NoThreeD\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FirstButton\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaGroup\" type=\"xsd:string\"/>\n      <xsd:element name=\"Val\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Min\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Max\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Inc\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Page\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Horiz\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dx\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MapOCX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"CF\" type=\"ST_CF\"/>\n      <xsd:element name=\"Camera\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RecalcAlways\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoScale\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DDE\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"UIObj\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ScriptText\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptExtended\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptLanguage\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"ScriptLocation\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"FmlaTxbx\" type=\"xsd:string\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"ObjectType\" type=\"ST_ObjectType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CF\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ObjectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Button\"/>\n      <xsd:enumeration value=\"Checkbox\"/>\n      <xsd:enumeration value=\"Dialog\"/>\n      <xsd:enumeration value=\"Drop\"/>\n      <xsd:enumeration value=\"Edit\"/>\n      <xsd:enumeration value=\"GBox\"/>\n      <xsd:enumeration value=\"Label\"/>\n      <xsd:enumeration value=\"LineA\"/>\n      <xsd:enumeration value=\"List\"/>\n      <xsd:enumeration value=\"Movie\"/>\n      <xsd:enumeration value=\"Note\"/>\n      <xsd:enumeration value=\"Pict\"/>\n      <xsd:enumeration value=\"Radio\"/>\n      <xsd:enumeration value=\"RectA\"/>\n      <xsd:enumeration value=\"Scroll\"/>\n      <xsd:enumeration value=\"Spin\"/>\n      <xsd:enumeration value=\"Shape\"/>\n      <xsd:enumeration value=\"Group\"/>\n      <xsd:enumeration value=\"Rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:word\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:word\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"bordertop\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderleft\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderright\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderbottom\" type=\"CT_Border\"/>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"type\" type=\"ST_BorderType\" use=\"optional\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:positiveInteger\" use=\"optional\"/>\n    <xsd:attribute name=\"shadow\" type=\"ST_BorderShadow\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"wrap\" type=\"CT_Wrap\"/>\n  <xsd:complexType name=\"CT_Wrap\">\n    <xsd:attribute name=\"type\" type=\"ST_WrapType\" use=\"optional\"/>\n    <xsd:attribute name=\"side\" type=\"ST_WrapSide\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorx\" type=\"ST_HorizontalAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"anchory\" type=\"ST_VerticalAnchor\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"anchorlock\" type=\"CT_AnchorLock\"/>\n  <xsd:complexType name=\"CT_AnchorLock\"/>\n  <xsd:simpleType name=\"ST_BorderType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hairline\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmall\"/>\n      <xsd:enumeration value=\"thickThinSmall\"/>\n      <xsd:enumeration value=\"thickBetweenThinSmall\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n      <xsd:enumeration value=\"thinThickLarge\"/>\n      <xsd:enumeration value=\"thickThinLarge\"/>\n      <xsd:enumeration value=\"thickBetweenThinLarge\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashedSmall\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"HTMLOutset\"/>\n      <xsd:enumeration value=\"HTMLInset\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderShadow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"topAndBottom\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapSide\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"char\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"line\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:sl=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" schemaLocation=\"../mce/mc.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n    schemaLocation=\"dml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n    schemaLocation=\"shared-math.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n    schemaLocation=\"shared-customXmlSchemaProperties.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LongHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LongHexNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_LongHexNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShortHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UcharHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Charset\">\n    <xsd:attribute name=\"val\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"s:ST_String\" use=\"optional\" default=\"ISO-8859-1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DecimalNumberOrPercent\">\n    <xsd:union memberTypes=\"ST_UnqualifiedPercentage s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnqualifiedPercentage\">\n    <xsd:restriction base=\"xsd:decimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DecimalNumber\">\n    <xsd:restriction base=\"xsd:integer\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedDecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DecimalNumberOrPrecent\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedTwipsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedTwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PixelsMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PixelsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HpsMeasure\">\n    <xsd:union memberTypes=\"s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_HpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedHpsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedHpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedHpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTime\">\n    <xsd:restriction base=\"xsd:dateTime\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_MacroName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"33\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MacroName\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MacroName\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EighthPointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextScale\">\n    <xsd:union memberTypes=\"ST_TextScalePercent ST_TextScaleDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(600|([0-5]?[0-9]?[0-9]))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScaleDecimal\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"600\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextScale\">\n    <xsd:attribute name=\"val\" type=\"ST_TextScale\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HighlightColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkYellow\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Highlight\">\n    <xsd:attribute name=\"val\" type=\"ST_HighlightColor\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HexColorAuto\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColor\">\n    <xsd:union memberTypes=\"ST_HexColorAuto s:ST_HexColorRGB\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"val\" type=\"ST_HexColor\" use=\"required\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lang\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guid\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Guid\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Underline\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashedHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dashDotDotHeavy\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDouble\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Underline\">\n    <xsd:attribute name=\"val\" type=\"ST_Underline\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextEffect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blinkBackground\"/>\n      <xsd:enumeration value=\"lights\"/>\n      <xsd:enumeration value=\"antsBlack\"/>\n      <xsd:enumeration value=\"antsRed\"/>\n      <xsd:enumeration value=\"shimmer\"/>\n      <xsd:enumeration value=\"sparkle\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextEffect\">\n    <xsd:attribute name=\"val\" type=\"ST_TextEffect\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Border\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmallGap\"/>\n      <xsd:enumeration value=\"thickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickMediumGap\"/>\n      <xsd:enumeration value=\"thickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickLargeGap\"/>\n      <xsd:enumeration value=\"thickThinLargeGap\"/>\n      <xsd:enumeration value=\"thinThickThinLargeGap\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashSmallGap\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"outset\"/>\n      <xsd:enumeration value=\"inset\"/>\n      <xsd:enumeration value=\"apples\"/>\n      <xsd:enumeration value=\"archedScallops\"/>\n      <xsd:enumeration value=\"babyPacifier\"/>\n      <xsd:enumeration value=\"babyRattle\"/>\n      <xsd:enumeration value=\"balloons3Colors\"/>\n      <xsd:enumeration value=\"balloonsHotAir\"/>\n      <xsd:enumeration value=\"basicBlackDashes\"/>\n      <xsd:enumeration value=\"basicBlackDots\"/>\n      <xsd:enumeration value=\"basicBlackSquares\"/>\n      <xsd:enumeration value=\"basicThinLines\"/>\n      <xsd:enumeration value=\"basicWhiteDashes\"/>\n      <xsd:enumeration value=\"basicWhiteDots\"/>\n      <xsd:enumeration value=\"basicWhiteSquares\"/>\n      <xsd:enumeration value=\"basicWideInline\"/>\n      <xsd:enumeration value=\"basicWideMidline\"/>\n      <xsd:enumeration value=\"basicWideOutline\"/>\n      <xsd:enumeration value=\"bats\"/>\n      <xsd:enumeration value=\"birds\"/>\n      <xsd:enumeration value=\"birdsFlight\"/>\n      <xsd:enumeration value=\"cabins\"/>\n      <xsd:enumeration value=\"cakeSlice\"/>\n      <xsd:enumeration value=\"candyCorn\"/>\n      <xsd:enumeration value=\"celticKnotwork\"/>\n      <xsd:enumeration value=\"certificateBanner\"/>\n      <xsd:enumeration value=\"chainLink\"/>\n      <xsd:enumeration value=\"champagneBottle\"/>\n      <xsd:enumeration value=\"checkedBarBlack\"/>\n      <xsd:enumeration value=\"checkedBarColor\"/>\n      <xsd:enumeration value=\"checkered\"/>\n      <xsd:enumeration value=\"christmasTree\"/>\n      <xsd:enumeration value=\"circlesLines\"/>\n      <xsd:enumeration value=\"circlesRectangles\"/>\n      <xsd:enumeration value=\"classicalWave\"/>\n      <xsd:enumeration value=\"clocks\"/>\n      <xsd:enumeration value=\"compass\"/>\n      <xsd:enumeration value=\"confetti\"/>\n      <xsd:enumeration value=\"confettiGrays\"/>\n      <xsd:enumeration value=\"confettiOutline\"/>\n      <xsd:enumeration value=\"confettiStreamers\"/>\n      <xsd:enumeration value=\"confettiWhite\"/>\n      <xsd:enumeration value=\"cornerTriangles\"/>\n      <xsd:enumeration value=\"couponCutoutDashes\"/>\n      <xsd:enumeration value=\"couponCutoutDots\"/>\n      <xsd:enumeration value=\"crazyMaze\"/>\n      <xsd:enumeration value=\"creaturesButterfly\"/>\n      <xsd:enumeration value=\"creaturesFish\"/>\n      <xsd:enumeration value=\"creaturesInsects\"/>\n      <xsd:enumeration value=\"creaturesLadyBug\"/>\n      <xsd:enumeration value=\"crossStitch\"/>\n      <xsd:enumeration value=\"cup\"/>\n      <xsd:enumeration value=\"decoArch\"/>\n      <xsd:enumeration value=\"decoArchColor\"/>\n      <xsd:enumeration value=\"decoBlocks\"/>\n      <xsd:enumeration value=\"diamondsGray\"/>\n      <xsd:enumeration value=\"doubleD\"/>\n      <xsd:enumeration value=\"doubleDiamonds\"/>\n      <xsd:enumeration value=\"earth1\"/>\n      <xsd:enumeration value=\"earth2\"/>\n      <xsd:enumeration value=\"earth3\"/>\n      <xsd:enumeration value=\"eclipsingSquares1\"/>\n      <xsd:enumeration value=\"eclipsingSquares2\"/>\n      <xsd:enumeration value=\"eggsBlack\"/>\n      <xsd:enumeration value=\"fans\"/>\n      <xsd:enumeration value=\"film\"/>\n      <xsd:enumeration value=\"firecrackers\"/>\n      <xsd:enumeration value=\"flowersBlockPrint\"/>\n      <xsd:enumeration value=\"flowersDaisies\"/>\n      <xsd:enumeration value=\"flowersModern1\"/>\n      <xsd:enumeration value=\"flowersModern2\"/>\n      <xsd:enumeration value=\"flowersPansy\"/>\n      <xsd:enumeration value=\"flowersRedRose\"/>\n      <xsd:enumeration value=\"flowersRoses\"/>\n      <xsd:enumeration value=\"flowersTeacup\"/>\n      <xsd:enumeration value=\"flowersTiny\"/>\n      <xsd:enumeration value=\"gems\"/>\n      <xsd:enumeration value=\"gingerbreadMan\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"handmade1\"/>\n      <xsd:enumeration value=\"handmade2\"/>\n      <xsd:enumeration value=\"heartBalloon\"/>\n      <xsd:enumeration value=\"heartGray\"/>\n      <xsd:enumeration value=\"hearts\"/>\n      <xsd:enumeration value=\"heebieJeebies\"/>\n      <xsd:enumeration value=\"holly\"/>\n      <xsd:enumeration value=\"houseFunky\"/>\n      <xsd:enumeration value=\"hypnotic\"/>\n      <xsd:enumeration value=\"iceCreamCones\"/>\n      <xsd:enumeration value=\"lightBulb\"/>\n      <xsd:enumeration value=\"lightning1\"/>\n      <xsd:enumeration value=\"lightning2\"/>\n      <xsd:enumeration value=\"mapPins\"/>\n      <xsd:enumeration value=\"mapleLeaf\"/>\n      <xsd:enumeration value=\"mapleMuffins\"/>\n      <xsd:enumeration value=\"marquee\"/>\n      <xsd:enumeration value=\"marqueeToothed\"/>\n      <xsd:enumeration value=\"moons\"/>\n      <xsd:enumeration value=\"mosaic\"/>\n      <xsd:enumeration value=\"musicNotes\"/>\n      <xsd:enumeration value=\"northwest\"/>\n      <xsd:enumeration value=\"ovals\"/>\n      <xsd:enumeration value=\"packages\"/>\n      <xsd:enumeration value=\"palmsBlack\"/>\n      <xsd:enumeration value=\"palmsColor\"/>\n      <xsd:enumeration value=\"paperClips\"/>\n      <xsd:enumeration value=\"papyrus\"/>\n      <xsd:enumeration value=\"partyFavor\"/>\n      <xsd:enumeration value=\"partyGlass\"/>\n      <xsd:enumeration value=\"pencils\"/>\n      <xsd:enumeration value=\"people\"/>\n      <xsd:enumeration value=\"peopleWaving\"/>\n      <xsd:enumeration value=\"peopleHats\"/>\n      <xsd:enumeration value=\"poinsettias\"/>\n      <xsd:enumeration value=\"postageStamp\"/>\n      <xsd:enumeration value=\"pumpkin1\"/>\n      <xsd:enumeration value=\"pushPinNote2\"/>\n      <xsd:enumeration value=\"pushPinNote1\"/>\n      <xsd:enumeration value=\"pyramids\"/>\n      <xsd:enumeration value=\"pyramidsAbove\"/>\n      <xsd:enumeration value=\"quadrants\"/>\n      <xsd:enumeration value=\"rings\"/>\n      <xsd:enumeration value=\"safari\"/>\n      <xsd:enumeration value=\"sawtooth\"/>\n      <xsd:enumeration value=\"sawtoothGray\"/>\n      <xsd:enumeration value=\"scaredCat\"/>\n      <xsd:enumeration value=\"seattle\"/>\n      <xsd:enumeration value=\"shadowedSquares\"/>\n      <xsd:enumeration value=\"sharksTeeth\"/>\n      <xsd:enumeration value=\"shorebirdTracks\"/>\n      <xsd:enumeration value=\"skyrocket\"/>\n      <xsd:enumeration value=\"snowflakeFancy\"/>\n      <xsd:enumeration value=\"snowflakes\"/>\n      <xsd:enumeration value=\"sombrero\"/>\n      <xsd:enumeration value=\"southwest\"/>\n      <xsd:enumeration value=\"stars\"/>\n      <xsd:enumeration value=\"starsTop\"/>\n      <xsd:enumeration value=\"stars3d\"/>\n      <xsd:enumeration value=\"starsBlack\"/>\n      <xsd:enumeration value=\"starsShadowed\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"swirligig\"/>\n      <xsd:enumeration value=\"tornPaper\"/>\n      <xsd:enumeration value=\"tornPaperBlack\"/>\n      <xsd:enumeration value=\"trees\"/>\n      <xsd:enumeration value=\"triangleParty\"/>\n      <xsd:enumeration value=\"triangles\"/>\n      <xsd:enumeration value=\"triangle1\"/>\n      <xsd:enumeration value=\"triangle2\"/>\n      <xsd:enumeration value=\"triangleCircle1\"/>\n      <xsd:enumeration value=\"triangleCircle2\"/>\n      <xsd:enumeration value=\"shapes1\"/>\n      <xsd:enumeration value=\"shapes2\"/>\n      <xsd:enumeration value=\"twistedLines1\"/>\n      <xsd:enumeration value=\"twistedLines2\"/>\n      <xsd:enumeration value=\"vine\"/>\n      <xsd:enumeration value=\"waveline\"/>\n      <xsd:enumeration value=\"weavingAngles\"/>\n      <xsd:enumeration value=\"weavingBraid\"/>\n      <xsd:enumeration value=\"weavingRibbon\"/>\n      <xsd:enumeration value=\"weavingStrips\"/>\n      <xsd:enumeration value=\"whiteFlowers\"/>\n      <xsd:enumeration value=\"woodwork\"/>\n      <xsd:enumeration value=\"xIllusions\"/>\n      <xsd:enumeration value=\"zanyTriangles\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n      <xsd:enumeration value=\"zigZagStitch\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"val\" type=\"ST_Border\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_EighthPointMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"ST_PointMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"shadow\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"frame\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shd\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"horzStripe\"/>\n      <xsd:enumeration value=\"vertStripe\"/>\n      <xsd:enumeration value=\"reverseDiagStripe\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"horzCross\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"thinHorzStripe\"/>\n      <xsd:enumeration value=\"thinVertStripe\"/>\n      <xsd:enumeration value=\"thinReverseDiagStripe\"/>\n      <xsd:enumeration value=\"thinDiagStripe\"/>\n      <xsd:enumeration value=\"thinHorzCross\"/>\n      <xsd:enumeration value=\"thinDiagCross\"/>\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct12\"/>\n      <xsd:enumeration value=\"pct15\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct35\"/>\n      <xsd:enumeration value=\"pct37\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct45\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct55\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct62\"/>\n      <xsd:enumeration value=\"pct65\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct85\"/>\n      <xsd:enumeration value=\"pct87\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"pct95\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shd\">\n    <xsd:attribute name=\"val\" type=\"ST_Shd\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFill\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignRun\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FitText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Em\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"comma\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"underDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Em\">\n    <xsd:attribute name=\"val\" type=\"ST_Em\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Language\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"bidi\" type=\"s:ST_Lang\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CombineBrackets\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"curly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EastAsianLayout\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"combine\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"combineBrackets\" type=\"ST_CombineBrackets\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"vertCompress\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HeightRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Wrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"notBeside\"/>\n      <xsd:enumeration value=\"around\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DropCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"drop\"/>\n      <xsd:enumeration value=\"margin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FramePr\">\n    <xsd:attribute name=\"dropCap\" type=\"ST_DropCap\" use=\"optional\"/>\n    <xsd:attribute name=\"lines\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"vSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_Wrap\" use=\"optional\"/>\n    <xsd:attribute name=\"hAnchor\" type=\"ST_HAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"vAnchor\" type=\"ST_VAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"x\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"xAlign\" type=\"s:ST_XAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"y\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"yAlign\" type=\"s:ST_YAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorLock\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TabJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TabTlc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TabStop\">\n    <xsd:attribute name=\"val\" type=\"ST_TabJc\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_TabTlc\" use=\"optional\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LineSpacingRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Spacing\">\n    <xsd:attribute name=\"before\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"after\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"line\" type=\"ST_SignedTwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"lineRule\" type=\"ST_LineSpacingRule\" use=\"optional\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ind\">\n    <xsd:attribute name=\"start\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"startChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"end\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"endChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"left\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"leftChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"right\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"rightChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"hanging\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLine\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLineChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"mediumKashida\"/>\n      <xsd:enumeration value=\"distribute\"/>\n      <xsd:enumeration value=\"numTab\"/>\n      <xsd:enumeration value=\"highKashida\"/>\n      <xsd:enumeration value=\"lowKashida\"/>\n      <xsd:enumeration value=\"thaiDistribute\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_JcTable\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"start\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Jc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_JcTable\">\n    <xsd:attribute name=\"val\" type=\"ST_JcTable\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_View\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"outline\"/>\n      <xsd:enumeration value=\"masterPages\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"web\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_View\">\n    <xsd:attribute name=\"val\" type=\"ST_View\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Zoom\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fullPage\"/>\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"textFit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Zoom\">\n    <xsd:attribute name=\"val\" type=\"ST_Zoom\" use=\"optional\"/>\n    <xsd:attribute name=\"percent\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WritingStyle\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"vendorID\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"dllVersion\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"nlCheck\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"checkStyle\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"appName\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Proof\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clean\"/>\n      <xsd:enumeration value=\"dirty\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Proof\">\n    <xsd:attribute name=\"spelling\" type=\"ST_Proof\" use=\"optional\"/>\n    <xsd:attribute name=\"grammar\" type=\"ST_Proof\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocType\">\n    <xsd:attribute name=\"val\" type=\"ST_DocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocProtect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"readOnly\"/>\n      <xsd:enumeration value=\"comments\"/>\n      <xsd:enumeration value=\"trackedChanges\"/>\n      <xsd:enumeration value=\"forms\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Password\">\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_TransitionalPassword\">\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptSpinCount\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hash\" type=\"xsd:base64Binary\"/>\n    <xsd:attribute name=\"salt\" type=\"xsd:base64Binary\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_DocProtect\">\n    <xsd:attribute name=\"edit\" type=\"ST_DocProtect\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"enforcement\" type=\"s:ST_OnOff\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDocType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"catalog\"/>\n      <xsd:enumeration value=\"envelopes\"/>\n      <xsd:enumeration value=\"mailingLabels\"/>\n      <xsd:enumeration value=\"formLetters\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDocType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDataType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDest\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newDocument\"/>\n      <xsd:enumeration value=\"printer\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDest\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDest\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeOdsoFMDFieldType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"dbColumn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeOdsoFMDFieldType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeOdsoFMDFieldType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangesView\">\n    <xsd:attribute name=\"markup\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"comments\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"insDel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"inkAnnotations\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextDirection\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tb\"/>\n      <xsd:enumeration value=\"rl\"/>\n      <xsd:enumeration value=\"lr\"/>\n      <xsd:enumeration value=\"tbV\"/>\n      <xsd:enumeration value=\"rlV\"/>\n      <xsd:enumeration value=\"lrV\"/>\n      <xsd:enumeration value=\"btLr\"/>\n      <xsd:enumeration value=\"lrTb\"/>\n      <xsd:enumeration value=\"lrTbV\"/>\n      <xsd:enumeration value=\"tbLrV\"/>\n      <xsd:enumeration value=\"tbRl\"/>\n      <xsd:enumeration value=\"tbRlV\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextDirection\">\n    <xsd:attribute name=\"val\" type=\"ST_TextDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextAlignment\">\n    <xsd:attribute name=\"val\" type=\"ST_TextAlignment\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DisplacedByCustomXml\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"next\"/>\n      <xsd:enumeration value=\"prev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnnotationVMerge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cont\"/>\n      <xsd:enumeration value=\"rest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Markup\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellMergeTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"vMerge\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n        <xsd:attribute name=\"vMergeOrig\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MarkupRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookmarkRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_MarkupRange\">\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_BookmarkRange\">\n        <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MoveBookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Bookmark\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"initials\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeNumbering\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"original\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrEx\" type=\"CT_TblPrExBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPr\" type=\"CT_TcPrInner\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"trPr\" type=\"CT_TrPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGrid\" type=\"CT_TblGridBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPrBase\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"pPr\" type=\"CT_PPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_RPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RunTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:group ref=\"EG_ContentRunContent\"/>\n          <xsd:group ref=\"m:EG_OMathMathElements\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContentMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_PContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_ContentRunContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_PContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ContentRunContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_CellMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"cellIns\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellDel\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellMerge\" type=\"CT_CellMergeTrackChange\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RangeMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"bookmarkStart\" type=\"CT_Bookmark\"/>\n      <xsd:element name=\"bookmarkEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveFromRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveFromRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveToRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveToRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeStart\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"customXmlInsRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlInsRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlDelRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlDelRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveFromRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveFromRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveToRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveToRangeEnd\" type=\"CT_Markup\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_NumPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ilvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"between\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bar\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tabs\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TabStop\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextboxTightWrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"allLines\"/>\n      <xsd:enumeration value=\"firstAndLastLine\"/>\n      <xsd:enumeration value=\"firstLineOnly\"/>\n      <xsd:enumeration value=\"lastLineOnly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextboxTightWrap\">\n    <xsd:attribute name=\"val\" type=\"ST_TextboxTightWrap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepNext\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageBreakBefore\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"framePr\" type=\"CT_FramePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"widowControl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"numPr\" type=\"CT_NumPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressLineNumbers\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pBdr\" type=\"CT_PBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabs\" type=\"CT_Tabs\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressAutoHyphens\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wordWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"overflowPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"topLinePunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDE\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDN\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustRightInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacing\" type=\"CT_Spacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"ind\" type=\"CT_Ind\" minOccurs=\"0\"/>\n      <xsd:element name=\"contextualSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorIndents\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressOverlap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"jc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"textAlignment\" type=\"CT_TextAlignment\" minOccurs=\"0\"/>\n      <xsd:element name=\"textboxTightWrap\" type=\"CT_TextboxTightWrap\" minOccurs=\"0\"/>\n      <xsd:element name=\"outlineLvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrGeneral\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeid\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Object\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"control\" type=\"CT_Control\"/>\n        <xsd:element name=\"objectLink\" type=\"CT_ObjectLink\"/>\n        <xsd:element name=\"objectEmbed\" type=\"CT_ObjectEmbed\"/>\n        <xsd:element name=\"movie\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"dxaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"dyaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"movie\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectEmbed\">\n    <xsd:attribute name=\"drawAspect\" type=\"ST_ObjectDrawAspect\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldCodes\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ObjectLink\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_ObjectEmbed\">\n        <xsd:attribute name=\"updateMode\" type=\"ST_ObjectUpdateMode\" use=\"required\"/>\n        <xsd:attribute name=\"lockedField\" type=\"s:ST_OnOff\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"onCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"wp:anchor\" minOccurs=\"0\"/>\n      <xsd:element ref=\"wp:inline\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SimpleField\">\n    <xsd:sequence>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"instr\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FldCharType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"separate\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InfoTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"autoText\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFHelpTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"256\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFStatusTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"140\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"65\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"regular\"/>\n      <xsd:enumeration value=\"number\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"currentTime\"/>\n      <xsd:enumeration value=\"currentDate\"/>\n      <xsd:enumeration value=\"calculated\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FFTextType\">\n    <xsd:attribute name=\"val\" type=\"ST_FFTextType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFName\">\n    <xsd:attribute name=\"val\" type=\"ST_FFName\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FldChar\">\n    <xsd:choice>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ffData\" type=\"CT_FFData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fldCharType\" type=\"ST_FldCharType\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"docLocation\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"history\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFData\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FFName\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"enabled\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"calcOnExit\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"entryMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"exitMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"helpText\" type=\"CT_FFHelpText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"statusText\" type=\"CT_FFStatusText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"checkBox\" type=\"CT_FFCheckBox\"/>\n        <xsd:element name=\"ddList\" type=\"CT_FFDDList\"/>\n        <xsd:element name=\"textInput\" type=\"CT_FFTextInput\"/>\n      </xsd:choice>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFHelpText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFHelpTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFStatusText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFStatusTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFCheckBox\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"size\" type=\"CT_HpsMeasure\"/>\n        <xsd:element name=\"sizeAuto\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"default\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFDDList\">\n    <xsd:sequence>\n      <xsd:element name=\"result\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"listEntry\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFTextInput\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FFTextType\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxLength\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"format\" type=\"CT_String\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SectionMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nextPage\"/>\n      <xsd:enumeration value=\"nextColumn\"/>\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"evenPage\"/>\n      <xsd:enumeration value=\"oddPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SectType\">\n    <xsd:attribute name=\"val\" type=\"ST_SectionMark\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PaperSource\">\n    <xsd:attribute name=\"first\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"other\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumberFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"upperRoman\"/>\n      <xsd:enumeration value=\"lowerRoman\"/>\n      <xsd:enumeration value=\"upperLetter\"/>\n      <xsd:enumeration value=\"lowerLetter\"/>\n      <xsd:enumeration value=\"ordinal\"/>\n      <xsd:enumeration value=\"cardinalText\"/>\n      <xsd:enumeration value=\"ordinalText\"/>\n      <xsd:enumeration value=\"hex\"/>\n      <xsd:enumeration value=\"chicago\"/>\n      <xsd:enumeration value=\"ideographDigital\"/>\n      <xsd:enumeration value=\"japaneseCounting\"/>\n      <xsd:enumeration value=\"aiueo\"/>\n      <xsd:enumeration value=\"iroha\"/>\n      <xsd:enumeration value=\"decimalFullWidth\"/>\n      <xsd:enumeration value=\"decimalHalfWidth\"/>\n      <xsd:enumeration value=\"japaneseLegal\"/>\n      <xsd:enumeration value=\"japaneseDigitalTenThousand\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircle\"/>\n      <xsd:enumeration value=\"decimalFullWidth2\"/>\n      <xsd:enumeration value=\"aiueoFullWidth\"/>\n      <xsd:enumeration value=\"irohaFullWidth\"/>\n      <xsd:enumeration value=\"decimalZero\"/>\n      <xsd:enumeration value=\"bullet\"/>\n      <xsd:enumeration value=\"ganada\"/>\n      <xsd:enumeration value=\"chosung\"/>\n      <xsd:enumeration value=\"decimalEnclosedFullstop\"/>\n      <xsd:enumeration value=\"decimalEnclosedParen\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircleChinese\"/>\n      <xsd:enumeration value=\"ideographEnclosedCircle\"/>\n      <xsd:enumeration value=\"ideographTraditional\"/>\n      <xsd:enumeration value=\"ideographZodiac\"/>\n      <xsd:enumeration value=\"ideographZodiacTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCounting\"/>\n      <xsd:enumeration value=\"ideographLegalTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCountingThousand\"/>\n      <xsd:enumeration value=\"taiwaneseDigital\"/>\n      <xsd:enumeration value=\"chineseCounting\"/>\n      <xsd:enumeration value=\"chineseLegalSimplified\"/>\n      <xsd:enumeration value=\"chineseCountingThousand\"/>\n      <xsd:enumeration value=\"koreanDigital\"/>\n      <xsd:enumeration value=\"koreanCounting\"/>\n      <xsd:enumeration value=\"koreanLegal\"/>\n      <xsd:enumeration value=\"koreanDigital2\"/>\n      <xsd:enumeration value=\"vietnameseCounting\"/>\n      <xsd:enumeration value=\"russianLower\"/>\n      <xsd:enumeration value=\"russianUpper\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"numberInDash\"/>\n      <xsd:enumeration value=\"hebrew1\"/>\n      <xsd:enumeration value=\"hebrew2\"/>\n      <xsd:enumeration value=\"arabicAlpha\"/>\n      <xsd:enumeration value=\"arabicAbjad\"/>\n      <xsd:enumeration value=\"hindiVowels\"/>\n      <xsd:enumeration value=\"hindiConsonants\"/>\n      <xsd:enumeration value=\"hindiNumbers\"/>\n      <xsd:enumeration value=\"hindiCounting\"/>\n      <xsd:enumeration value=\"thaiLetters\"/>\n      <xsd:enumeration value=\"thaiNumbers\"/>\n      <xsd:enumeration value=\"thaiCounting\"/>\n      <xsd:enumeration value=\"bahtText\"/>\n      <xsd:enumeration value=\"dollarText\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageSz\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_PageOrientation\" use=\"optional\"/>\n    <xsd:attribute name=\"code\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMar\">\n    <xsd:attribute name=\"top\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"left\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"gutter\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageBorderZOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"front\"/>\n      <xsd:enumeration value=\"back\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderDisplay\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"allPages\"/>\n      <xsd:enumeration value=\"firstPage\"/>\n      <xsd:enumeration value=\"notFirstPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderOffset\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TopPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BottomPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zOrder\" type=\"ST_PageBorderZOrder\" use=\"optional\" default=\"front\"/>\n    <xsd:attribute name=\"display\" type=\"ST_PageBorderDisplay\" use=\"optional\"/>\n    <xsd:attribute name=\"offsetFrom\" type=\"ST_PageBorderOffset\" use=\"optional\" default=\"text\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Border\">\n        <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BottomPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:bottomLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:bottomRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TopPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:topLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:topRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ChapterSep\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"period\"/>\n      <xsd:enumeration value=\"colon\"/>\n      <xsd:enumeration value=\"emDash\"/>\n      <xsd:enumeration value=\"enDash\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineNumberRestart\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newPage\"/>\n      <xsd:enumeration value=\"newSection\"/>\n      <xsd:enumeration value=\"continuous\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineNumber\">\n    <xsd:attribute name=\"countBy\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"distance\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_LineNumberRestart\" use=\"optional\" default=\"newPage\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageNumber\">\n    <xsd:attribute name=\"fmt\" type=\"ST_NumberFormat\" use=\"optional\" default=\"decimal\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapStyle\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapSep\" type=\"ST_ChapterSep\" use=\"optional\" default=\"hyphen\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Column\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Columns\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"col\" type=\"CT_Column\" maxOccurs=\"45\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"equalWidth\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"720\"/>\n    <xsd:attribute name=\"num\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"sep\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VerticalJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"bottom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VerticalJc\">\n    <xsd:attribute name=\"val\" type=\"ST_VerticalJc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocGrid\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"lines\"/>\n      <xsd:enumeration value=\"linesAndChars\"/>\n      <xsd:enumeration value=\"snapToChars\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocGrid\">\n    <xsd:attribute name=\"type\" type=\"ST_DocGrid\"/>\n    <xsd:attribute name=\"linePitch\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"charSpace\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HdrFtr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"even\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"first\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FtnEdn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"separator\"/>\n      <xsd:enumeration value=\"continuationSeparator\"/>\n      <xsd:enumeration value=\"continuationNotice\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HdrFtrRef\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"type\" type=\"ST_HdrFtr\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_HdrFtrReferences\">\n    <xsd:choice>\n      <xsd:element name=\"headerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n      <xsd:element name=\"footerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_HdrFtr\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SectPrContents\">\n    <xsd:sequence>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_SectType\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgSz\" type=\"CT_PageSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgMar\" type=\"CT_PageMar\" minOccurs=\"0\"/>\n      <xsd:element name=\"paperSrc\" type=\"CT_PaperSource\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgBorders\" type=\"CT_PageBorders\" minOccurs=\"0\"/>\n      <xsd:element name=\"lnNumType\" type=\"CT_LineNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNumType\" type=\"CT_PageNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cols\" type=\"CT_Columns\" minOccurs=\"0\"/>\n      <xsd:element name=\"formProt\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"noEndnote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"titlePg\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rtlGutter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"docGrid\" type=\"CT_DocGrid\" minOccurs=\"0\"/>\n      <xsd:element name=\"printerSettings\" type=\"CT_Rel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_SectPrAttributes\">\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidSect\" type=\"ST_LongHexNumber\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_SectPrBase\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_HdrFtrReferences\" minOccurs=\"0\" maxOccurs=\"6\"/>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n      <xsd:element name=\"sectPrChange\" type=\"CT_SectPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BrType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"textWrapping\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BrClear\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Br\">\n    <xsd:attribute name=\"type\" type=\"ST_BrType\" use=\"optional\"/>\n    <xsd:attribute name=\"clear\" type=\"ST_BrClear\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PTabAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabRelativeTo\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"indent\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabLeader\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PTab\">\n    <xsd:attribute name=\"alignment\" type=\"ST_PTabAlignment\" use=\"required\"/>\n    <xsd:attribute name=\"relativeTo\" type=\"ST_PTabRelativeTo\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_PTabLeader\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sym\">\n    <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"char\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ProofErr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"spellStart\"/>\n      <xsd:enumeration value=\"spellEnd\"/>\n      <xsd:enumeration value=\"gramStart\"/>\n      <xsd:enumeration value=\"gramEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ProofErr\">\n    <xsd:attribute name=\"type\" type=\"ST_ProofErr\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdGrp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"everyone\"/>\n      <xsd:enumeration value=\"administrators\"/>\n      <xsd:enumeration value=\"contributors\"/>\n      <xsd:enumeration value=\"editors\"/>\n      <xsd:enumeration value=\"owners\"/>\n      <xsd:enumeration value=\"current\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perm\">\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PermStart\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Perm\">\n        <xsd:attribute name=\"edGrp\" type=\"ST_EdGrp\" use=\"optional\"/>\n        <xsd:attribute name=\"ed\" type=\"s:ST_String\" use=\"optional\"/>\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RunInnerContent\">\n    <xsd:choice>\n      <xsd:element name=\"br\" type=\"CT_Br\"/>\n      <xsd:element name=\"t\" type=\"CT_Text\"/>\n      <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      <xsd:element name=\"delText\" type=\"CT_Text\"/>\n      <xsd:element name=\"instrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"delInstrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"noBreakHyphen\" type=\"CT_Empty\"/>\n      <xsd:element name=\"softHyphen\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"annotationRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"separator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"continuationSeparator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"sym\" type=\"CT_Sym\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNum\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"cr\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"tab\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"object\" type=\"CT_Object\"/>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"fldChar\" type=\"CT_FldChar\"/>\n      <xsd:element name=\"ruby\" type=\"CT_Ruby\"/>\n      <xsd:element name=\"footnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"endnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"commentReference\" type=\"CT_Markup\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"ptab\" type=\"CT_PTab\" minOccurs=\"0\"/>\n      <xsd:element name=\"lastRenderedPageBreak\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RunInnerContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Hint\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"eastAsia\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Theme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"majorEastAsia\"/>\n      <xsd:enumeration value=\"majorBidi\"/>\n      <xsd:enumeration value=\"majorAscii\"/>\n      <xsd:enumeration value=\"majorHAnsi\"/>\n      <xsd:enumeration value=\"minorEastAsia\"/>\n      <xsd:enumeration value=\"minorBidi\"/>\n      <xsd:enumeration value=\"minorAscii\"/>\n      <xsd:enumeration value=\"minorHAnsi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:attribute name=\"hint\" type=\"ST_Hint\"/>\n    <xsd:attribute name=\"ascii\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hAnsi\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cs\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"asciiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"hAnsiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"eastAsiaTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"cstheme\" type=\"ST_Theme\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPrBase\">\n    <xsd:choice>\n      <xsd:element name=\"rStyle\" type=\"CT_String\"/>\n      <xsd:element name=\"rFonts\" type=\"CT_Fonts\"/>\n      <xsd:element name=\"b\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"bCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"i\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"iCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"caps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"smallCaps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"strike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"dstrike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"outline\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"shadow\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"emboss\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"imprint\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"noProof\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"vanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"webHidden\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\"/>\n      <xsd:element name=\"spacing\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"w\" type=\"CT_TextScale\"/>\n      <xsd:element name=\"kern\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"position\" type=\"CT_SignedHpsMeasure\"/>\n      <xsd:element name=\"sz\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"szCs\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Highlight\"/>\n      <xsd:element name=\"u\" type=\"CT_Underline\"/>\n      <xsd:element name=\"effect\" type=\"CT_TextEffect\"/>\n      <xsd:element name=\"bdr\" type=\"CT_Border\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\"/>\n      <xsd:element name=\"fitText\" type=\"CT_FitText\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignRun\"/>\n      <xsd:element name=\"rtl\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"cs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"em\" type=\"CT_Em\"/>\n      <xsd:element name=\"lang\" type=\"CT_Language\"/>\n      <xsd:element name=\"eastAsianLayout\" type=\"CT_EastAsianLayout\"/>\n      <xsd:element name=\"specVanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OnOff\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrContent\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_RPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrContent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_RPr\"/>\n      <xsd:element name=\"ins\" type=\"CT_MathCtrlIns\"/>\n      <xsd:element name=\"del\" type=\"CT_MathCtrlDel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_MathCtrlIns\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"del\" type=\"CT_RPrChange\" minOccurs=\"1\"/>\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathCtrlDel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_ParaRPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ParaRPrTrackChanges\">\n    <xsd:sequence>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AltChunk\">\n    <xsd:sequence>\n      <xsd:element name=\"altChunkPr\" type=\"CT_AltChunkPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AltChunkPr\">\n    <xsd:sequence>\n      <xsd:element name=\"matchSrc\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RubyAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributeLetter\"/>\n      <xsd:enumeration value=\"distributeSpace\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"rightVertical\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RubyAlign\">\n    <xsd:attribute name=\"val\" type=\"ST_RubyAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RubyPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyAlign\" type=\"CT_RubyAlign\"/>\n      <xsd:element name=\"hps\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsRaise\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsBaseText\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\"/>\n      <xsd:element name=\"dirty\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RubyContent\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RubyContent\">\n    <xsd:group ref=\"EG_RubyContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ruby\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyPr\" type=\"CT_RubyPr\"/>\n      <xsd:element name=\"rt\" type=\"CT_RubyContent\"/>\n      <xsd:element name=\"rubyBase\" type=\"CT_RubyContent\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Lock\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sdtLocked\"/>\n      <xsd:enumeration value=\"contentLocked\"/>\n      <xsd:enumeration value=\"unlocked\"/>\n      <xsd:enumeration value=\"sdtContentLocked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attribute name=\"val\" type=\"ST_Lock\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtListItem\">\n    <xsd:attribute name=\"displayText\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"value\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SdtDateMappingType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"dateTime\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtDateMappingType\">\n    <xsd:attribute name=\"val\" type=\"ST_SdtDateMappingType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalendarType\">\n    <xsd:attribute name=\"val\" type=\"s:ST_CalendarType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDate\">\n    <xsd:sequence>\n      <xsd:element name=\"dateFormat\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"storeMappedDataAs\" type=\"CT_SdtDateMappingType\" minOccurs=\"0\"/>\n      <xsd:element name=\"calendar\" type=\"CT_CalendarType\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullDate\" type=\"ST_DateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtComboBox\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartGallery\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartCategory\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartUnique\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDropDownList\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"docPart\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtText\">\n    <xsd:attribute name=\"multiLine\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:attribute name=\"prefixMappings\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"storeItemID\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"alias\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tag\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"id\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lock\" type=\"CT_Lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"placeholder\" type=\"CT_Placeholder\" minOccurs=\"0\"/>\n      <xsd:element name=\"temporary\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showingPlcHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"equation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comboBox\" type=\"CT_SdtComboBox\"/>\n        <xsd:element name=\"date\" type=\"CT_SdtDate\"/>\n        <xsd:element name=\"docPartObj\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"docPartList\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"dropDownList\" type=\"CT_SdtDropDownList\"/>\n        <xsd:element name=\"picture\" type=\"CT_Empty\"/>\n        <xsd:element name=\"richText\" type=\"CT_Empty\"/>\n        <xsd:element name=\"text\" type=\"CT_SdtText\"/>\n        <xsd:element name=\"citation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"group\" type=\"CT_Empty\"/>\n        <xsd:element name=\"bibliography\" type=\"CT_Empty\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtEndPr\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRunContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:element name=\"dir\" type=\"CT_DirContentRun\"/>\n      <xsd:element name=\"bdo\" type=\"CT_BdoContentRun\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DirContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BdoContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ltr\"/>\n      <xsd:enumeration value=\"rtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentBlockContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlBlock\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtBlock\"/>\n      <xsd:element name=\"p\" type=\"CT_P\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tbl\" type=\"CT_Tbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentBlock\">\n    <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRowContent\">\n    <xsd:choice>\n      <xsd:element name=\"tr\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRow\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRow\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentRow\">\n    <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentCellContent\">\n    <xsd:choice>\n      <xsd:element name=\"tc\" type=\"CT_Tc\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlCell\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtCell\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentCell\">\n    <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentBlock\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRun\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRun\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtCell\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentCell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRow\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRow\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Attr\">\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRun\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagRun\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"placeholder\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRow\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:sequence>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContent\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentRunContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n      <xsd:element name=\"subDoc\" type=\"CT_Rel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_P\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidP\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidRDefault\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"pct\"/>\n      <xsd:enumeration value=\"dxa\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Height\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MeasurementOrPercent\">\n    <xsd:union memberTypes=\"ST_DecimalNumberOrPercent s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblWidth\">\n    <xsd:attribute name=\"w\" type=\"ST_MeasurementOrPercent\"/>\n    <xsd:attribute name=\"type\" type=\"ST_TblWidth\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridCol\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridBase\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TblGridCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGrid\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblGridBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGridChange\" type=\"CT_TblGridChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Merge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continue\"/>\n      <xsd:enumeration value=\"restart\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpan\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hMerge\" type=\"CT_HMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"vMerge\" type=\"CT_VMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcBorders\" type=\"CT_TcBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"noWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcMar\" type=\"CT_TcMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcFitText\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrInner\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPrChange\" type=\"CT_TcPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrInner\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrBase\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_CellMarkupElements\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tc\">\n    <xsd:sequence>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Cnf\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:length value=\"12\"/>\n      <xsd:pattern value=\"[01]*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cnf\">\n    <xsd:attribute name=\"val\" type=\"ST_Cnf\"/>\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowLastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowLastColumn\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrBase\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridBefore\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridAfter\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"wBefore\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wAfter\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cantSplit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"trHeight\" type=\"CT_Height\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"trPrChange\" type=\"CT_TrPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPrEx\" type=\"CT_TblPrEx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidTr\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblLayoutType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"autofit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblLayoutType\">\n    <xsd:attribute name=\"type\" type=\"ST_TblLayoutType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblOverlap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"overlap\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblOverlap\">\n    <xsd:attribute name=\"val\" type=\"ST_TblOverlap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPPr\">\n    <xsd:attribute name=\"leftFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"rightFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"topFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"bottomFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"vertAnchor\" type=\"ST_VAnchor\"/>\n    <xsd:attribute name=\"horzAnchor\" type=\"ST_HAnchor\"/>\n    <xsd:attribute name=\"tblpXSpec\" type=\"s:ST_XAlign\"/>\n    <xsd:attribute name=\"tblpX\" type=\"ST_SignedTwipsMeasure\"/>\n    <xsd:attribute name=\"tblpYSpec\" type=\"s:ST_YAlign\"/>\n    <xsd:attribute name=\"tblpY\" type=\"ST_SignedTwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblCellMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblpPr\" type=\"CT_TblPPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblOverlap\" type=\"CT_TblOverlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bidiVisual\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleRowBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleColBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCaption\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblDescription\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrChange\" type=\"CT_TblPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrEx\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrExBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrExChange\" type=\"CT_TblPrExChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tbl\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPr\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TblGrid\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblLook\">\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FtnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pageBottom\"/>\n      <xsd:enumeration value=\"beneathText\"/>\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FtnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_FtnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EdnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_EdnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"val\" type=\"ST_NumberFormat\" use=\"required\"/>\n    <xsd:attribute name=\"format\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RestartNumber\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"eachSect\"/>\n      <xsd:enumeration value=\"eachPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumRestart\">\n    <xsd:attribute name=\"val\" type=\"ST_RestartNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnRef\">\n    <xsd:attribute name=\"customMarkFollows\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnSepRef\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdn\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_FtnEdn\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FtnEdnNumProps\">\n    <xsd:sequence>\n      <xsd:element name=\"numStart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numRestart\" type=\"CT_NumRestart\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FtnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_FtnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_EdnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_FtnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"footnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_EdnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"endnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RecipientData\">\n    <xsd:sequence>\n      <xsd:element name=\"active\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"uniqueTag\" type=\"CT_Base64Binary\" minOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Base64Binary\">\n    <xsd:attribute name=\"val\" type=\"xsd:base64Binary\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Recipients\">\n    <xsd:sequence>\n      <xsd:element name=\"recipientData\" type=\"CT_RecipientData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"recipients\" type=\"CT_Recipients\"/>\n  <xsd:complexType name=\"CT_OdsoFieldMapData\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_MailMergeOdsoFMDFieldType\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mappedName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"dynamicAddress\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"database\"/>\n      <xsd:enumeration value=\"addressBook\"/>\n      <xsd:enumeration value=\"document1\"/>\n      <xsd:enumeration value=\"document2\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"native\"/>\n      <xsd:enumeration value=\"legacy\"/>\n      <xsd:enumeration value=\"master\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeSourceType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MailMergeSourceType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Odso\">\n    <xsd:sequence>\n      <xsd:element name=\"udl\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"table\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"src\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"colDelim\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_MailMergeSourceType\" minOccurs=\"0\"/>\n      <xsd:element name=\"fHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"fieldMapData\" type=\"CT_OdsoFieldMapData\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"recipientData\" type=\"CT_Rel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MailMerge\">\n    <xsd:sequence>\n      <xsd:element name=\"mainDocumentType\" type=\"CT_MailMergeDocType\" minOccurs=\"1\"/>\n      <xsd:element name=\"linkToQuery\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataType\" type=\"CT_MailMergeDataType\" minOccurs=\"1\"/>\n      <xsd:element name=\"connectString\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"query\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"headerSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressBlankLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"destination\" type=\"CT_MailMergeDest\" minOccurs=\"0\"/>\n      <xsd:element name=\"addressFieldName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailSubject\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailAsAttachment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"viewMergedData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeRecord\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"checkErrors\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"odso\" type=\"CT_Odso\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSz\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TargetScreenSz\">\n    <xsd:attribute name=\"val\" type=\"ST_TargetScreenSz\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Compat\">\n    <xsd:sequence>\n      <xsd:element name=\"useSingleBorderforContiguousCells\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpJustification\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noTabHangInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLeading\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spaceForUL\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noColumnBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"balanceSingleByteDoubleByteWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noExtraLineSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotLeaveBackslashAlone\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ulTrailSpace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotExpandShiftReturn\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacingInWholePoints\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lineWrapLikeWord6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printBodyTextBeforeHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printColBlack\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpSpaceWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showBreaksInFrames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subFontBySize\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressBottomSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpacingAtTopOfPage\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacingWP\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpBfAfterPgBrk\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"swapBordersFacingPages\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"convMailMergeEsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"truncateFontHeightsLikeWP6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mwSmallCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"usePrinterMetrics\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressParagraphBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wrapTrailSpaces\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shapeLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignTablesRowByRow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forgetLastTabAlignment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustLineHeightInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceLikeWord95\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noSpaceRaiseLower\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseHTMLParagraphAutoSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutRawTableWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutTableRowsApart\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord97LineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakWrappedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSnapToGridInCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"selectFldWithFirstOrLastChar\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"applyBreakingRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotWrapTextWithPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseEastAsianBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord2002TableStyleRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"growAutofit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useFELayout\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useNormalStyleForList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseIndentAsNumberingTabStop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAltKinsokuLineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowSpaceOfSameStyleInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressIndentation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutofitConstrainedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autofitToFirstFixedWidthCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"underlineTabInNumList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHangulFixedWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"splitPgBreakAndParaMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignCellWithSp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakConstrainedForcedTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignInTxbx\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAnsiKerningPairs\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"cachedColBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"compatSetting\" type=\"CT_CompatSetting\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CompatSetting\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVar\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVars\">\n    <xsd:sequence>\n      <xsd:element name=\"docVar\" type=\"CT_DocVar\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocRsids\">\n    <xsd:sequence>\n      <xsd:element name=\"rsidRoot\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CharacterSpacing\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doNotCompress\"/>\n      <xsd:enumeration value=\"compressPunctuation\"/>\n      <xsd:enumeration value=\"compressPunctuationAndJapaneseKana\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CharacterSpacing\">\n    <xsd:attribute name=\"val\" type=\"ST_CharacterSpacing\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SaveThroughXslt\">\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"solutionID\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"rPrDefault\" type=\"CT_RPrDefault\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPrDefault\" type=\"CT_PPrDefault\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WmlColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorSchemeMapping\">\n    <xsd:attribute name=\"bg1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"hyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"followedHyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReadingModeInkLockDown\">\n    <xsd:attribute name=\"actualPg\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"w\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"fontSz\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WriteProtection\">\n    <xsd:attribute name=\"recommended\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Settings\">\n    <xsd:sequence>\n      <xsd:element name=\"writeProtection\" type=\"CT_WriteProtection\" minOccurs=\"0\"/>\n      <xsd:element name=\"view\" type=\"CT_View\" minOccurs=\"0\"/>\n      <xsd:element name=\"zoom\" type=\"CT_Zoom\" minOccurs=\"0\"/>\n      <xsd:element name=\"removePersonalInformation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"removeDateAndTime\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDisplayPageBoundaries\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayBackgroundShape\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printPostScriptOverText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFractionalCharacterWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedTrueTypeFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedSystemFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSubsetFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorMargins\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignBordersAndEdges\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundFooter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"gutterAtTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideSpellingErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideGrammaticalErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeWritingStyle\" type=\"CT_WritingStyle\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"proofState\" type=\"CT_Proof\" minOccurs=\"0\"/>\n      <xsd:element name=\"formsDesign\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"attachedTemplate\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkStyles\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneFormatFilter\" type=\"CT_StylePaneFilter\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneSortMethod\" type=\"CT_StyleSort\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentType\" type=\"CT_DocType\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailMerge\" type=\"CT_MailMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"revisionView\" type=\"CT_TrackChangesView\" minOccurs=\"0\"/>\n      <xsd:element name=\"trackRevisions\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackMoves\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackFormatting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentProtection\" type=\"CT_DocProtect\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoFormatOverride\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockTheme\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockQFSet\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTabStop\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoHyphenation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"consecutiveHyphenLimit\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hyphenationZone\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotHyphenateCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showEnvelope\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"summaryLength\" type=\"CT_DecimalNumberOrPrecent\" minOccurs=\"0\"/>\n      <xsd:element name=\"clickAndTypeStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTableStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"evenAndOddHeaders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldRevPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrintingSheets\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHorizontalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayVerticalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseMarginsForDrawingGridOrigin\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotShadeFormData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noPunctuationKerning\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"characterSpacingControl\" type=\"CT_CharacterSpacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"printTwoOnOne\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strictFirstAndLastChars\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksAfter\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksBefore\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"savePreviewPicture\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotValidateAgainstSchema\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ignoreMixedContent\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysShowPlaceholderText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDemarcateInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveXmlDataOnly\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useXSLTWhenSaving\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveThroughXslt\" type=\"CT_SaveThroughXslt\" minOccurs=\"0\"/>\n      <xsd:element name=\"showXMLTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysMergeEmptyNamespace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"updateFields\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hdrShapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"compat\" type=\"CT_Compat\" minOccurs=\"0\"/>\n      <xsd:element name=\"docVars\" type=\"CT_DocVars\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsids\" type=\"CT_DocRsids\" minOccurs=\"0\"/>\n      <xsd:element ref=\"m:mathPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attachedSchema\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"themeFontLang\" type=\"CT_Language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrSchemeMapping\" type=\"CT_ColorSchemeMapping\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotIncludeSubdocsInStats\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutoCompressPictures\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forceUpgrade\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"captions\" type=\"CT_Captions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"readModeInkLockDown\" type=\"CT_ReadingModeInkLockDown\" minOccurs=\"0\"/>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"sl:schemaLibrary\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotEmbedSmartTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"decimalSymbol\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"listSeparator\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleSort\">\n    <xsd:attribute name=\"val\" type=\"ST_StyleSort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StylePaneFilter\">\n    <xsd:attribute name=\"allStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"customStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"latentStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"stylesInUse\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"headingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"numberingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"tableStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnRuns\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnParagraphs\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnNumbering\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnTables\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"clearFormatting\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"top3HeadingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"visibleStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"alternateStyleNames\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleSort\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"name\"/>\n      <xsd:enumeration value=\"priority\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"font\"/>\n      <xsd:enumeration value=\"basedOn\"/>\n      <xsd:enumeration value=\"type\"/>\n      <xsd:enumeration value=\"0000\"/>\n      <xsd:enumeration value=\"0001\"/>\n      <xsd:enumeration value=\"0002\"/>\n      <xsd:enumeration value=\"0003\"/>\n      <xsd:enumeration value=\"0004\"/>\n      <xsd:enumeration value=\"0005\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\"/>\n      <xsd:element name=\"divs\" type=\"CT_Divs\" minOccurs=\"0\"/>\n      <xsd:element name=\"encoding\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"optimizeForBrowser\" type=\"CT_OptimizeForBrowser\" minOccurs=\"0\"/>\n      <xsd:element name=\"relyOnVML\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowPNG\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotRelyOnCSS\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSaveAsSingleFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotOrganizeInFolder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseLongFileNames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pixelsPerInch\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"targetScreenSz\" type=\"CT_TargetScreenSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSmartTagsAsXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameScrollbar\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameScrollbar\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameScrollbar\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptimizeForBrowser\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_OnOff\">\n        <xsd:attribute name=\"target\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frame\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"longDesc\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"sourceFileName\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"marW\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"marH\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"scrollbar\" type=\"CT_FrameScrollbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"noResizeAllowed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkedToFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameLayout\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rows\"/>\n      <xsd:enumeration value=\"cols\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameLayout\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameLayout\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FramesetSplitbar\">\n    <xsd:sequence>\n      <xsd:element name=\"w\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBorder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"flatBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frameset\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"framesetSplitbar\" type=\"CT_FramesetSplitbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"frameLayout\" type=\"CT_FrameLayout\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xsd:element name=\"frame\" type=\"CT_Frame\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumPicBullet\">\n    <xsd:choice>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"numPicBulletId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LevelSuffix\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tab\"/>\n      <xsd:enumeration value=\"space\"/>\n      <xsd:enumeration value=\"nothing\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LevelSuffix\">\n    <xsd:attribute name=\"val\" type=\"ST_LevelSuffix\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"null\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LvlLegacy\">\n    <xsd:attribute name=\"legacy\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"legacySpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"legacyIndent\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlRestart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"isLgl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suff\" type=\"CT_LevelSuffix\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlText\" type=\"CT_LevelText\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlPicBulletId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"legacy\" type=\"CT_LvlLegacy\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlJc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n    <xsd:attribute name=\"tplc\" type=\"ST_LongHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"tentative\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MultiLevelType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"singleLevel\"/>\n      <xsd:enumeration value=\"multilevel\"/>\n      <xsd:enumeration value=\"hybridMultilevel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MultiLevelType\">\n    <xsd:attribute name=\"val\" type=\"ST_MultiLevelType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbstractNum\">\n    <xsd:sequence>\n      <xsd:element name=\"nsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"multiLevelType\" type=\"CT_MultiLevelType\" minOccurs=\"0\"/>\n      <xsd:element name=\"tmpl\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"numStyleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"abstractNumId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumLvl\">\n    <xsd:sequence>\n      <xsd:element name=\"startOverride\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Num\">\n    <xsd:sequence>\n      <xsd:element name=\"abstractNumId\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"lvlOverride\" type=\"CT_NumLvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Numbering\">\n    <xsd:sequence>\n      <xsd:element name=\"numPicBullet\" type=\"CT_NumPicBullet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"abstractNum\" type=\"CT_AbstractNum\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"num\" type=\"CT_Num\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"numIdMacAtCleanup\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblStyleOverrideType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"firstRow\"/>\n      <xsd:enumeration value=\"lastRow\"/>\n      <xsd:enumeration value=\"firstCol\"/>\n      <xsd:enumeration value=\"lastCol\"/>\n      <xsd:enumeration value=\"band1Vert\"/>\n      <xsd:enumeration value=\"band2Vert\"/>\n      <xsd:enumeration value=\"band1Horz\"/>\n      <xsd:enumeration value=\"band2Horz\"/>\n      <xsd:enumeration value=\"neCell\"/>\n      <xsd:enumeration value=\"nwCell\"/>\n      <xsd:enumeration value=\"seCell\"/>\n      <xsd:enumeration value=\"swCell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblStylePr\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_TblStyleOverrideType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"table\"/>\n      <xsd:enumeration value=\"numbering\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"aliases\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"basedOn\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"next\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"link\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoRedefine\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"uiPriority\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"semiHidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"unhideWhenUsed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"qFormat\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"locked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personal\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalCompose\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalReply\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStylePr\" type=\"CT_TblStylePr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_StyleType\" use=\"optional\"/>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"default\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"customStyle\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LsdException\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"uiPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"semiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"unhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"qFormat\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LatentStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"lsdException\" type=\"CT_LsdException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"defLockedState\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUIPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"defSemiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUnhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defQFormat\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"count\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Styles\">\n    <xsd:sequence>\n      <xsd:element name=\"docDefaults\" type=\"CT_DocDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"latentStyles\" type=\"CT_LatentStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Panose\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Panose\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decorative\"/>\n      <xsd:enumeration value=\"modern\"/>\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"swiss\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pitch\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"variable\"/>\n      <xsd:enumeration value=\"default\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pitch\">\n    <xsd:attribute name=\"val\" type=\"ST_Pitch\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSig\">\n    <xsd:attribute name=\"usb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb2\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb3\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontRel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"fontKey\" type=\"s:ST_Guid\"/>\n        <xsd:attribute name=\"subsetted\" type=\"s:ST_OnOff\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:sequence>\n      <xsd:element name=\"altName\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"panose1\" type=\"CT_Panose\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_Charset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notTrueType\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pitch\" type=\"CT_Pitch\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sig\" type=\"CT_FontSig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedRegular\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBold\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBoldItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontsList\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DivBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Div\">\n    <xsd:sequence>\n      <xsd:element name=\"blockQuote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bodyDiv\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"marLeft\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marRight\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marTop\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marBottom\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"divBdr\" type=\"CT_DivBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"divsChild\" type=\"CT_Divs\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Divs\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"div\" type=\"CT_Div\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\"/>\n  <xsd:group name=\"EG_MathContent\">\n    <xsd:choice>\n      <xsd:element ref=\"m:oMathPara\"/>\n      <xsd:element ref=\"m:oMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelChunkElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_BlockLevelChunkElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"altChunk\" type=\"CT_AltChunk\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RunLevelElts\">\n    <xsd:choice>\n      <xsd:element name=\"proofErr\" minOccurs=\"0\" type=\"CT_ProofErr\"/>\n      <xsd:element name=\"permStart\" minOccurs=\"0\" type=\"CT_PermStart\"/>\n      <xsd:element name=\"permEnd\" minOccurs=\"0\" type=\"CT_Perm\"/>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ins\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_RunTrackChange\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_RunTrackChange\"/>\n      <xsd:group ref=\"EG_MathContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Body\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sectPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SectPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n        minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Footnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"footnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"footnotes\" type=\"CT_Footnotes\"/>\n  <xsd:complexType name=\"CT_Endnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"endnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"endnotes\" type=\"CT_Endnotes\"/>\n  <xsd:element name=\"hdr\" type=\"CT_HdrFtr\"/>\n  <xsd:element name=\"ftr\" type=\"CT_HdrFtr\"/>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceuri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ThemeColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"background1\"/>\n      <xsd:enumeration value=\"text1\"/>\n      <xsd:enumeration value=\"background2\"/>\n      <xsd:enumeration value=\"text2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DocPartBehavior\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"pg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartBehavior\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartBehavior\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartBehaviors\">\n    <xsd:choice>\n      <xsd:element name=\"behavior\" type=\"CT_DocPartBehavior\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"autoExp\"/>\n      <xsd:enumeration value=\"toolbar\"/>\n      <xsd:enumeration value=\"speller\"/>\n      <xsd:enumeration value=\"formFld\"/>\n      <xsd:enumeration value=\"bbPlcHdr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartTypes\">\n    <xsd:choice>\n      <xsd:element name=\"type\" type=\"CT_DocPartType\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"all\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartGallery\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"placeholder\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"docParts\"/>\n      <xsd:enumeration value=\"coverPg\"/>\n      <xsd:enumeration value=\"eq\"/>\n      <xsd:enumeration value=\"ftrs\"/>\n      <xsd:enumeration value=\"hdrs\"/>\n      <xsd:enumeration value=\"pgNum\"/>\n      <xsd:enumeration value=\"tbls\"/>\n      <xsd:enumeration value=\"watermarks\"/>\n      <xsd:enumeration value=\"autoTxt\"/>\n      <xsd:enumeration value=\"txtBox\"/>\n      <xsd:enumeration value=\"pgNumT\"/>\n      <xsd:enumeration value=\"pgNumB\"/>\n      <xsd:enumeration value=\"pgNumMargins\"/>\n      <xsd:enumeration value=\"tblOfContents\"/>\n      <xsd:enumeration value=\"bib\"/>\n      <xsd:enumeration value=\"custQuickParts\"/>\n      <xsd:enumeration value=\"custCoverPg\"/>\n      <xsd:enumeration value=\"custEq\"/>\n      <xsd:enumeration value=\"custFtrs\"/>\n      <xsd:enumeration value=\"custHdrs\"/>\n      <xsd:enumeration value=\"custPgNum\"/>\n      <xsd:enumeration value=\"custTbls\"/>\n      <xsd:enumeration value=\"custWatermarks\"/>\n      <xsd:enumeration value=\"custAutoTxt\"/>\n      <xsd:enumeration value=\"custTxtBox\"/>\n      <xsd:enumeration value=\"custPgNumT\"/>\n      <xsd:enumeration value=\"custPgNumB\"/>\n      <xsd:enumeration value=\"custPgNumMargins\"/>\n      <xsd:enumeration value=\"custTblOfContents\"/>\n      <xsd:enumeration value=\"custBib\"/>\n      <xsd:enumeration value=\"custom1\"/>\n      <xsd:enumeration value=\"custom2\"/>\n      <xsd:enumeration value=\"custom3\"/>\n      <xsd:enumeration value=\"custom4\"/>\n      <xsd:enumeration value=\"custom5\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartGallery\">\n    <xsd:attribute name=\"val\" type=\"ST_DocPartGallery\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartCategory\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gallery\" type=\"CT_DocPartGallery\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"decorated\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartPr\">\n    <xsd:all>\n      <xsd:element name=\"name\" type=\"CT_DocPartName\" minOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"category\" type=\"CT_DocPartCategory\" minOccurs=\"0\"/>\n      <xsd:element name=\"types\" type=\"CT_DocPartTypes\" minOccurs=\"0\"/>\n      <xsd:element name=\"behaviors\" type=\"CT_DocPartBehaviors\" minOccurs=\"0\"/>\n      <xsd:element name=\"description\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"guid\" type=\"CT_Guid\" minOccurs=\"0\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartPr\" type=\"CT_DocPartPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartBody\" type=\"CT_Body\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocParts\">\n    <xsd:choice>\n      <xsd:element name=\"docPart\" type=\"CT_DocPart\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:element name=\"settings\" type=\"CT_Settings\"/>\n  <xsd:element name=\"webSettings\" type=\"CT_WebSettings\"/>\n  <xsd:element name=\"fonts\" type=\"CT_FontsList\"/>\n  <xsd:element name=\"numbering\" type=\"CT_Numbering\"/>\n  <xsd:element name=\"styles\" type=\"CT_Styles\"/>\n  <xsd:simpleType name=\"ST_CaptionPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"above\"/>\n      <xsd:enumeration value=\"below\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Caption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_CaptionPos\" use=\"optional\"/>\n    <xsd:attribute name=\"chapNum\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"heading\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"noLabel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"numFmt\" type=\"ST_NumberFormat\" use=\"optional\"/>\n    <xsd:attribute name=\"sep\" type=\"ST_ChapterSep\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaptions\">\n    <xsd:sequence>\n      <xsd:element name=\"autoCaption\" type=\"CT_AutoCaption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Captions\">\n    <xsd:sequence>\n      <xsd:element name=\"caption\" type=\"CT_Caption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"autoCaptions\" type=\"CT_AutoCaptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocumentBase\">\n    <xsd:sequence>\n      <xsd:element name=\"background\" type=\"CT_Background\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Document\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"body\" type=\"CT_Body\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n        <xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlossaryDocument\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"docParts\" type=\"CT_DocParts\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:element name=\"document\" type=\"CT_Document\"/>\n  <xsd:element name=\"glossaryDocument\" type=\"CT_GlossaryDocument\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd",
    "content": "<?xml version='1.0'?>\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xs:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xs:element name=\"Types\" type=\"CT_Types\"/>\n  <xs:element name=\"Default\" type=\"CT_Default\"/>\n  <xs:element name=\"Override\" type=\"CT_Override\"/>\n\n  <xs:complexType name=\"CT_Types\">\n    <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element ref=\"Default\"/>\n      <xs:element ref=\"Override\"/>\n    </xs:choice>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Default\">\n    <xs:attribute name=\"Extension\" type=\"ST_Extension\" use=\"required\"/>\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Override\">\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n    <xs:attribute name=\"PartName\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:simpleType name=\"ST_ContentType\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))/((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))((\\s+)*;(\\s+)*(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))=((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+)|(&quot;(([\\p{IsLatin-1Supplement}\\p{IsBasicLatin}-[\\p{Cc}&#127;&quot;\\n\\r]]|(\\s+))|(\\\\[\\p{IsBasicLatin}]))*&quot;))))*)\"\n      />\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:simpleType name=\"ST_Extension\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"([!$&amp;'\\(\\)\\*\\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\\-_~])+\"/>\n    </xs:restriction>\n  </xs:simpleType>\n</xs:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:dcterms=\"http://purl.org/dc/terms/\" elementFormDefault=\"qualified\" blockDefault=\"#all\">\n\n  <xs:import namespace=\"http://purl.org/dc/elements/1.1/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd\"/>\n  <xs:import namespace=\"http://purl.org/dc/terms/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd\"/>\n  <xs:import id=\"xml\" namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n\n  <xs:element name=\"coreProperties\" type=\"CT_CoreProperties\"/>\n\n  <xs:complexType name=\"CT_CoreProperties\">\n    <xs:all>\n      <xs:element name=\"category\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"contentStatus\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dcterms:created\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:creator\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:description\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:identifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"keywords\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Keywords\"/>\n      <xs:element ref=\"dc:language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"lastModifiedBy\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"lastPrinted\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:dateTime\"/>\n      <xs:element ref=\"dcterms:modified\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"revision\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dc:subject\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"version\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n    </xs:all>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keywords\" mixed=\"true\">\n    <xs:sequence>\n      <xs:element name=\"value\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Keyword\"/>\n    </xs:sequence>\n    <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keyword\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"SignatureTime\" type=\"CT_SignatureTime\"/>\n  <xsd:element name=\"RelationshipReference\" type=\"CT_RelationshipReference\"/>\n  <xsd:element name=\"RelationshipsGroupReference\" type=\"CT_RelationshipsGroupReference\"/>\n\n  <xsd:complexType name=\"CT_SignatureTime\">\n    <xsd:sequence>\n      <xsd:element name=\"Format\" type=\"ST_Format\"/>\n      <xsd:element name=\"Value\" type=\"ST_Value\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceId\" type=\"xsd:string\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipsGroupReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceType\" type=\"xsd:anyURI\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_Format\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n\n  <xsd:simpleType name=\"ST_Value\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\\.[0-9])(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"Relationships\" type=\"CT_Relationships\"/>\n  <xsd:element name=\"Relationship\" type=\"CT_Relationship\"/>\n\n  <xsd:complexType name=\"CT_Relationships\">\n    <xsd:sequence>\n      <xsd:element ref=\"Relationship\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_Relationship\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"TargetMode\" type=\"ST_TargetMode\" use=\"optional\"/>\n        <xsd:attribute name=\"Target\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Type\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Id\" type=\"xsd:ID\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_TargetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"External\"/>\n      <xsd:enumeration value=\"Internal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/mce/mc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\tattributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\"\n\ttargetNamespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--\n    This XSD is a modified version of the one found at:\n    https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd\n\n    This XSD has 2 objectives:\n\n        1. round tripping @mc:Ignorable\n\n\t\t\t<w:document\n\t\t\t            xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t            xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t\t\t            mc:Ignorable=\"w14 w15 wp14\">\n\n        2. enabling AlternateContent to be manipulated in certain elements\n           (in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)\n\n\t\tSee further ECMA-376, 4th Edition, Office Open XML File Formats\n\t\tPart 3 : Markup Compatibility and Extensibility\n   -->\n\n  <!--  Objective 1 -->\n  <xsd:attribute name=\"Ignorable\" type=\"xsd:string\" />\n\n  <!--  Objective 2 -->\n\t<xsd:attribute name=\"MustUnderstand\" type=\"xsd:string\"  />\n\t<xsd:attribute name=\"ProcessContent\" type=\"xsd:string\"  />\n\n<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a\nFallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice\nelements. -->\n\t<xsd:element name=\"AlternateContent\">\n\t\t<xsd:complexType>\n\t\t\t<xsd:sequence>\n\t\t\t\t<xsd:element name=\"Choice\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute name=\"Requires\" type=\"xsd:string\" use=\"required\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t\t<xsd:element name=\"Fallback\" minOccurs=\"0\" maxOccurs=\"1\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t</xsd:sequence>\n\t\t\t<!-- AlternateContent elements might include the attributes Ignorable,\n\t\t\t\tMustUnderstand and ProcessContent described in this Part of ECMA-376. These\n\t\t\t\tattributes’ qualified names shall be prefixed when associated with an AlternateContent\n\t\t\t\telement. -->\n\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t</xsd:complexType>\n\t</xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns=\"http://schemas.microsoft.com/office/word/2010/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2010/wordml\">\n   <!-- <xsd:import id=\"rel\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" schemaLocation=\"orel.xsd\"/> -->\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <!-- <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartbasetypes.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartsplineproperties.xsd\"/> -->\n   <xsd:complexType name=\"CT_LongHexNumber\">\n     <xsd:attribute name=\"val\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_OnOff\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"true\"/>\n       <xsd:enumeration value=\"false\"/>\n       <xsd:enumeration value=\"0\"/>\n       <xsd:enumeration value=\"1\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_OnOff\">\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\"/>\n   </xsd:complexType>\n   <xsd:element name=\"docId\" type=\"CT_LongHexNumber\"/>\n   <xsd:element name=\"conflictMode\" type=\"CT_OnOff\"/>\n   <xsd:attributeGroup name=\"AG_Parids\">\n     <xsd:attribute name=\"paraId\" type=\"w:ST_LongHexNumber\"/>\n     <xsd:attribute name=\"textId\" type=\"w:ST_LongHexNumber\"/>\n   </xsd:attributeGroup>\n   <xsd:attribute name=\"anchorId\" type=\"w:ST_LongHexNumber\"/>\n   <xsd:attribute name=\"noSpellErr\" type=\"ST_OnOff\"/>\n   <xsd:element name=\"customXmlConflictInsRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictInsRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:element name=\"customXmlConflictDelRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictDelRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:group name=\"EG_RunLevelConflicts\">\n     <xsd:sequence>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:group name=\"EG_Conflicts\">\n     <xsd:choice>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Percentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_Percentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositivePercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_SchemeColorVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"bg1\"/>\n       <xsd:enumeration value=\"tx1\"/>\n       <xsd:enumeration value=\"bg2\"/>\n       <xsd:enumeration value=\"tx2\"/>\n       <xsd:enumeration value=\"accent1\"/>\n       <xsd:enumeration value=\"accent2\"/>\n       <xsd:enumeration value=\"accent3\"/>\n       <xsd:enumeration value=\"accent4\"/>\n       <xsd:enumeration value=\"accent5\"/>\n       <xsd:enumeration value=\"accent6\"/>\n       <xsd:enumeration value=\"hlink\"/>\n       <xsd:enumeration value=\"folHlink\"/>\n       <xsd:enumeration value=\"dk1\"/>\n       <xsd:enumeration value=\"lt1\"/>\n       <xsd:enumeration value=\"dk2\"/>\n       <xsd:enumeration value=\"lt2\"/>\n       <xsd:enumeration value=\"phClr\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_RectAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PathShadeType\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"shape\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"rect\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LineCap\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"rnd\"/>\n       <xsd:enumeration value=\"sq\"/>\n       <xsd:enumeration value=\"flat\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PresetLineDashVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"solid\"/>\n       <xsd:enumeration value=\"dot\"/>\n       <xsd:enumeration value=\"sysDot\"/>\n       <xsd:enumeration value=\"dash\"/>\n       <xsd:enumeration value=\"sysDash\"/>\n       <xsd:enumeration value=\"lgDash\"/>\n       <xsd:enumeration value=\"dashDot\"/>\n       <xsd:enumeration value=\"sysDashDot\"/>\n       <xsd:enumeration value=\"lgDashDot\"/>\n       <xsd:enumeration value=\"lgDashDotDot\"/>\n       <xsd:enumeration value=\"sysDashDotDot\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PenAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"in\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_CompoundLine\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"sng\"/>\n       <xsd:enumeration value=\"dbl\"/>\n       <xsd:enumeration value=\"thickThin\"/>\n       <xsd:enumeration value=\"thinThick\"/>\n       <xsd:enumeration value=\"tri\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_RelativeRect\">\n     <xsd:attribute name=\"l\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"t\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"r\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"b\" use=\"optional\" type=\"a:ST_Percentage\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorTransform\">\n     <xsd:choice>\n       <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\"/>\n       <xsd:element name=\"sat\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satMod\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lum\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumMod\" type=\"CT_Percentage\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SRgbColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SchemeColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorChoice\">\n     <xsd:choice>\n       <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\"/>\n       <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Color\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStop\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"pos\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStopList\">\n     <xsd:sequence>\n       <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"10\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_LinearShadeProperties\">\n     <xsd:attribute name=\"ang\" type=\"a:ST_PositiveFixedAngle\" use=\"optional\"/>\n     <xsd:attribute name=\"scaled\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PathShadeProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ShadeProperties\">\n     <xsd:choice>\n       <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\"/>\n       <xsd:element name=\"path\" type=\"CT_PathShadeProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SolidColorFillProperties\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientFillProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_FillProperties\">\n     <xsd:choice>\n       <xsd:element name=\"noFill\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\"/>\n       <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_PresetLineDashProperties\">\n     <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineDashProperties\">\n     <xsd:choice>\n       <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n     <xsd:attribute name=\"lim\" type=\"a:ST_PositivePercentage\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineJoinProperties\">\n     <xsd:choice>\n       <xsd:element name=\"round\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"bevel\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_PresetCameraType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueTop\"/>\n       <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n       <xsd:enumeration value=\"legacyObliqueLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueFront\"/>\n       <xsd:enumeration value=\"legacyObliqueRight\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueBottom\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n       <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n       <xsd:enumeration value=\"orthographicFront\"/>\n       <xsd:enumeration value=\"isometricTopUp\"/>\n       <xsd:enumeration value=\"isometricTopDown\"/>\n       <xsd:enumeration value=\"isometricBottomUp\"/>\n       <xsd:enumeration value=\"isometricBottomDown\"/>\n       <xsd:enumeration value=\"isometricLeftUp\"/>\n       <xsd:enumeration value=\"isometricLeftDown\"/>\n       <xsd:enumeration value=\"isometricRightUp\"/>\n       <xsd:enumeration value=\"isometricRightDown\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n       <xsd:enumeration value=\"obliqueTopLeft\"/>\n       <xsd:enumeration value=\"obliqueTop\"/>\n       <xsd:enumeration value=\"obliqueTopRight\"/>\n       <xsd:enumeration value=\"obliqueLeft\"/>\n       <xsd:enumeration value=\"obliqueRight\"/>\n       <xsd:enumeration value=\"obliqueBottomLeft\"/>\n       <xsd:enumeration value=\"obliqueBottom\"/>\n       <xsd:enumeration value=\"obliqueBottomRight\"/>\n       <xsd:enumeration value=\"perspectiveFront\"/>\n       <xsd:enumeration value=\"perspectiveLeft\"/>\n       <xsd:enumeration value=\"perspectiveRight\"/>\n       <xsd:enumeration value=\"perspectiveAbove\"/>\n       <xsd:enumeration value=\"perspectiveBelow\"/>\n       <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveRelaxed\"/>\n       <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Camera\">\n     <xsd:attribute name=\"prst\" use=\"required\" type=\"ST_PresetCameraType\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SphereCoords\">\n     <xsd:attribute name=\"lat\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"lon\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"rev\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_LightRigType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyFlat1\"/>\n       <xsd:enumeration value=\"legacyFlat2\"/>\n       <xsd:enumeration value=\"legacyFlat3\"/>\n       <xsd:enumeration value=\"legacyFlat4\"/>\n       <xsd:enumeration value=\"legacyNormal1\"/>\n       <xsd:enumeration value=\"legacyNormal2\"/>\n       <xsd:enumeration value=\"legacyNormal3\"/>\n       <xsd:enumeration value=\"legacyNormal4\"/>\n       <xsd:enumeration value=\"legacyHarsh1\"/>\n       <xsd:enumeration value=\"legacyHarsh2\"/>\n       <xsd:enumeration value=\"legacyHarsh3\"/>\n       <xsd:enumeration value=\"legacyHarsh4\"/>\n       <xsd:enumeration value=\"threePt\"/>\n       <xsd:enumeration value=\"balanced\"/>\n       <xsd:enumeration value=\"soft\"/>\n       <xsd:enumeration value=\"harsh\"/>\n       <xsd:enumeration value=\"flood\"/>\n       <xsd:enumeration value=\"contrasting\"/>\n       <xsd:enumeration value=\"morning\"/>\n       <xsd:enumeration value=\"sunrise\"/>\n       <xsd:enumeration value=\"sunset\"/>\n       <xsd:enumeration value=\"chilly\"/>\n       <xsd:enumeration value=\"freezing\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"twoPt\"/>\n       <xsd:enumeration value=\"glow\"/>\n       <xsd:enumeration value=\"brightRoom\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LightRigDirection\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_LightRig\">\n     <xsd:sequence>\n       <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n     <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_BevelPresetType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"relaxedInset\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"slope\"/>\n       <xsd:enumeration value=\"cross\"/>\n       <xsd:enumeration value=\"angle\"/>\n       <xsd:enumeration value=\"softRound\"/>\n       <xsd:enumeration value=\"convex\"/>\n       <xsd:enumeration value=\"coolSlant\"/>\n       <xsd:enumeration value=\"divot\"/>\n       <xsd:enumeration value=\"riblet\"/>\n       <xsd:enumeration value=\"hardEdge\"/>\n       <xsd:enumeration value=\"artDeco\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Bevel\">\n     <xsd:attribute name=\"w\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"h\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_PresetMaterialType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyMatte\"/>\n       <xsd:enumeration value=\"legacyPlastic\"/>\n       <xsd:enumeration value=\"legacyMetal\"/>\n       <xsd:enumeration value=\"legacyWireframe\"/>\n       <xsd:enumeration value=\"matte\"/>\n       <xsd:enumeration value=\"plastic\"/>\n       <xsd:enumeration value=\"metal\"/>\n       <xsd:enumeration value=\"warmMatte\"/>\n       <xsd:enumeration value=\"translucentPowder\"/>\n       <xsd:enumeration value=\"powder\"/>\n       <xsd:enumeration value=\"dkEdge\"/>\n       <xsd:enumeration value=\"softEdge\"/>\n       <xsd:enumeration value=\"clear\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"softmetal\"/>\n       <xsd:enumeration value=\"none\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Glow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Shadow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Reflection\">\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"stA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"stPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"fadeDir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_FillTextEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_TextOutlineEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"w\" use=\"optional\" type=\"a:ST_LineWidth\"/>\n     <xsd:attribute name=\"cap\" use=\"optional\" type=\"ST_LineCap\"/>\n     <xsd:attribute name=\"cmpd\" use=\"optional\" type=\"ST_CompoundLine\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_PenAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Scene3D\">\n     <xsd:sequence>\n       <xsd:element name=\"camera\" type=\"CT_Camera\"/>\n       <xsd:element name=\"lightRig\" type=\"CT_LightRig\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Props3D\">\n     <xsd:sequence>\n       <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n       <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"extrusionH\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"contourW\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrTextEffects\">\n     <xsd:sequence>\n       <xsd:element name=\"glow\" minOccurs=\"0\" type=\"CT_Glow\"/>\n       <xsd:element name=\"shadow\" minOccurs=\"0\" type=\"CT_Shadow\"/>\n       <xsd:element name=\"reflection\" minOccurs=\"0\" type=\"CT_Reflection\"/>\n       <xsd:element name=\"textOutline\" minOccurs=\"0\" type=\"CT_TextOutlineEffect\"/>\n       <xsd:element name=\"textFill\" minOccurs=\"0\" type=\"CT_FillTextEffect\"/>\n       <xsd:element name=\"scene3d\" minOccurs=\"0\" type=\"CT_Scene3D\"/>\n       <xsd:element name=\"props3d\" minOccurs=\"0\" type=\"CT_Props3D\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_Ligatures\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"standard\"/>\n       <xsd:enumeration value=\"contextual\"/>\n       <xsd:enumeration value=\"historical\"/>\n       <xsd:enumeration value=\"discretional\"/>\n       <xsd:enumeration value=\"standardContextual\"/>\n       <xsd:enumeration value=\"standardHistorical\"/>\n       <xsd:enumeration value=\"contextualHistorical\"/>\n       <xsd:enumeration value=\"standardDiscretional\"/>\n       <xsd:enumeration value=\"contextualDiscretional\"/>\n       <xsd:enumeration value=\"historicalDiscretional\"/>\n       <xsd:enumeration value=\"standardContextualHistorical\"/>\n       <xsd:enumeration value=\"standardContextualDiscretional\"/>\n       <xsd:enumeration value=\"standardHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"contextualHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"all\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Ligatures\">\n     <xsd:attribute name=\"val\" type=\"ST_Ligatures\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumForm\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"lining\"/>\n       <xsd:enumeration value=\"oldStyle\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumForm\">\n     <xsd:attribute name=\"val\" type=\"ST_NumForm\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumSpacing\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"proportional\"/>\n       <xsd:enumeration value=\"tabular\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumSpacing\">\n     <xsd:attribute name=\"val\" type=\"ST_NumSpacing\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StyleSet\">\n     <xsd:attribute name=\"id\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StylisticSets\">\n     <xsd:sequence minOccurs=\"0\">\n       <xsd:element name=\"styleSet\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_StyleSet\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrOpenType\">\n     <xsd:sequence>\n       <xsd:element name=\"ligatures\" minOccurs=\"0\" type=\"CT_Ligatures\"/>\n       <xsd:element name=\"numForm\" minOccurs=\"0\" type=\"CT_NumForm\"/>\n       <xsd:element name=\"numSpacing\" minOccurs=\"0\" type=\"CT_NumSpacing\"/>\n       <xsd:element name=\"stylisticSets\" minOccurs=\"0\" type=\"CT_StylisticSets\"/>\n       <xsd:element name=\"cntxtAlts\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:element name=\"discardImageEditingData\" type=\"CT_OnOff\"/>\n   <xsd:element name=\"defaultImageDpi\" type=\"CT_DefaultImageDpi\"/>\n   <xsd:complexType name=\"CT_DefaultImageDpi\">\n     <xsd:attribute name=\"val\" type=\"w:ST_DecimalNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"entityPicker\" type=\"w:CT_Empty\"/>\n   <xsd:complexType name=\"CT_SdtCheckboxSymbol\">\n     <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n     <xsd:attribute name=\"val\" type=\"w:ST_ShortHexNumber\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SdtCheckbox\">\n     <xsd:sequence>\n       <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n       <xsd:element name=\"checkedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n       <xsd:element name=\"uncheckedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:element name=\"checkbox\" type=\"CT_SdtCheckbox\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2012/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:element name=\"color\" type=\"w12:CT_Color\"/>\n   <xsd:simpleType name=\"ST_SdtAppearance\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"boundingBox\"/>\n       <xsd:enumeration value=\"tags\"/>\n       <xsd:enumeration value=\"hidden\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:element name=\"dataBinding\" type=\"w12:CT_DataBinding\"/>\n   <xsd:complexType name=\"CT_SdtAppearance\">\n     <xsd:attribute name=\"val\" type=\"ST_SdtAppearance\"/>\n   </xsd:complexType>\n   <xsd:element name=\"appearance\" type=\"CT_SdtAppearance\"/>\n   <xsd:complexType name=\"CT_CommentsEx\">\n     <xsd:sequence>\n       <xsd:element name=\"commentEx\" type=\"CT_CommentEx\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentEx\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"paraIdParent\" type=\"w12:ST_LongHexNumber\" use=\"optional\"/>\n     <xsd:attribute name=\"done\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsEx\" type=\"CT_CommentsEx\"/>\n   <xsd:complexType name=\"CT_People\">\n     <xsd:sequence>\n       <xsd:element name=\"person\" type=\"CT_Person\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PresenceInfo\">\n     <xsd:attribute name=\"providerId\" type=\"xsd:string\" use=\"required\"/>\n     <xsd:attribute name=\"userId\" type=\"xsd:string\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Person\">\n     <xsd:sequence>\n       <xsd:element name=\"presenceInfo\" type=\"CT_PresenceInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"people\" type=\"CT_People\"/>\n   <xsd:complexType name=\"CT_SdtRepeatedSection\">\n     <xsd:sequence>\n       <xsd:element name=\"sectionTitle\" type=\"w12:CT_String\" minOccurs=\"0\"/>\n       <xsd:element name=\"doNotAllowInsertDeleteSection\" type=\"w12:CT_OnOff\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_Guid\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Guid\">\n     <xsd:attribute name=\"val\" type=\"ST_Guid\"/>\n   </xsd:complexType>\n   <xsd:element name=\"repeatingSection\" type=\"CT_SdtRepeatedSection\"/>\n   <xsd:element name=\"repeatingSectionItem\" type=\"w12:CT_Empty\"/>\n   <xsd:element name=\"chartTrackingRefBased\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"collapsed\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"docId\" type=\"CT_Guid\"/>\n   <xsd:element name=\"footnoteColumns\" type=\"w12:CT_DecimalNumber\"/>\n   <xsd:element name=\"webExtensionLinked\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"webExtensionCreated\" type=\"w12:CT_OnOff\"/>\n   <xsd:attribute name=\"restartNumberingAfterBreak\" type=\"s:ST_OnOff\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_Extension\">\n     <xsd:sequence>\n       <xsd:any processContents=\"lax\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_ExtensionList\">\n     <xsd:sequence>\n       <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\">\n   <xsd:import id=\"w16\" namespace=\"http://schemas.microsoft.com/office/word/2018/wordml\" schemaLocation=\"wml-2018.xsd\"/>\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import id=\"s\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"commentExtensible\" type=\"CT_CommentExtensible\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"durableId\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"dateUtc\" type=\"w:ST_DateTime\" use=\"optional\"/>\n     <xsd:attribute name=\"intelligentPlaceholder\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsExtensible\" type=\"CT_CommentsExtensible\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" targetNamespace=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsIds\">\n     <xsd:sequence>\n       <xsd:element name=\"commentId\" type=\"CT_CommentId\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentId\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"durableId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsIds\" type=\"CT_CommentsIds\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" targetNamespace=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:attribute name=\"storeItemChecksum\" type=\"w12:ST_String\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_SymEx\">\n     <xsd:attribute name=\"font\" type=\"w12:ST_String\"/>\n     <xsd:attribute name=\"char\" type=\"w12:ST_LongHexNumber\"/>\n   </xsd:complexType>\n   <xsd:element name=\"symEx\" type=\"CT_SymEx\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/pptx/scripts/office/soffice.py",
    "content": "\"\"\"\nHelper for running LibreOffice (soffice) in environments where AF_UNIX\nsockets may be blocked (e.g., sandboxed VMs).  Detects the restriction\nat runtime and applies an LD_PRELOAD shim if needed.\n\nUsage:\n    from office.soffice import run_soffice, get_soffice_env\n\n    # Option 1 – run soffice directly\n    result = run_soffice([\"--headless\", \"--convert-to\", \"pdf\", \"input.docx\"])\n\n    # Option 2 – get env dict for your own subprocess calls\n    env = get_soffice_env()\n    subprocess.run([\"soffice\", ...], env=env)\n\"\"\"\n\nimport os\nimport socket\nimport subprocess\nimport tempfile\nfrom pathlib import Path\n\n\ndef get_soffice_env() -> dict:\n    env = os.environ.copy()\n    env[\"SAL_USE_VCLPLUGIN\"] = \"svp\"\n\n    if _needs_shim():\n        shim = _ensure_shim()\n        env[\"LD_PRELOAD\"] = str(shim)\n\n    return env\n\n\ndef run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:\n    env = get_soffice_env()\n    return subprocess.run([\"soffice\"] + args, env=env, **kwargs)\n\n\n\n_SHIM_SO = Path(tempfile.gettempdir()) / \"lo_socket_shim.so\"\n\n\ndef _needs_shim() -> bool:\n    try:\n        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        s.close()\n        return False\n    except OSError:\n        return True\n\n\ndef _ensure_shim() -> Path:\n    if _SHIM_SO.exists():\n        return _SHIM_SO\n\n    src = Path(tempfile.gettempdir()) / \"lo_socket_shim.c\"\n    src.write_text(_SHIM_SOURCE)\n    subprocess.run(\n        [\"gcc\", \"-shared\", \"-fPIC\", \"-o\", str(_SHIM_SO), str(src), \"-ldl\"],\n        check=True,\n        capture_output=True,\n    )\n    src.unlink()\n    return _SHIM_SO\n\n\n\n_SHIM_SOURCE = r\"\"\"\n#define _GNU_SOURCE\n#include <dlfcn.h>\n#include <errno.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/socket.h>\n#include <unistd.h>\n\nstatic int (*real_socket)(int, int, int);\nstatic int (*real_socketpair)(int, int, int, int[2]);\nstatic int (*real_listen)(int, int);\nstatic int (*real_accept)(int, struct sockaddr *, socklen_t *);\nstatic int (*real_close)(int);\nstatic int (*real_read)(int, void *, size_t);\n\n/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */\nstatic int is_shimmed[1024];\nstatic int peer_of[1024];\nstatic int wake_r[1024];            /* accept() blocks reading this */\nstatic int wake_w[1024];            /* close()  writes to this      */\nstatic int listener_fd = -1;        /* FD that received listen()    */\n\n__attribute__((constructor))\nstatic void init(void) {\n    real_socket     = dlsym(RTLD_NEXT, \"socket\");\n    real_socketpair = dlsym(RTLD_NEXT, \"socketpair\");\n    real_listen     = dlsym(RTLD_NEXT, \"listen\");\n    real_accept     = dlsym(RTLD_NEXT, \"accept\");\n    real_close      = dlsym(RTLD_NEXT, \"close\");\n    real_read       = dlsym(RTLD_NEXT, \"read\");\n    for (int i = 0; i < 1024; i++) {\n        peer_of[i] = -1;\n        wake_r[i]  = -1;\n        wake_w[i]  = -1;\n    }\n}\n\n/* ---- socket ---------------------------------------------------------- */\nint socket(int domain, int type, int protocol) {\n    if (domain == AF_UNIX) {\n        int fd = real_socket(domain, type, protocol);\n        if (fd >= 0) return fd;\n        /* socket(AF_UNIX) blocked – fall back to socketpair(). */\n        int sv[2];\n        if (real_socketpair(domain, type, protocol, sv) == 0) {\n            if (sv[0] >= 0 && sv[0] < 1024) {\n                is_shimmed[sv[0]] = 1;\n                peer_of[sv[0]]    = sv[1];\n                int wp[2];\n                if (pipe(wp) == 0) {\n                    wake_r[sv[0]] = wp[0];\n                    wake_w[sv[0]] = wp[1];\n                }\n            }\n            return sv[0];\n        }\n        errno = EPERM;\n        return -1;\n    }\n    return real_socket(domain, type, protocol);\n}\n\n/* ---- listen ---------------------------------------------------------- */\nint listen(int sockfd, int backlog) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        listener_fd = sockfd;\n        return 0;\n    }\n    return real_listen(sockfd, backlog);\n}\n\n/* ---- accept ---------------------------------------------------------- */\nint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        /* Block until close() writes to the wake pipe. */\n        if (wake_r[sockfd] >= 0) {\n            char buf;\n            real_read(wake_r[sockfd], &buf, 1);\n        }\n        errno = ECONNABORTED;\n        return -1;\n    }\n    return real_accept(sockfd, addr, addrlen);\n}\n\n/* ---- close ----------------------------------------------------------- */\nint close(int fd) {\n    if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {\n        int was_listener = (fd == listener_fd);\n        is_shimmed[fd] = 0;\n\n        if (wake_w[fd] >= 0) {              /* unblock accept() */\n            char c = 0;\n            write(wake_w[fd], &c, 1);\n            real_close(wake_w[fd]);\n            wake_w[fd] = -1;\n        }\n        if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd]  = -1; }\n        if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }\n\n        if (was_listener)\n            _exit(0);                        /* conversion done – exit */\n    }\n    return real_close(fd);\n}\n\"\"\"\n\n\n\nif __name__ == \"__main__\":\n    import sys\n    result = run_soffice(sys.argv[1:])\n    sys.exit(result.returncode)\n"
  },
  {
    "path": "skills/pptx/scripts/office/unpack.py",
    "content": "\"\"\"Unpack Office files (DOCX, PPTX, XLSX) for editing.\n\nExtracts the ZIP archive, pretty-prints XML files, and optionally:\n- Merges adjacent runs with identical formatting (DOCX only)\n- Simplifies adjacent tracked changes from same author (DOCX only)\n\nUsage:\n    python unpack.py <office_file> <output_dir> [options]\n\nExamples:\n    python unpack.py document.docx unpacked/\n    python unpack.py presentation.pptx unpacked/\n    python unpack.py document.docx unpacked/ --merge-runs false\n\"\"\"\n\nimport argparse\nimport sys\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom helpers.merge_runs import merge_runs as do_merge_runs\nfrom helpers.simplify_redlines import simplify_redlines as do_simplify_redlines\n\nSMART_QUOTE_REPLACEMENTS = {\n    \"\\u201c\": \"&#x201C;\",  \n    \"\\u201d\": \"&#x201D;\",  \n    \"\\u2018\": \"&#x2018;\",  \n    \"\\u2019\": \"&#x2019;\",  \n}\n\n\ndef unpack(\n    input_file: str,\n    output_directory: str,\n    merge_runs: bool = True,\n    simplify_redlines: bool = True,\n) -> tuple[None, str]:\n    input_path = Path(input_file)\n    output_path = Path(output_directory)\n    suffix = input_path.suffix.lower()\n\n    if not input_path.exists():\n        return None, f\"Error: {input_file} does not exist\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {input_file} must be a .docx, .pptx, or .xlsx file\"\n\n    try:\n        output_path.mkdir(parents=True, exist_ok=True)\n\n        with zipfile.ZipFile(input_path, \"r\") as zf:\n            zf.extractall(output_path)\n\n        xml_files = list(output_path.rglob(\"*.xml\")) + list(output_path.rglob(\"*.rels\"))\n        for xml_file in xml_files:\n            _pretty_print_xml(xml_file)\n\n        message = f\"Unpacked {input_file} ({len(xml_files)} XML files)\"\n\n        if suffix == \".docx\":\n            if simplify_redlines:\n                simplify_count, _ = do_simplify_redlines(str(output_path))\n                message += f\", simplified {simplify_count} tracked changes\"\n\n            if merge_runs:\n                merge_count, _ = do_merge_runs(str(output_path))\n                message += f\", merged {merge_count} runs\"\n\n        for xml_file in xml_files:\n            _escape_smart_quotes(xml_file)\n\n        return None, message\n\n    except zipfile.BadZipFile:\n        return None, f\"Error: {input_file} is not a valid Office file\"\n    except Exception as e:\n        return None, f\"Error unpacking: {e}\"\n\n\ndef _pretty_print_xml(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        dom = defusedxml.minidom.parseString(content)\n        xml_file.write_bytes(dom.toprettyxml(indent=\"  \", encoding=\"utf-8\"))\n    except Exception:\n        pass  \n\n\ndef _escape_smart_quotes(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        for char, entity in SMART_QUOTE_REPLACEMENTS.items():\n            content = content.replace(char, entity)\n        xml_file.write_text(content, encoding=\"utf-8\")\n    except Exception:\n        pass\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Unpack an Office file (DOCX, PPTX, XLSX) for editing\"\n    )\n    parser.add_argument(\"input_file\", help=\"Office file to unpack\")\n    parser.add_argument(\"output_directory\", help=\"Output directory\")\n    parser.add_argument(\n        \"--merge-runs\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent runs with identical formatting (DOCX only, default: true)\",\n    )\n    parser.add_argument(\n        \"--simplify-redlines\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent tracked changes from same author (DOCX only, default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = unpack(\n        args.input_file,\n        args.output_directory,\n        merge_runs=args.merge_runs,\n        simplify_redlines=args.simplify_redlines,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/pptx/scripts/office/validate.py",
    "content": "\"\"\"\nCommand line tool to validate Office document XML files against XSD schemas and tracked changes.\n\nUsage:\n    python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]\n\nThe first argument can be either:\n- An unpacked directory containing the Office document XML files\n- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory\n\nAuto-repair fixes:\n- paraId/durableId values that exceed OOXML limits\n- Missing xml:space=\"preserve\" on w:t elements with whitespace\n\"\"\"\n\nimport argparse\nimport sys\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Validate Office document XML files\")\n    parser.add_argument(\n        \"path\",\n        help=\"Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)\",\n    )\n    parser.add_argument(\n        \"--original\",\n        required=False,\n        default=None,\n        help=\"Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.\",\n    )\n    parser.add_argument(\n        \"-v\",\n        \"--verbose\",\n        action=\"store_true\",\n        help=\"Enable verbose output\",\n    )\n    parser.add_argument(\n        \"--auto-repair\",\n        action=\"store_true\",\n        help=\"Automatically repair common issues (hex IDs, whitespace preservation)\",\n    )\n    parser.add_argument(\n        \"--author\",\n        default=\"Claude\",\n        help=\"Author name for redlining validation (default: Claude)\",\n    )\n    args = parser.parse_args()\n\n    path = Path(args.path)\n    assert path.exists(), f\"Error: {path} does not exist\"\n\n    original_file = None\n    if args.original:\n        original_file = Path(args.original)\n        assert original_file.is_file(), f\"Error: {original_file} is not a file\"\n        assert original_file.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"], (\n            f\"Error: {original_file} must be a .docx, .pptx, or .xlsx file\"\n        )\n\n    file_extension = (original_file or path).suffix.lower()\n    assert file_extension in [\".docx\", \".pptx\", \".xlsx\"], (\n        f\"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file.\"\n    )\n\n    if path.is_file() and path.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"]:\n        temp_dir = tempfile.mkdtemp()\n        with zipfile.ZipFile(path, \"r\") as zf:\n            zf.extractall(temp_dir)\n        unpacked_dir = Path(temp_dir)\n    else:\n        assert path.is_dir(), f\"Error: {path} is not a directory or Office file\"\n        unpacked_dir = path\n\n    match file_extension:\n        case \".docx\":\n            validators = [\n                DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n            if original_file:\n                validators.append(\n                    RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)  \n                )\n        case \".pptx\":\n            validators = [\n                PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n        case _:\n            print(f\"Error: Validation not supported for file type {file_extension}\")\n            sys.exit(1)\n\n    if args.auto_repair:\n        total_repairs = sum(v.repair() for v in validators)\n        if total_repairs:\n            print(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        print(\"All validations PASSED!\")\n\n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/pptx/scripts/office/validators/__init__.py",
    "content": "\"\"\"\nValidation modules for Word document processing.\n\"\"\"\n\nfrom .base import BaseSchemaValidator\nfrom .docx import DOCXSchemaValidator\nfrom .pptx import PPTXSchemaValidator\nfrom .redlining import RedliningValidator\n\n__all__ = [\n    \"BaseSchemaValidator\",\n    \"DOCXSchemaValidator\",\n    \"PPTXSchemaValidator\",\n    \"RedliningValidator\",\n]\n"
  },
  {
    "path": "skills/pptx/scripts/office/validators/base.py",
    "content": "\"\"\"\nBase validator with common validation logic for document files.\n\"\"\"\n\nimport re\nfrom pathlib import Path\n\nimport defusedxml.minidom\nimport lxml.etree\n\n\nclass BaseSchemaValidator:\n\n    IGNORED_VALIDATION_ERRORS = [\n        \"hyphenationZone\",\n        \"purl.org/dc/terms\",\n    ]\n\n    UNIQUE_ID_REQUIREMENTS = {\n        \"comment\": (\"id\", \"file\"),  \n        \"commentrangestart\": (\"id\", \"file\"),  \n        \"commentrangeend\": (\"id\", \"file\"),  \n        \"bookmarkstart\": (\"id\", \"file\"),  \n        \"bookmarkend\": (\"id\", \"file\"),  \n        \"sldid\": (\"id\", \"file\"),  \n        \"sldmasterid\": (\"id\", \"global\"),  \n        \"sldlayoutid\": (\"id\", \"global\"),  \n        \"cm\": (\"authorid\", \"file\"),  \n        \"sheet\": (\"sheetid\", \"file\"),  \n        \"definedname\": (\"id\", \"file\"),  \n        \"cxnsp\": (\"id\", \"file\"),  \n        \"sp\": (\"id\", \"file\"),  \n        \"pic\": (\"id\", \"file\"),  \n        \"grpsp\": (\"id\", \"file\"),  \n    }\n\n    EXCLUDED_ID_CONTAINERS = {\n        \"sectionlst\",  \n    }\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    SCHEMA_MAPPINGS = {\n        \"word\": \"ISO-IEC29500-4_2016/wml.xsd\",  \n        \"ppt\": \"ISO-IEC29500-4_2016/pml.xsd\",  \n        \"xl\": \"ISO-IEC29500-4_2016/sml.xsd\",  \n        \"[Content_Types].xml\": \"ecma/fouth-edition/opc-contentTypes.xsd\",\n        \"app.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd\",\n        \"core.xml\": \"ecma/fouth-edition/opc-coreProperties.xsd\",\n        \"custom.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd\",\n        \".rels\": \"ecma/fouth-edition/opc-relationships.xsd\",\n        \"people.xml\": \"microsoft/wml-2012.xsd\",\n        \"commentsIds.xml\": \"microsoft/wml-cid-2016.xsd\",\n        \"commentsExtensible.xml\": \"microsoft/wml-cex-2018.xsd\",\n        \"commentsExtended.xml\": \"microsoft/wml-2012.xsd\",\n        \"chart\": \"ISO-IEC29500-4_2016/dml-chart.xsd\",\n        \"theme\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n        \"drawing\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n    }\n\n    MC_NAMESPACE = \"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\"\n\n    PACKAGE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/relationships\"\n    )\n    OFFICE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    )\n    CONTENT_TYPES_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/content-types\"\n    )\n\n    MAIN_CONTENT_FOLDERS = {\"word\", \"ppt\", \"xl\"}\n\n    OOXML_NAMESPACES = {\n        \"http://schemas.openxmlformats.org/officeDocument/2006/math\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n        \"http://schemas.openxmlformats.org/schemaLibrary/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chart\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/diagram\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n        \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\",\n        \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\",\n        \"http://www.w3.org/XML/1998/namespace\",\n    }\n\n    def __init__(self, unpacked_dir, original_file=None, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir).resolve()\n        self.original_file = Path(original_file) if original_file else None\n        self.verbose = verbose\n\n        self.schemas_dir = Path(__file__).parent.parent / \"schemas\"\n\n        patterns = [\"*.xml\", \"*.rels\"]\n        self.xml_files = [\n            f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)\n        ]\n\n        if not self.xml_files:\n            print(f\"Warning: No XML files found in {self.unpacked_dir}\")\n\n    def validate(self):\n        raise NotImplementedError(\"Subclasses must implement the validate method\")\n\n    def repair(self) -> int:\n        return self.repair_whitespace_preservation()\n\n    def repair_whitespace_preservation(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if elem.tagName.endswith(\":t\") and elem.firstChild:\n                        text = elem.firstChild.nodeValue\n                        if text and (text.startswith((' ', '\\t')) or text.endswith((' ', '\\t'))):\n                            if elem.getAttribute(\"xml:space\") != \"preserve\":\n                                elem.setAttribute(\"xml:space\", \"preserve\")\n                                text_preview = repr(text[:30]) + \"...\" if len(text) > 30 else repr(text)\n                                print(f\"  Repaired: {xml_file.name}: Added xml:space='preserve' to {elem.tagName}: {text_preview}\")\n                                repairs += 1\n                                modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n    def validate_xml(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                lxml.etree.parse(str(xml_file))\n            except lxml.etree.XMLSyntaxError as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Line {e.lineno}: {e.msg}\"\n                )\n            except Exception as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Unexpected error: {str(e)}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} XML violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All XML files are well-formed\")\n            return True\n\n    def validate_namespaces(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                declared = set(root.nsmap.keys()) - {None}  \n\n                for attr_val in [\n                    v for k, v in root.attrib.items() if k.endswith(\"Ignorable\")\n                ]:\n                    undeclared = set(attr_val.split()) - declared\n                    errors.extend(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Namespace '{ns}' in Ignorable but not declared\"\n                        for ns in undeclared\n                    )\n            except lxml.etree.XMLSyntaxError:\n                continue\n\n        if errors:\n            print(f\"FAILED - {len(errors)} namespace issues:\")\n            for error in errors:\n                print(error)\n            return False\n        if self.verbose:\n            print(\"PASSED - All namespace prefixes properly declared\")\n        return True\n\n    def validate_unique_ids(self):\n        errors = []\n        global_ids = {}  \n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                file_ids = {}  \n\n                mc_elements = root.xpath(\n                    \".//mc:AlternateContent\", namespaces={\"mc\": self.MC_NAMESPACE}\n                )\n                for elem in mc_elements:\n                    elem.getparent().remove(elem)\n\n                for elem in root.iter():\n                    tag = (\n                        elem.tag.split(\"}\")[-1].lower()\n                        if \"}\" in elem.tag\n                        else elem.tag.lower()\n                    )\n\n                    if tag in self.UNIQUE_ID_REQUIREMENTS:\n                        in_excluded_container = any(\n                            ancestor.tag.split(\"}\")[-1].lower() in self.EXCLUDED_ID_CONTAINERS\n                            for ancestor in elem.iterancestors()\n                        )\n                        if in_excluded_container:\n                            continue\n\n                        attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]\n\n                        id_value = None\n                        for attr, value in elem.attrib.items():\n                            attr_local = (\n                                attr.split(\"}\")[-1].lower()\n                                if \"}\" in attr\n                                else attr.lower()\n                            )\n                            if attr_local == attr_name:\n                                id_value = value\n                                break\n\n                        if id_value is not None:\n                            if scope == \"global\":\n                                if id_value in global_ids:\n                                    prev_file, prev_line, prev_tag = global_ids[\n                                        id_value\n                                    ]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> \"\n                                        f\"already used in {prev_file} at line {prev_line} in <{prev_tag}>\"\n                                    )\n                                else:\n                                    global_ids[id_value] = (\n                                        xml_file.relative_to(self.unpacked_dir),\n                                        elem.sourceline,\n                                        tag,\n                                    )\n                            elif scope == \"file\":\n                                key = (tag, attr_name)\n                                if key not in file_ids:\n                                    file_ids[key] = {}\n\n                                if id_value in file_ids[key]:\n                                    prev_line = file_ids[key][id_value]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> \"\n                                        f\"(first occurrence at line {prev_line})\"\n                                    )\n                                else:\n                                    file_ids[key][id_value] = elem.sourceline\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} ID uniqueness violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All required IDs are unique\")\n            return True\n\n    def validate_file_references(self):\n        errors = []\n\n        rels_files = list(self.unpacked_dir.rglob(\"*.rels\"))\n\n        if not rels_files:\n            if self.verbose:\n                print(\"PASSED - No .rels files found\")\n            return True\n\n        all_files = []\n        for file_path in self.unpacked_dir.rglob(\"*\"):\n            if (\n                file_path.is_file()\n                and file_path.name != \"[Content_Types].xml\"\n                and not file_path.name.endswith(\".rels\")\n            ):  \n                all_files.append(file_path.resolve())\n\n        all_referenced_files = set()\n\n        if self.verbose:\n            print(\n                f\"Found {len(rels_files)} .rels files and {len(all_files)} target files\"\n            )\n\n        for rels_file in rels_files:\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                rels_dir = rels_file.parent\n\n                referenced_files = set()\n                broken_refs = []\n\n                for rel in rels_root.findall(\n                    \".//ns:Relationship\",\n                    namespaces={\"ns\": self.PACKAGE_RELATIONSHIPS_NAMESPACE},\n                ):\n                    target = rel.get(\"Target\")\n                    if target and not target.startswith(\n                        (\"http\", \"mailto:\")\n                    ):  \n                        if target.startswith(\"/\"):\n                            target_path = self.unpacked_dir / target.lstrip(\"/\")\n                        elif rels_file.name == \".rels\":\n                            target_path = self.unpacked_dir / target\n                        else:\n                            base_dir = rels_dir.parent\n                            target_path = base_dir / target\n\n                        try:\n                            target_path = target_path.resolve()\n                            if target_path.exists() and target_path.is_file():\n                                referenced_files.add(target_path)\n                                all_referenced_files.add(target_path)\n                            else:\n                                broken_refs.append((target, rel.sourceline))\n                        except (OSError, ValueError):\n                            broken_refs.append((target, rel.sourceline))\n\n                if broken_refs:\n                    rel_path = rels_file.relative_to(self.unpacked_dir)\n                    for broken_ref, line_num in broken_refs:\n                        errors.append(\n                            f\"  {rel_path}: Line {line_num}: Broken reference to {broken_ref}\"\n                        )\n\n            except Exception as e:\n                rel_path = rels_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error parsing {rel_path}: {e}\")\n\n        unreferenced_files = set(all_files) - all_referenced_files\n\n        if unreferenced_files:\n            for unref_file in sorted(unreferenced_files):\n                unref_rel_path = unref_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Unreferenced file: {unref_rel_path}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"CRITICAL: These errors will cause the document to appear corrupt. \"\n                + \"Broken references MUST be fixed, \"\n                + \"and unreferenced files MUST be referenced or removed.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All references are valid and all files are properly referenced\"\n                )\n            return True\n\n    def validate_all_relationship_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.suffix == \".rels\":\n                continue\n\n            rels_dir = xml_file.parent / \"_rels\"\n            rels_file = rels_dir / f\"{xml_file.name}.rels\"\n\n            if not rels_file.exists():\n                continue\n\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n                rid_to_type = {}\n\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rid = rel.get(\"Id\")\n                    rel_type = rel.get(\"Type\", \"\")\n                    if rid:\n                        if rid in rid_to_type:\n                            rels_rel_path = rels_file.relative_to(self.unpacked_dir)\n                            errors.append(\n                                f\"  {rels_rel_path}: Line {rel.sourceline}: \"\n                                f\"Duplicate relationship ID '{rid}' (IDs must be unique)\"\n                            )\n                        type_name = (\n                            rel_type.split(\"/\")[-1] if \"/\" in rel_type else rel_type\n                        )\n                        rid_to_type[rid] = type_name\n\n                xml_root = lxml.etree.parse(str(xml_file)).getroot()\n\n                r_ns = self.OFFICE_RELATIONSHIPS_NAMESPACE\n                rid_attrs_to_check = [\"id\", \"embed\", \"link\"]\n                for elem in xml_root.iter():\n                    for attr_name in rid_attrs_to_check:\n                        rid_attr = elem.get(f\"{{{r_ns}}}{attr_name}\")\n                        if not rid_attr:\n                            continue\n                        xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                        elem_name = (\n                            elem.tag.split(\"}\")[-1] if \"}\" in elem.tag else elem.tag\n                        )\n\n                        if rid_attr not in rid_to_type:\n                            errors.append(\n                                f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                f\"<{elem_name}> r:{attr_name} references non-existent relationship '{rid_attr}' \"\n                                f\"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})\"\n                            )\n                        elif attr_name == \"id\" and self.ELEMENT_RELATIONSHIP_TYPES:\n                            expected_type = self._get_expected_relationship_type(\n                                elem_name\n                            )\n                            if expected_type:\n                                actual_type = rid_to_type[rid_attr]\n                                if expected_type not in actual_type.lower():\n                                    errors.append(\n                                        f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                        f\"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' \"\n                                        f\"but should point to a '{expected_type}' relationship\"\n                                    )\n\n            except Exception as e:\n                xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error processing {xml_rel_path}: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship ID reference errors:\")\n            for error in errors:\n                print(error)\n            print(\"\\nThese ID mismatches will cause the document to appear corrupt!\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All relationship ID references are valid\")\n            return True\n\n    def _get_expected_relationship_type(self, element_name):\n        elem_lower = element_name.lower()\n\n        if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:\n            return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]\n\n        if elem_lower.endswith(\"id\") and len(elem_lower) > 2:\n            prefix = elem_lower[:-2]  \n            if prefix.endswith(\"master\"):\n                return prefix.lower()\n            elif prefix.endswith(\"layout\"):\n                return prefix.lower()\n            else:\n                if prefix == \"sld\":\n                    return \"slide\"\n                return prefix.lower()\n\n        if elem_lower.endswith(\"reference\") and len(elem_lower) > 9:\n            prefix = elem_lower[:-9]  \n            return prefix.lower()\n\n        return None\n\n    def validate_content_types(self):\n        errors = []\n\n        content_types_file = self.unpacked_dir / \"[Content_Types].xml\"\n        if not content_types_file.exists():\n            print(\"FAILED - [Content_Types].xml file not found\")\n            return False\n\n        try:\n            root = lxml.etree.parse(str(content_types_file)).getroot()\n            declared_parts = set()\n            declared_extensions = set()\n\n            for override in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override\"\n            ):\n                part_name = override.get(\"PartName\")\n                if part_name is not None:\n                    declared_parts.add(part_name.lstrip(\"/\"))\n\n            for default in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default\"\n            ):\n                extension = default.get(\"Extension\")\n                if extension is not None:\n                    declared_extensions.add(extension.lower())\n\n            declarable_roots = {\n                \"sld\",\n                \"sldLayout\",\n                \"sldMaster\",\n                \"presentation\",  \n                \"document\",  \n                \"workbook\",\n                \"worksheet\",  \n                \"theme\",  \n            }\n\n            media_extensions = {\n                \"png\": \"image/png\",\n                \"jpg\": \"image/jpeg\",\n                \"jpeg\": \"image/jpeg\",\n                \"gif\": \"image/gif\",\n                \"bmp\": \"image/bmp\",\n                \"tiff\": \"image/tiff\",\n                \"wmf\": \"image/x-wmf\",\n                \"emf\": \"image/x-emf\",\n            }\n\n            all_files = list(self.unpacked_dir.rglob(\"*\"))\n            all_files = [f for f in all_files if f.is_file()]\n\n            for xml_file in self.xml_files:\n                path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(\n                    \"\\\\\", \"/\"\n                )\n\n                if any(\n                    skip in path_str\n                    for skip in [\".rels\", \"[Content_Types]\", \"docProps/\", \"_rels/\"]\n                ):\n                    continue\n\n                try:\n                    root_tag = lxml.etree.parse(str(xml_file)).getroot().tag\n                    root_name = root_tag.split(\"}\")[-1] if \"}\" in root_tag else root_tag\n\n                    if root_name in declarable_roots and path_str not in declared_parts:\n                        errors.append(\n                            f\"  {path_str}: File with <{root_name}> root not declared in [Content_Types].xml\"\n                        )\n\n                except Exception:\n                    continue  \n\n            for file_path in all_files:\n                if file_path.suffix.lower() in {\".xml\", \".rels\"}:\n                    continue\n                if file_path.name == \"[Content_Types].xml\":\n                    continue\n                if \"_rels\" in file_path.parts or \"docProps\" in file_path.parts:\n                    continue\n\n                extension = file_path.suffix.lstrip(\".\").lower()\n                if extension and extension not in declared_extensions:\n                    if extension in media_extensions:\n                        relative_path = file_path.relative_to(self.unpacked_dir)\n                        errors.append(\n                            f'  {relative_path}: File with extension \\'{extension}\\' not declared in [Content_Types].xml - should add: <Default Extension=\"{extension}\" ContentType=\"{media_extensions[extension]}\"/>'\n                        )\n\n        except Exception as e:\n            errors.append(f\"  Error parsing [Content_Types].xml: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} content type declaration errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All content files are properly declared in [Content_Types].xml\"\n                )\n            return True\n\n    def validate_file_against_xsd(self, xml_file, verbose=False):\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n\n        is_valid, current_errors = self._validate_single_file_xsd(\n            xml_file, unpacked_dir\n        )\n\n        if is_valid is None:\n            return None, set()  \n        elif is_valid:\n            return True, set()  \n\n        original_errors = self._get_original_file_errors(xml_file)\n\n        assert current_errors is not None\n        new_errors = current_errors - original_errors\n\n        new_errors = {\n            e for e in new_errors\n            if not any(pattern in e for pattern in self.IGNORED_VALIDATION_ERRORS)\n        }\n\n        if new_errors:\n            if verbose:\n                relative_path = xml_file.relative_to(unpacked_dir)\n                print(f\"FAILED - {relative_path}: {len(new_errors)} new error(s)\")\n                for error in list(new_errors)[:3]:\n                    truncated = error[:250] + \"...\" if len(error) > 250 else error\n                    print(f\"  - {truncated}\")\n            return False, new_errors\n        else:\n            if verbose:\n                print(\n                    f\"PASSED - No new errors (original had {len(current_errors)} errors)\"\n                )\n            return True, set()\n\n    def validate_against_xsd(self):\n        new_errors = []\n        original_error_count = 0\n        valid_count = 0\n        skipped_count = 0\n\n        for xml_file in self.xml_files:\n            relative_path = str(xml_file.relative_to(self.unpacked_dir))\n            is_valid, new_file_errors = self.validate_file_against_xsd(\n                xml_file, verbose=False\n            )\n\n            if is_valid is None:\n                skipped_count += 1\n                continue\n            elif is_valid and not new_file_errors:\n                valid_count += 1\n                continue\n            elif is_valid:\n                original_error_count += 1\n                valid_count += 1\n                continue\n\n            new_errors.append(f\"  {relative_path}: {len(new_file_errors)} new error(s)\")\n            for error in list(new_file_errors)[:3]:  \n                new_errors.append(\n                    f\"    - {error[:250]}...\" if len(error) > 250 else f\"    - {error}\"\n                )\n\n        if self.verbose:\n            print(f\"Validated {len(self.xml_files)} files:\")\n            print(f\"  - Valid: {valid_count}\")\n            print(f\"  - Skipped (no schema): {skipped_count}\")\n            if original_error_count:\n                print(f\"  - With original errors (ignored): {original_error_count}\")\n            print(\n                f\"  - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith('    ')]) or 0}\"\n            )\n\n        if new_errors:\n            print(\"\\nFAILED - Found NEW validation errors:\")\n            for error in new_errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"\\nPASSED - No new XSD validation errors introduced\")\n            return True\n\n    def _get_schema_path(self, xml_file):\n        if xml_file.name in self.SCHEMA_MAPPINGS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]\n\n        if xml_file.suffix == \".rels\":\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\".rels\"]\n\n        if \"charts/\" in str(xml_file) and xml_file.name.startswith(\"chart\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"chart\"]\n\n        if \"theme/\" in str(xml_file) and xml_file.name.startswith(\"theme\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"theme\"]\n\n        if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]\n\n        return None\n\n    def _clean_ignorable_namespaces(self, xml_doc):\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        for elem in xml_copy.iter():\n            attrs_to_remove = []\n\n            for attr in elem.attrib:\n                if \"{\" in attr:\n                    ns = attr.split(\"}\")[0][1:]\n                    if ns not in self.OOXML_NAMESPACES:\n                        attrs_to_remove.append(attr)\n\n            for attr in attrs_to_remove:\n                del elem.attrib[attr]\n\n        self._remove_ignorable_elements(xml_copy)\n\n        return lxml.etree.ElementTree(xml_copy)\n\n    def _remove_ignorable_elements(self, root):\n        elements_to_remove = []\n\n        for elem in list(root):\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n\n            tag_str = str(elem.tag)\n            if tag_str.startswith(\"{\"):\n                ns = tag_str.split(\"}\")[0][1:]\n                if ns not in self.OOXML_NAMESPACES:\n                    elements_to_remove.append(elem)\n                    continue\n\n            self._remove_ignorable_elements(elem)\n\n        for elem in elements_to_remove:\n            root.remove(elem)\n\n    def _preprocess_for_mc_ignorable(self, xml_doc):\n        root = xml_doc.getroot()\n\n        if f\"{{{self.MC_NAMESPACE}}}Ignorable\" in root.attrib:\n            del root.attrib[f\"{{{self.MC_NAMESPACE}}}Ignorable\"]\n\n        return xml_doc\n\n    def _validate_single_file_xsd(self, xml_file, base_path):\n        schema_path = self._get_schema_path(xml_file)\n        if not schema_path:\n            return None, None  \n\n        try:\n            with open(schema_path, \"rb\") as xsd_file:\n                parser = lxml.etree.XMLParser()\n                xsd_doc = lxml.etree.parse(\n                    xsd_file, parser=parser, base_url=str(schema_path)\n                )\n                schema = lxml.etree.XMLSchema(xsd_doc)\n\n            with open(xml_file, \"r\") as f:\n                xml_doc = lxml.etree.parse(f)\n\n            xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)\n            xml_doc = self._preprocess_for_mc_ignorable(xml_doc)\n\n            relative_path = xml_file.relative_to(base_path)\n            if (\n                relative_path.parts\n                and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS\n            ):\n                xml_doc = self._clean_ignorable_namespaces(xml_doc)\n\n            if schema.validate(xml_doc):\n                return True, set()\n            else:\n                errors = set()\n                for error in schema.error_log:\n                    errors.add(error.message)\n                return False, errors\n\n        except Exception as e:\n            return False, {str(e)}\n\n    def _get_original_file_errors(self, xml_file):\n        if self.original_file is None:\n            return set()\n\n        import tempfile\n        import zipfile\n\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n        relative_path = xml_file.relative_to(unpacked_dir)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                zip_ref.extractall(temp_path)\n\n            original_xml_file = temp_path / relative_path\n\n            if not original_xml_file.exists():\n                return set()\n\n            is_valid, errors = self._validate_single_file_xsd(\n                original_xml_file, temp_path\n            )\n            return errors if errors else set()\n\n    def _remove_template_tags_from_text_nodes(self, xml_doc):\n        warnings = []\n        template_pattern = re.compile(r\"\\{\\{[^}]*\\}\\}\")\n\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        def process_text_content(text, content_type):\n            if not text:\n                return text\n            matches = list(template_pattern.finditer(text))\n            if matches:\n                for match in matches:\n                    warnings.append(\n                        f\"Found template tag in {content_type}: {match.group()}\"\n                    )\n                return template_pattern.sub(\"\", text)\n            return text\n\n        for elem in xml_copy.iter():\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n            tag_str = str(elem.tag)\n            if tag_str.endswith(\"}t\") or tag_str == \"t\":\n                continue\n\n            elem.text = process_text_content(elem.text, \"text content\")\n            elem.tail = process_text_content(elem.tail, \"tail content\")\n\n        return lxml.etree.ElementTree(xml_copy), warnings\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/pptx/scripts/office/validators/docx.py",
    "content": "\"\"\"\nValidator for Word document XML files against XSD schemas.\n\"\"\"\n\nimport random\nimport re\nimport tempfile\nimport zipfile\n\nimport defusedxml.minidom\nimport lxml.etree\n\nfrom .base import BaseSchemaValidator\n\n\nclass DOCXSchemaValidator(BaseSchemaValidator):\n\n    WORD_2006_NAMESPACE = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    W14_NAMESPACE = \"http://schemas.microsoft.com/office/word/2010/wordml\"\n    W16CID_NAMESPACE = \"http://schemas.microsoft.com/office/word/2016/wordml/cid\"\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_whitespace_preservation():\n            all_valid = False\n\n        if not self.validate_deletions():\n            all_valid = False\n\n        if not self.validate_insertions():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_id_constraints():\n            all_valid = False\n\n        if not self.validate_comment_markers():\n            all_valid = False\n\n        self.compare_paragraph_counts()\n\n        return all_valid\n\n    def validate_whitespace_preservation(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter(f\"{{{self.WORD_2006_NAMESPACE}}}t\"):\n                    if elem.text:\n                        text = elem.text\n                        if re.search(r\"^[ \\t\\n\\r]\", text) or re.search(\n                            r\"[ \\t\\n\\r]$\", text\n                        ):\n                            xml_space_attr = f\"{{{self.XML_NAMESPACE}}}space\"\n                            if (\n                                xml_space_attr not in elem.attrib\n                                or elem.attrib[xml_space_attr] != \"preserve\"\n                            ):\n                                text_preview = (\n                                    repr(text)[:50] + \"...\"\n                                    if len(repr(text)) > 50\n                                    else repr(text)\n                                )\n                                errors.append(\n                                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                    f\"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}\"\n                                )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} whitespace preservation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All whitespace is properly preserved\")\n            return True\n\n    def validate_deletions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                for t_elem in root.xpath(\".//w:del//w:t\", namespaces=namespaces):\n                    if t_elem.text:\n                        text_preview = (\n                            repr(t_elem.text)[:50] + \"...\"\n                            if len(repr(t_elem.text)) > 50\n                            else repr(t_elem.text)\n                        )\n                        errors.append(\n                            f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}\"\n                        )\n\n                for instr_elem in root.xpath(\n                    \".//w:del//w:instrText\", namespaces=namespaces\n                ):\n                    text_preview = (\n                        repr(instr_elem.text or \"\")[:50] + \"...\"\n                        if len(repr(instr_elem.text or \"\")) > 50\n                        else repr(instr_elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} deletion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:t elements found within w:del elements\")\n            return True\n\n    def count_paragraphs_in_unpacked(self):\n        count = 0\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n            except Exception as e:\n                print(f\"Error counting paragraphs in unpacked document: {e}\")\n\n        return count\n\n    def count_paragraphs_in_original(self):\n        original = self.original_file\n        if original is None:\n            return 0\n\n        count = 0\n\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                with zipfile.ZipFile(original, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_dir)\n\n                doc_xml_path = temp_dir + \"/word/document.xml\"\n                root = lxml.etree.parse(doc_xml_path).getroot()\n\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n\n        except Exception as e:\n            print(f\"Error counting paragraphs in original document: {e}\")\n\n        return count\n\n    def validate_insertions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                invalid_elements = root.xpath(\n                    \".//w:ins//w:delText[not(ancestor::w:del)]\", namespaces=namespaces\n                )\n\n                for elem in invalid_elements:\n                    text_preview = (\n                        repr(elem.text or \"\")[:50] + \"...\"\n                        if len(repr(elem.text or \"\")) > 50\n                        else repr(elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} insertion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:delText elements within w:ins elements\")\n            return True\n\n    def compare_paragraph_counts(self):\n        original_count = self.count_paragraphs_in_original()\n        new_count = self.count_paragraphs_in_unpacked()\n\n        diff = new_count - original_count\n        diff_str = f\"+{diff}\" if diff > 0 else str(diff)\n        print(f\"\\nParagraphs: {original_count} → {new_count} ({diff_str})\")\n\n    def _parse_id_value(self, val: str, base: int = 16) -> int:\n        return int(val, base)\n\n    def validate_id_constraints(self):\n        errors = []\n        para_id_attr = f\"{{{self.W14_NAMESPACE}}}paraId\"\n        durable_id_attr = f\"{{{self.W16CID_NAMESPACE}}}durableId\"\n\n        for xml_file in self.xml_files:\n            try:\n                for elem in lxml.etree.parse(str(xml_file)).iter():\n                    if val := elem.get(para_id_attr):\n                        if self._parse_id_value(val, base=16) >= 0x80000000:\n                            errors.append(\n                                f\"  {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000\"\n                            )\n\n                    if val := elem.get(durable_id_attr):\n                        if xml_file.name == \"numbering.xml\":\n                            try:\n                                if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:\n                                    errors.append(\n                                        f\"  {xml_file.name}:{elem.sourceline}: \"\n                                        f\"durableId={val} >= 0x7FFFFFFF\"\n                                    )\n                            except ValueError:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} must be decimal in numbering.xml\"\n                                )\n                        else:\n                            if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} >= 0x7FFFFFFF\"\n                                )\n            except Exception:\n                pass\n\n        if errors:\n            print(f\"FAILED - {len(errors)} ID constraint violations:\")\n            for e in errors:\n                print(e)\n        elif self.verbose:\n            print(\"PASSED - All paraId/durableId values within constraints\")\n        return not errors\n\n    def validate_comment_markers(self):\n        errors = []\n\n        document_xml = None\n        comments_xml = None\n        for xml_file in self.xml_files:\n            if xml_file.name == \"document.xml\" and \"word\" in str(xml_file):\n                document_xml = xml_file\n            elif xml_file.name == \"comments.xml\":\n                comments_xml = xml_file\n\n        if not document_xml:\n            if self.verbose:\n                print(\"PASSED - No document.xml found (skipping comment validation)\")\n            return True\n\n        try:\n            doc_root = lxml.etree.parse(str(document_xml)).getroot()\n            namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n            range_starts = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeStart\", namespaces=namespaces\n                )\n            }\n            range_ends = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeEnd\", namespaces=namespaces\n                )\n            }\n            references = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentReference\", namespaces=namespaces\n                )\n            }\n\n            orphaned_ends = range_ends - range_starts\n            for comment_id in sorted(\n                orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeEnd id=\"{comment_id}\" has no matching commentRangeStart'\n                )\n\n            orphaned_starts = range_starts - range_ends\n            for comment_id in sorted(\n                orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeStart id=\"{comment_id}\" has no matching commentRangeEnd'\n                )\n\n            comment_ids = set()\n            if comments_xml and comments_xml.exists():\n                comments_root = lxml.etree.parse(str(comments_xml)).getroot()\n                comment_ids = {\n                    elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                    for elem in comments_root.xpath(\n                        \".//w:comment\", namespaces=namespaces\n                    )\n                }\n\n                marker_ids = range_starts | range_ends | references\n                invalid_refs = marker_ids - comment_ids\n                for comment_id in sorted(\n                    invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0\n                ):\n                    if comment_id:  \n                        errors.append(\n                            f'  document.xml: marker id=\"{comment_id}\" references non-existent comment'\n                        )\n\n        except (lxml.etree.XMLSyntaxError, Exception) as e:\n            errors.append(f\"  Error parsing XML: {e}\")\n\n        if errors:\n            print(f\"FAILED - {len(errors)} comment marker violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All comment markers properly paired\")\n            return True\n\n    def repair(self) -> int:\n        repairs = super().repair()\n        repairs += self.repair_durableId()\n        return repairs\n\n    def repair_durableId(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if not elem.hasAttribute(\"w16cid:durableId\"):\n                        continue\n\n                    durable_id = elem.getAttribute(\"w16cid:durableId\")\n                    needs_repair = False\n\n                    if xml_file.name == \"numbering.xml\":\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n                    else:\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n\n                    if needs_repair:\n                        value = random.randint(1, 0x7FFFFFFE)\n                        if xml_file.name == \"numbering.xml\":\n                            new_id = str(value)  \n                        else:\n                            new_id = f\"{value:08X}\"  \n\n                        elem.setAttribute(\"w16cid:durableId\", new_id)\n                        print(\n                            f\"  Repaired: {xml_file.name}: durableId {durable_id} → {new_id}\"\n                        )\n                        repairs += 1\n                        modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/pptx/scripts/office/validators/pptx.py",
    "content": "\"\"\"\nValidator for PowerPoint presentation XML files against XSD schemas.\n\"\"\"\n\nimport re\n\nfrom .base import BaseSchemaValidator\n\n\nclass PPTXSchemaValidator(BaseSchemaValidator):\n\n    PRESENTATIONML_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\"\n    )\n\n    ELEMENT_RELATIONSHIP_TYPES = {\n        \"sldid\": \"slide\",\n        \"sldmasterid\": \"slidemaster\",\n        \"notesmasterid\": \"notesmaster\",\n        \"sldlayoutid\": \"slidelayout\",\n        \"themeid\": \"theme\",\n        \"tablestyleid\": \"tablestyles\",\n    }\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_uuid_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_slide_layout_ids():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_notes_slide_references():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_no_duplicate_slide_layouts():\n            all_valid = False\n\n        return all_valid\n\n    def validate_uuid_ids(self):\n        import lxml.etree\n\n        errors = []\n        uuid_pattern = re.compile(\n            r\"^[\\{\\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\\}\\)]?$\"\n        )\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter():\n                    for attr, value in elem.attrib.items():\n                        attr_name = attr.split(\"}\")[-1].lower()\n                        if attr_name == \"id\" or attr_name.endswith(\"id\"):\n                            if self._looks_like_uuid(value):\n                                if not uuid_pattern.match(value):\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters\"\n                                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} UUID ID validation errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All UUID-like IDs contain valid hex values\")\n            return True\n\n    def _looks_like_uuid(self, value):\n        clean_value = value.strip(\"{}()\").replace(\"-\", \"\")\n        return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)\n\n    def validate_slide_layout_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        slide_masters = list(self.unpacked_dir.glob(\"ppt/slideMasters/*.xml\"))\n\n        if not slide_masters:\n            if self.verbose:\n                print(\"PASSED - No slide masters found\")\n            return True\n\n        for slide_master in slide_masters:\n            try:\n                root = lxml.etree.parse(str(slide_master)).getroot()\n\n                rels_file = slide_master.parent / \"_rels\" / f\"{slide_master.name}.rels\"\n\n                if not rels_file.exists():\n                    errors.append(\n                        f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                        f\"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}\"\n                    )\n                    continue\n\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                valid_layout_rids = set()\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"slideLayout\" in rel_type:\n                        valid_layout_rids.add(rel.get(\"Id\"))\n\n                for sld_layout_id in root.findall(\n                    f\".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId\"\n                ):\n                    r_id = sld_layout_id.get(\n                        f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\"\n                    )\n                    layout_id = sld_layout_id.get(\"id\")\n\n                    if r_id and r_id not in valid_layout_rids:\n                        errors.append(\n                            f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' \"\n                            f\"references r:id='{r_id}' which is not found in slide layout relationships\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {slide_master.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} slide layout ID validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"Remove invalid references or add missing slide layouts to the relationships file.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slide layout IDs reference valid slide layouts\")\n            return True\n\n    def validate_no_duplicate_slide_layouts(self):\n        import lxml.etree\n\n        errors = []\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                layout_rels = [\n                    rel\n                    for rel in root.findall(\n                        f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                    )\n                    if \"slideLayout\" in rel.get(\"Type\", \"\")\n                ]\n\n                if len(layout_rels) > 1:\n                    errors.append(\n                        f\"  {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references\"\n                    )\n\n            except Exception as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(\"FAILED - Found slides with duplicate slideLayout references:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slides have exactly one slideLayout reference\")\n            return True\n\n    def validate_notes_slide_references(self):\n        import lxml.etree\n\n        errors = []\n        notes_slide_references = {}  \n\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        if not slide_rels_files:\n            if self.verbose:\n                print(\"PASSED - No slide relationship files found\")\n            return True\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                for rel in root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"notesSlide\" in rel_type:\n                        target = rel.get(\"Target\", \"\")\n                        if target:\n                            normalized_target = target.replace(\"../\", \"\")\n\n                            slide_name = rels_file.stem.replace(\n                                \".xml\", \"\"\n                            )  \n\n                            if normalized_target not in notes_slide_references:\n                                notes_slide_references[normalized_target] = []\n                            notes_slide_references[normalized_target].append(\n                                (slide_name, rels_file)\n                            )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        for target, references in notes_slide_references.items():\n            if len(references) > 1:\n                slide_names = [ref[0] for ref in references]\n                errors.append(\n                    f\"  Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}\"\n                )\n                for slide_name, rels_file in references:\n                    errors.append(f\"    - {rels_file.relative_to(self.unpacked_dir)}\")\n\n        if errors:\n            print(\n                f\"FAILED - Found {len([e for e in errors if not e.startswith('    ')])} notes slide reference validation errors:\"\n            )\n            for error in errors:\n                print(error)\n            print(\"Each slide may optionally have its own slide file.\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All notes slide references are unique\")\n            return True\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/pptx/scripts/office/validators/redlining.py",
    "content": "\"\"\"\nValidator for tracked changes in Word documents.\n\"\"\"\n\nimport subprocess\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\n\nclass RedliningValidator:\n\n    def __init__(self, unpacked_dir, original_docx, verbose=False, author=\"Claude\"):\n        self.unpacked_dir = Path(unpacked_dir)\n        self.original_docx = Path(original_docx)\n        self.verbose = verbose\n        self.author = author\n        self.namespaces = {\n            \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n        }\n\n    def repair(self) -> int:\n        return 0\n\n    def validate(self):\n        modified_file = self.unpacked_dir / \"word\" / \"document.xml\"\n        if not modified_file.exists():\n            print(f\"FAILED - Modified document.xml not found at {modified_file}\")\n            return False\n\n        try:\n            import xml.etree.ElementTree as ET\n\n            tree = ET.parse(modified_file)\n            root = tree.getroot()\n\n            del_elements = root.findall(\".//w:del\", self.namespaces)\n            ins_elements = root.findall(\".//w:ins\", self.namespaces)\n\n            author_del_elements = [\n                elem\n                for elem in del_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n            author_ins_elements = [\n                elem\n                for elem in ins_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n\n            if not author_del_elements and not author_ins_elements:\n                if self.verbose:\n                    print(f\"PASSED - No tracked changes by {self.author} found.\")\n                return True\n\n        except Exception:\n            pass\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            try:\n                with zipfile.ZipFile(self.original_docx, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_path)\n            except Exception as e:\n                print(f\"FAILED - Error unpacking original docx: {e}\")\n                return False\n\n            original_file = temp_path / \"word\" / \"document.xml\"\n            if not original_file.exists():\n                print(\n                    f\"FAILED - Original document.xml not found in {self.original_docx}\"\n                )\n                return False\n\n            try:\n                import xml.etree.ElementTree as ET\n\n                modified_tree = ET.parse(modified_file)\n                modified_root = modified_tree.getroot()\n                original_tree = ET.parse(original_file)\n                original_root = original_tree.getroot()\n            except ET.ParseError as e:\n                print(f\"FAILED - Error parsing XML files: {e}\")\n                return False\n\n            self._remove_author_tracked_changes(original_root)\n            self._remove_author_tracked_changes(modified_root)\n\n            modified_text = self._extract_text_content(modified_root)\n            original_text = self._extract_text_content(original_root)\n\n            if modified_text != original_text:\n                error_message = self._generate_detailed_diff(\n                    original_text, modified_text\n                )\n                print(error_message)\n                return False\n\n            if self.verbose:\n                print(f\"PASSED - All changes by {self.author} are properly tracked\")\n            return True\n\n    def _generate_detailed_diff(self, original_text, modified_text):\n        error_parts = [\n            f\"FAILED - Document text doesn't match after removing {self.author}'s tracked changes\",\n            \"\",\n            \"Likely causes:\",\n            \"  1. Modified text inside another author's <w:ins> or <w:del> tags\",\n            \"  2. Made edits without proper tracked changes\",\n            \"  3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion\",\n            \"\",\n            \"For pre-redlined documents, use correct patterns:\",\n            \"  - To reject another's INSERTION: Nest <w:del> inside their <w:ins>\",\n            \"  - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>\",\n            \"\",\n        ]\n\n        git_diff = self._get_git_word_diff(original_text, modified_text)\n        if git_diff:\n            error_parts.extend([\"Differences:\", \"============\", git_diff])\n        else:\n            error_parts.append(\"Unable to generate word diff (git not available)\")\n\n        return \"\\n\".join(error_parts)\n\n    def _get_git_word_diff(self, original_text, modified_text):\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                temp_path = Path(temp_dir)\n\n                original_file = temp_path / \"original.txt\"\n                modified_file = temp_path / \"modified.txt\"\n\n                original_file.write_text(original_text, encoding=\"utf-8\")\n                modified_file.write_text(modified_text, encoding=\"utf-8\")\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"--word-diff-regex=.\",  \n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n\n                    if content_lines:\n                        return \"\\n\".join(content_lines)\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n                    return \"\\n\".join(content_lines)\n\n        except (subprocess.CalledProcessError, FileNotFoundError, Exception):\n            pass\n\n        return None\n\n    def _remove_author_tracked_changes(self, root):\n        ins_tag = f\"{{{self.namespaces['w']}}}ins\"\n        del_tag = f\"{{{self.namespaces['w']}}}del\"\n        author_attr = f\"{{{self.namespaces['w']}}}author\"\n\n        for parent in root.iter():\n            to_remove = []\n            for child in parent:\n                if child.tag == ins_tag and child.get(author_attr) == self.author:\n                    to_remove.append(child)\n            for elem in to_remove:\n                parent.remove(elem)\n\n        deltext_tag = f\"{{{self.namespaces['w']}}}delText\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        for parent in root.iter():\n            to_process = []\n            for child in parent:\n                if child.tag == del_tag and child.get(author_attr) == self.author:\n                    to_process.append((child, list(parent).index(child)))\n\n            for del_elem, del_index in reversed(to_process):\n                for elem in del_elem.iter():\n                    if elem.tag == deltext_tag:\n                        elem.tag = t_tag\n\n                for child in reversed(list(del_elem)):\n                    parent.insert(del_index, child)\n                parent.remove(del_elem)\n\n    def _extract_text_content(self, root):\n        p_tag = f\"{{{self.namespaces['w']}}}p\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        paragraphs = []\n        for p_elem in root.findall(f\".//{p_tag}\"):\n            text_parts = []\n            for t_elem in p_elem.findall(f\".//{t_tag}\"):\n                if t_elem.text:\n                    text_parts.append(t_elem.text)\n            paragraph_text = \"\".join(text_parts)\n            if paragraph_text:\n                paragraphs.append(paragraph_text)\n\n        return \"\\n\".join(paragraphs)\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/pptx/scripts/thumbnail.py",
    "content": "\"\"\"Create thumbnail grids from PowerPoint presentation slides.\n\nCreates a grid layout of slide thumbnails for quick visual analysis.\nLabels each thumbnail with its XML filename (e.g., slide1.xml).\nHidden slides are shown with a placeholder pattern.\n\nUsage:\n    python thumbnail.py input.pptx [output_prefix] [--cols N]\n\nExamples:\n    python thumbnail.py presentation.pptx\n    # Creates: thumbnails.jpg\n\n    python thumbnail.py template.pptx grid --cols 4\n    # Creates: grid.jpg (or grid-1.jpg, grid-2.jpg for large decks)\n\"\"\"\n\nimport argparse\nimport subprocess\nimport sys\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\nfrom office.soffice import get_soffice_env\nfrom PIL import Image, ImageDraw, ImageFont\n\nTHUMBNAIL_WIDTH = 300\nCONVERSION_DPI = 100\nMAX_COLS = 6\nDEFAULT_COLS = 3\nJPEG_QUALITY = 95\nGRID_PADDING = 20\nBORDER_WIDTH = 2\nFONT_SIZE_RATIO = 0.10\nLABEL_PADDING_RATIO = 0.4\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description=\"Create thumbnail grids from PowerPoint slides.\"\n    )\n    parser.add_argument(\"input\", help=\"Input PowerPoint file (.pptx)\")\n    parser.add_argument(\n        \"output_prefix\",\n        nargs=\"?\",\n        default=\"thumbnails\",\n        help=\"Output prefix for image files (default: thumbnails)\",\n    )\n    parser.add_argument(\n        \"--cols\",\n        type=int,\n        default=DEFAULT_COLS,\n        help=f\"Number of columns (default: {DEFAULT_COLS}, max: {MAX_COLS})\",\n    )\n\n    args = parser.parse_args()\n\n    cols = min(args.cols, MAX_COLS)\n    if args.cols > MAX_COLS:\n        print(f\"Warning: Columns limited to {MAX_COLS}\")\n\n    input_path = Path(args.input)\n    if not input_path.exists() or input_path.suffix.lower() != \".pptx\":\n        print(f\"Error: Invalid PowerPoint file: {args.input}\", file=sys.stderr)\n        sys.exit(1)\n\n    output_path = Path(f\"{args.output_prefix}.jpg\")\n\n    try:\n        slide_info = get_slide_info(input_path)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n            visible_images = convert_to_images(input_path, temp_path)\n\n            if not visible_images and not any(s[\"hidden\"] for s in slide_info):\n                print(\"Error: No slides found\", file=sys.stderr)\n                sys.exit(1)\n\n            slides = build_slide_list(slide_info, visible_images, temp_path)\n\n            grid_files = create_grids(slides, cols, THUMBNAIL_WIDTH, output_path)\n\n            print(f\"Created {len(grid_files)} grid(s):\")\n            for grid_file in grid_files:\n                print(f\"  {grid_file}\")\n\n    except Exception as e:\n        print(f\"Error: {e}\", file=sys.stderr)\n        sys.exit(1)\n\n\ndef get_slide_info(pptx_path: Path) -> list[dict]:\n    with zipfile.ZipFile(pptx_path, \"r\") as zf:\n        rels_content = zf.read(\"ppt/_rels/presentation.xml.rels\").decode(\"utf-8\")\n        rels_dom = defusedxml.minidom.parseString(rels_content)\n\n        rid_to_slide = {}\n        for rel in rels_dom.getElementsByTagName(\"Relationship\"):\n            rid = rel.getAttribute(\"Id\")\n            target = rel.getAttribute(\"Target\")\n            rel_type = rel.getAttribute(\"Type\")\n            if \"slide\" in rel_type and target.startswith(\"slides/\"):\n                rid_to_slide[rid] = target.replace(\"slides/\", \"\")\n\n        pres_content = zf.read(\"ppt/presentation.xml\").decode(\"utf-8\")\n        pres_dom = defusedxml.minidom.parseString(pres_content)\n\n        slides = []\n        for sld_id in pres_dom.getElementsByTagName(\"p:sldId\"):\n            rid = sld_id.getAttribute(\"r:id\")\n            if rid in rid_to_slide:\n                hidden = sld_id.getAttribute(\"show\") == \"0\"\n                slides.append({\"name\": rid_to_slide[rid], \"hidden\": hidden})\n\n        return slides\n\n\ndef build_slide_list(\n    slide_info: list[dict],\n    visible_images: list[Path],\n    temp_dir: Path,\n) -> list[tuple[Path, str]]:\n    if visible_images:\n        with Image.open(visible_images[0]) as img:\n            placeholder_size = img.size\n    else:\n        placeholder_size = (1920, 1080)\n\n    slides = []\n    visible_idx = 0\n\n    for info in slide_info:\n        if info[\"hidden\"]:\n            placeholder_path = temp_dir / f\"hidden-{info['name']}.jpg\"\n            placeholder_img = create_hidden_placeholder(placeholder_size)\n            placeholder_img.save(placeholder_path, \"JPEG\")\n            slides.append((placeholder_path, f\"{info['name']} (hidden)\"))\n        else:\n            if visible_idx < len(visible_images):\n                slides.append((visible_images[visible_idx], info[\"name\"]))\n                visible_idx += 1\n\n    return slides\n\n\ndef create_hidden_placeholder(size: tuple[int, int]) -> Image.Image:\n    img = Image.new(\"RGB\", size, color=\"#F0F0F0\")\n    draw = ImageDraw.Draw(img)\n    line_width = max(5, min(size) // 100)\n    draw.line([(0, 0), size], fill=\"#CCCCCC\", width=line_width)\n    draw.line([(size[0], 0), (0, size[1])], fill=\"#CCCCCC\", width=line_width)\n    return img\n\n\ndef convert_to_images(pptx_path: Path, temp_dir: Path) -> list[Path]:\n    pdf_path = temp_dir / f\"{pptx_path.stem}.pdf\"\n\n    result = subprocess.run(\n        [\n            \"soffice\",\n            \"--headless\",\n            \"--convert-to\",\n            \"pdf\",\n            \"--outdir\",\n            str(temp_dir),\n            str(pptx_path),\n        ],\n        capture_output=True,\n        text=True,\n        env=get_soffice_env(),\n    )\n    if result.returncode != 0 or not pdf_path.exists():\n        raise RuntimeError(\"PDF conversion failed\")\n\n    result = subprocess.run(\n        [\n            \"pdftoppm\",\n            \"-jpeg\",\n            \"-r\",\n            str(CONVERSION_DPI),\n            str(pdf_path),\n            str(temp_dir / \"slide\"),\n        ],\n        capture_output=True,\n        text=True,\n    )\n    if result.returncode != 0:\n        raise RuntimeError(\"Image conversion failed\")\n\n    return sorted(temp_dir.glob(\"slide-*.jpg\"))\n\n\ndef create_grids(\n    slides: list[tuple[Path, str]],\n    cols: int,\n    width: int,\n    output_path: Path,\n) -> list[str]:\n    max_per_grid = cols * (cols + 1)\n    grid_files = []\n\n    for chunk_idx, start_idx in enumerate(range(0, len(slides), max_per_grid)):\n        end_idx = min(start_idx + max_per_grid, len(slides))\n        chunk_slides = slides[start_idx:end_idx]\n\n        grid = create_grid(chunk_slides, cols, width)\n\n        if len(slides) <= max_per_grid:\n            grid_filename = output_path\n        else:\n            stem = output_path.stem\n            suffix = output_path.suffix\n            grid_filename = output_path.parent / f\"{stem}-{chunk_idx + 1}{suffix}\"\n\n        grid_filename.parent.mkdir(parents=True, exist_ok=True)\n        grid.save(str(grid_filename), quality=JPEG_QUALITY)\n        grid_files.append(str(grid_filename))\n\n    return grid_files\n\n\ndef create_grid(\n    slides: list[tuple[Path, str]],\n    cols: int,\n    width: int,\n) -> Image.Image:\n    font_size = int(width * FONT_SIZE_RATIO)\n    label_padding = int(font_size * LABEL_PADDING_RATIO)\n\n    with Image.open(slides[0][0]) as img:\n        aspect = img.height / img.width\n    height = int(width * aspect)\n\n    rows = (len(slides) + cols - 1) // cols\n    grid_w = cols * width + (cols + 1) * GRID_PADDING\n    grid_h = rows * (height + font_size + label_padding * 2) + (rows + 1) * GRID_PADDING\n\n    grid = Image.new(\"RGB\", (grid_w, grid_h), \"white\")\n    draw = ImageDraw.Draw(grid)\n\n    try:\n        font = ImageFont.load_default(size=font_size)\n    except Exception:\n        font = ImageFont.load_default()\n\n    for i, (img_path, slide_name) in enumerate(slides):\n        row, col = i // cols, i % cols\n        x = col * width + (col + 1) * GRID_PADDING\n        y_base = (\n            row * (height + font_size + label_padding * 2) + (row + 1) * GRID_PADDING\n        )\n\n        label = slide_name\n        bbox = draw.textbbox((0, 0), label, font=font)\n        text_w = bbox[2] - bbox[0]\n        draw.text(\n            (x + (width - text_w) // 2, y_base + label_padding),\n            label,\n            fill=\"black\",\n            font=font,\n        )\n\n        y_thumbnail = y_base + label_padding + font_size + label_padding\n\n        with Image.open(img_path) as img:\n            img.thumbnail((width, height), Image.Resampling.LANCZOS)\n            w, h = img.size\n            tx = x + (width - w) // 2\n            ty = y_thumbnail + (height - h) // 2\n            grid.paste(img, (tx, ty))\n\n            if BORDER_WIDTH > 0:\n                draw.rectangle(\n                    [\n                        (tx - BORDER_WIDTH, ty - BORDER_WIDTH),\n                        (tx + w + BORDER_WIDTH - 1, ty + h + BORDER_WIDTH - 1),\n                    ],\n                    outline=\"gray\",\n                    width=BORDER_WIDTH,\n                )\n\n    return grid\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/slack-gif-creator/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/slack-gif-creator/SKILL.md",
    "content": "---\nname: slack-gif-creator\ndescription: Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like \"make me a GIF of X doing Y for Slack.\"\nlicense: Complete terms in LICENSE.txt\n---\n\n# Slack GIF Creator\n\nA toolkit providing utilities and knowledge for creating animated GIFs optimized for Slack.\n\n## Slack Requirements\n\n**Dimensions:**\n- Emoji GIFs: 128x128 (recommended)\n- Message GIFs: 480x480\n\n**Parameters:**\n- FPS: 10-30 (lower is smaller file size)\n- Colors: 48-128 (fewer = smaller file size)\n- Duration: Keep under 3 seconds for emoji GIFs\n\n## Core Workflow\n\n```python\nfrom core.gif_builder import GIFBuilder\nfrom PIL import Image, ImageDraw\n\n# 1. Create builder\nbuilder = GIFBuilder(width=128, height=128, fps=10)\n\n# 2. Generate frames\nfor i in range(12):\n    frame = Image.new('RGB', (128, 128), (240, 248, 255))\n    draw = ImageDraw.Draw(frame)\n\n    # Draw your animation using PIL primitives\n    # (circles, polygons, lines, etc.)\n\n    builder.add_frame(frame)\n\n# 3. Save with optimization\nbuilder.save('output.gif', num_colors=48, optimize_for_emoji=True)\n```\n\n## Drawing Graphics\n\n### Working with User-Uploaded Images\nIf a user uploads an image, consider whether they want to:\n- **Use it directly** (e.g., \"animate this\", \"split this into frames\")\n- **Use it as inspiration** (e.g., \"make something like this\")\n\nLoad and work with images using PIL:\n```python\nfrom PIL import Image\n\nuploaded = Image.open('file.png')\n# Use directly, or just as reference for colors/style\n```\n\n### Drawing from Scratch\nWhen drawing graphics from scratch, use PIL ImageDraw primitives:\n\n```python\nfrom PIL import ImageDraw\n\ndraw = ImageDraw.Draw(frame)\n\n# Circles/ovals\ndraw.ellipse([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)\n\n# Stars, triangles, any polygon\npoints = [(x1, y1), (x2, y2), (x3, y3), ...]\ndraw.polygon(points, fill=(r, g, b), outline=(r, g, b), width=3)\n\n# Lines\ndraw.line([(x1, y1), (x2, y2)], fill=(r, g, b), width=5)\n\n# Rectangles\ndraw.rectangle([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)\n```\n\n**Don't use:** Emoji fonts (unreliable across platforms) or assume pre-packaged graphics exist in this skill.\n\n### Making Graphics Look Good\n\nGraphics should look polished and creative, not basic. Here's how:\n\n**Use thicker lines** - Always set `width=2` or higher for outlines and lines. Thin lines (width=1) look choppy and amateurish.\n\n**Add visual depth**:\n- Use gradients for backgrounds (`create_gradient_background`)\n- Layer multiple shapes for complexity (e.g., a star with a smaller star inside)\n\n**Make shapes more interesting**:\n- Don't just draw a plain circle - add highlights, rings, or patterns\n- Stars can have glows (draw larger, semi-transparent versions behind)\n- Combine multiple shapes (stars + sparkles, circles + rings)\n\n**Pay attention to colors**:\n- Use vibrant, complementary colors\n- Add contrast (dark outlines on light shapes, light outlines on dark shapes)\n- Consider the overall composition\n\n**For complex shapes** (hearts, snowflakes, etc.):\n- Use combinations of polygons and ellipses\n- Calculate points carefully for symmetry\n- Add details (a heart can have a highlight curve, snowflakes have intricate branches)\n\nBe creative and detailed! A good Slack GIF should look polished, not like placeholder graphics.\n\n## Available Utilities\n\n### GIFBuilder (`core.gif_builder`)\nAssembles frames and optimizes for Slack:\n```python\nbuilder = GIFBuilder(width=128, height=128, fps=10)\nbuilder.add_frame(frame)  # Add PIL Image\nbuilder.add_frames(frames)  # Add list of frames\nbuilder.save('out.gif', num_colors=48, optimize_for_emoji=True, remove_duplicates=True)\n```\n\n### Validators (`core.validators`)\nCheck if GIF meets Slack requirements:\n```python\nfrom core.validators import validate_gif, is_slack_ready\n\n# Detailed validation\npasses, info = validate_gif('my.gif', is_emoji=True, verbose=True)\n\n# Quick check\nif is_slack_ready('my.gif'):\n    print(\"Ready!\")\n```\n\n### Easing Functions (`core.easing`)\nSmooth motion instead of linear:\n```python\nfrom core.easing import interpolate\n\n# Progress from 0.0 to 1.0\nt = i / (num_frames - 1)\n\n# Apply easing\ny = interpolate(start=0, end=400, t=t, easing='ease_out')\n\n# Available: linear, ease_in, ease_out, ease_in_out,\n#           bounce_out, elastic_out, back_out\n```\n\n### Frame Helpers (`core.frame_composer`)\nConvenience functions for common needs:\n```python\nfrom core.frame_composer import (\n    create_blank_frame,         # Solid color background\n    create_gradient_background,  # Vertical gradient\n    draw_circle,                # Helper for circles\n    draw_text,                  # Simple text rendering\n    draw_star                   # 5-pointed star\n)\n```\n\n## Animation Concepts\n\n### Shake/Vibrate\nOffset object position with oscillation:\n- Use `math.sin()` or `math.cos()` with frame index\n- Add small random variations for natural feel\n- Apply to x and/or y position\n\n### Pulse/Heartbeat\nScale object size rhythmically:\n- Use `math.sin(t * frequency * 2 * math.pi)` for smooth pulse\n- For heartbeat: two quick pulses then pause (adjust sine wave)\n- Scale between 0.8 and 1.2 of base size\n\n### Bounce\nObject falls and bounces:\n- Use `interpolate()` with `easing='bounce_out'` for landing\n- Use `easing='ease_in'` for falling (accelerating)\n- Apply gravity by increasing y velocity each frame\n\n### Spin/Rotate\nRotate object around center:\n- PIL: `image.rotate(angle, resample=Image.BICUBIC)`\n- For wobble: use sine wave for angle instead of linear\n\n### Fade In/Out\nGradually appear or disappear:\n- Create RGBA image, adjust alpha channel\n- Or use `Image.blend(image1, image2, alpha)`\n- Fade in: alpha from 0 to 1\n- Fade out: alpha from 1 to 0\n\n### Slide\nMove object from off-screen to position:\n- Start position: outside frame bounds\n- End position: target location\n- Use `interpolate()` with `easing='ease_out'` for smooth stop\n- For overshoot: use `easing='back_out'`\n\n### Zoom\nScale and position for zoom effect:\n- Zoom in: scale from 0.1 to 2.0, crop center\n- Zoom out: scale from 2.0 to 1.0\n- Can add motion blur for drama (PIL filter)\n\n### Explode/Particle Burst\nCreate particles radiating outward:\n- Generate particles with random angles and velocities\n- Update each particle: `x += vx`, `y += vy`\n- Add gravity: `vy += gravity_constant`\n- Fade out particles over time (reduce alpha)\n\n## Optimization Strategies\n\nOnly when asked to make the file size smaller, implement a few of the following methods:\n\n1. **Fewer frames** - Lower FPS (10 instead of 20) or shorter duration\n2. **Fewer colors** - `num_colors=48` instead of 128\n3. **Smaller dimensions** - 128x128 instead of 480x480\n4. **Remove duplicates** - `remove_duplicates=True` in save()\n5. **Emoji mode** - `optimize_for_emoji=True` auto-optimizes\n\n```python\n# Maximum optimization for emoji\nbuilder.save(\n    'emoji.gif',\n    num_colors=48,\n    optimize_for_emoji=True,\n    remove_duplicates=True\n)\n```\n\n## Philosophy\n\nThis skill provides:\n- **Knowledge**: Slack's requirements and animation concepts\n- **Utilities**: GIFBuilder, validators, easing functions\n- **Flexibility**: Create the animation logic using PIL primitives\n\nIt does NOT provide:\n- Rigid animation templates or pre-made functions\n- Emoji font rendering (unreliable across platforms)\n- A library of pre-packaged graphics built into the skill\n\n**Note on user uploads**: This skill doesn't include pre-built graphics, but if a user uploads an image, use PIL to load and work with it - interpret based on their request whether they want it used directly or just as inspiration.\n\nBe creative! Combine concepts (bouncing + rotating, pulsing + sliding, etc.) and use PIL's full capabilities.\n\n## Dependencies\n\n```bash\npip install pillow imageio numpy\n```\n"
  },
  {
    "path": "skills/slack-gif-creator/core/easing.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nEasing Functions - Timing functions for smooth animations.\n\nProvides various easing functions for natural motion and timing.\nAll functions take a value t (0.0 to 1.0) and return eased value (0.0 to 1.0).\n\"\"\"\n\nimport math\n\n\ndef linear(t: float) -> float:\n    \"\"\"Linear interpolation (no easing).\"\"\"\n    return t\n\n\ndef ease_in_quad(t: float) -> float:\n    \"\"\"Quadratic ease-in (slow start, accelerating).\"\"\"\n    return t * t\n\n\ndef ease_out_quad(t: float) -> float:\n    \"\"\"Quadratic ease-out (fast start, decelerating).\"\"\"\n    return t * (2 - t)\n\n\ndef ease_in_out_quad(t: float) -> float:\n    \"\"\"Quadratic ease-in-out (slow start and end).\"\"\"\n    if t < 0.5:\n        return 2 * t * t\n    return -1 + (4 - 2 * t) * t\n\n\ndef ease_in_cubic(t: float) -> float:\n    \"\"\"Cubic ease-in (slow start).\"\"\"\n    return t * t * t\n\n\ndef ease_out_cubic(t: float) -> float:\n    \"\"\"Cubic ease-out (fast start).\"\"\"\n    return (t - 1) * (t - 1) * (t - 1) + 1\n\n\ndef ease_in_out_cubic(t: float) -> float:\n    \"\"\"Cubic ease-in-out.\"\"\"\n    if t < 0.5:\n        return 4 * t * t * t\n    return (t - 1) * (2 * t - 2) * (2 * t - 2) + 1\n\n\ndef ease_in_bounce(t: float) -> float:\n    \"\"\"Bounce ease-in (bouncy start).\"\"\"\n    return 1 - ease_out_bounce(1 - t)\n\n\ndef ease_out_bounce(t: float) -> float:\n    \"\"\"Bounce ease-out (bouncy end).\"\"\"\n    if t < 1 / 2.75:\n        return 7.5625 * t * t\n    elif t < 2 / 2.75:\n        t -= 1.5 / 2.75\n        return 7.5625 * t * t + 0.75\n    elif t < 2.5 / 2.75:\n        t -= 2.25 / 2.75\n        return 7.5625 * t * t + 0.9375\n    else:\n        t -= 2.625 / 2.75\n        return 7.5625 * t * t + 0.984375\n\n\ndef ease_in_out_bounce(t: float) -> float:\n    \"\"\"Bounce ease-in-out.\"\"\"\n    if t < 0.5:\n        return ease_in_bounce(t * 2) * 0.5\n    return ease_out_bounce(t * 2 - 1) * 0.5 + 0.5\n\n\ndef ease_in_elastic(t: float) -> float:\n    \"\"\"Elastic ease-in (spring effect).\"\"\"\n    if t == 0 or t == 1:\n        return t\n    return -math.pow(2, 10 * (t - 1)) * math.sin((t - 1.1) * 5 * math.pi)\n\n\ndef ease_out_elastic(t: float) -> float:\n    \"\"\"Elastic ease-out (spring effect).\"\"\"\n    if t == 0 or t == 1:\n        return t\n    return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) + 1\n\n\ndef ease_in_out_elastic(t: float) -> float:\n    \"\"\"Elastic ease-in-out.\"\"\"\n    if t == 0 or t == 1:\n        return t\n    t = t * 2 - 1\n    if t < 0:\n        return -0.5 * math.pow(2, 10 * t) * math.sin((t - 0.1) * 5 * math.pi)\n    return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) * 0.5 + 1\n\n\n# Convenience mapping\nEASING_FUNCTIONS = {\n    \"linear\": linear,\n    \"ease_in\": ease_in_quad,\n    \"ease_out\": ease_out_quad,\n    \"ease_in_out\": ease_in_out_quad,\n    \"bounce_in\": ease_in_bounce,\n    \"bounce_out\": ease_out_bounce,\n    \"bounce\": ease_in_out_bounce,\n    \"elastic_in\": ease_in_elastic,\n    \"elastic_out\": ease_out_elastic,\n    \"elastic\": ease_in_out_elastic,\n}\n\n\ndef get_easing(name: str = \"linear\"):\n    \"\"\"Get easing function by name.\"\"\"\n    return EASING_FUNCTIONS.get(name, linear)\n\n\ndef interpolate(start: float, end: float, t: float, easing: str = \"linear\") -> float:\n    \"\"\"\n    Interpolate between two values with easing.\n\n    Args:\n        start: Start value\n        end: End value\n        t: Progress from 0.0 to 1.0\n        easing: Name of easing function\n\n    Returns:\n        Interpolated value\n    \"\"\"\n    ease_func = get_easing(easing)\n    eased_t = ease_func(t)\n    return start + (end - start) * eased_t\n\n\ndef ease_back_in(t: float) -> float:\n    \"\"\"Back ease-in (slight overshoot backward before forward motion).\"\"\"\n    c1 = 1.70158\n    c3 = c1 + 1\n    return c3 * t * t * t - c1 * t * t\n\n\ndef ease_back_out(t: float) -> float:\n    \"\"\"Back ease-out (overshoot forward then settle back).\"\"\"\n    c1 = 1.70158\n    c3 = c1 + 1\n    return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2)\n\n\ndef ease_back_in_out(t: float) -> float:\n    \"\"\"Back ease-in-out (overshoot at both ends).\"\"\"\n    c1 = 1.70158\n    c2 = c1 * 1.525\n    if t < 0.5:\n        return (pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2\n    return (pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2\n\n\ndef apply_squash_stretch(\n    base_scale: tuple[float, float], intensity: float, direction: str = \"vertical\"\n) -> tuple[float, float]:\n    \"\"\"\n    Calculate squash and stretch scales for more dynamic animation.\n\n    Args:\n        base_scale: (width_scale, height_scale) base scales\n        intensity: Squash/stretch intensity (0.0-1.0)\n        direction: 'vertical', 'horizontal', or 'both'\n\n    Returns:\n        (width_scale, height_scale) with squash/stretch applied\n    \"\"\"\n    width_scale, height_scale = base_scale\n\n    if direction == \"vertical\":\n        # Compress vertically, expand horizontally (preserve volume)\n        height_scale *= 1 - intensity * 0.5\n        width_scale *= 1 + intensity * 0.5\n    elif direction == \"horizontal\":\n        # Compress horizontally, expand vertically\n        width_scale *= 1 - intensity * 0.5\n        height_scale *= 1 + intensity * 0.5\n    elif direction == \"both\":\n        # General squash (both dimensions)\n        width_scale *= 1 - intensity * 0.3\n        height_scale *= 1 - intensity * 0.3\n\n    return (width_scale, height_scale)\n\n\ndef calculate_arc_motion(\n    start: tuple[float, float], end: tuple[float, float], height: float, t: float\n) -> tuple[float, float]:\n    \"\"\"\n    Calculate position along a parabolic arc (natural motion path).\n\n    Args:\n        start: (x, y) starting position\n        end: (x, y) ending position\n        height: Arc height at midpoint (positive = upward)\n        t: Progress (0.0-1.0)\n\n    Returns:\n        (x, y) position along arc\n    \"\"\"\n    x1, y1 = start\n    x2, y2 = end\n\n    # Linear interpolation for x\n    x = x1 + (x2 - x1) * t\n\n    # Parabolic interpolation for y\n    # y = start + progress * (end - start) + arc_offset\n    # Arc offset peaks at t=0.5\n    arc_offset = 4 * height * t * (1 - t)\n    y = y1 + (y2 - y1) * t - arc_offset\n\n    return (x, y)\n\n\n# Add new easing functions to the convenience mapping\nEASING_FUNCTIONS.update(\n    {\n        \"back_in\": ease_back_in,\n        \"back_out\": ease_back_out,\n        \"back_in_out\": ease_back_in_out,\n        \"anticipate\": ease_back_in,  # Alias\n        \"overshoot\": ease_back_out,  # Alias\n    }\n)\n"
  },
  {
    "path": "skills/slack-gif-creator/core/frame_composer.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nFrame Composer - Utilities for composing visual elements into frames.\n\nProvides functions for drawing shapes, text, emojis, and compositing elements\ntogether to create animation frames.\n\"\"\"\n\nfrom typing import Optional\n\nimport numpy as np\nfrom PIL import Image, ImageDraw, ImageFont\n\n\ndef create_blank_frame(\n    width: int, height: int, color: tuple[int, int, int] = (255, 255, 255)\n) -> Image.Image:\n    \"\"\"\n    Create a blank frame with solid color background.\n\n    Args:\n        width: Frame width\n        height: Frame height\n        color: RGB color tuple (default: white)\n\n    Returns:\n        PIL Image\n    \"\"\"\n    return Image.new(\"RGB\", (width, height), color)\n\n\ndef draw_circle(\n    frame: Image.Image,\n    center: tuple[int, int],\n    radius: int,\n    fill_color: Optional[tuple[int, int, int]] = None,\n    outline_color: Optional[tuple[int, int, int]] = None,\n    outline_width: int = 1,\n) -> Image.Image:\n    \"\"\"\n    Draw a circle on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        center: (x, y) center position\n        radius: Circle radius\n        fill_color: RGB fill color (None for no fill)\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = center\n    bbox = [x - radius, y - radius, x + radius, y + radius]\n    draw.ellipse(bbox, fill=fill_color, outline=outline_color, width=outline_width)\n    return frame\n\n\ndef draw_text(\n    frame: Image.Image,\n    text: str,\n    position: tuple[int, int],\n    color: tuple[int, int, int] = (0, 0, 0),\n    centered: bool = False,\n) -> Image.Image:\n    \"\"\"\n    Draw text on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position (top-left unless centered=True)\n        color: RGB text color\n        centered: If True, center text at position\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n\n    # Uses Pillow's default font.\n    # If the font should be changed for the emoji, add additional logic here.\n    font = ImageFont.load_default()\n\n    if centered:\n        bbox = draw.textbbox((0, 0), text, font=font)\n        text_width = bbox[2] - bbox[0]\n        text_height = bbox[3] - bbox[1]\n        x = position[0] - text_width // 2\n        y = position[1] - text_height // 2\n        position = (x, y)\n\n    draw.text(position, text, fill=color, font=font)\n    return frame\n\n\ndef create_gradient_background(\n    width: int,\n    height: int,\n    top_color: tuple[int, int, int],\n    bottom_color: tuple[int, int, int],\n) -> Image.Image:\n    \"\"\"\n    Create a vertical gradient background.\n\n    Args:\n        width: Frame width\n        height: Frame height\n        top_color: RGB color at top\n        bottom_color: RGB color at bottom\n\n    Returns:\n        PIL Image with gradient\n    \"\"\"\n    frame = Image.new(\"RGB\", (width, height))\n    draw = ImageDraw.Draw(frame)\n\n    # Calculate color step for each row\n    r1, g1, b1 = top_color\n    r2, g2, b2 = bottom_color\n\n    for y in range(height):\n        # Interpolate color\n        ratio = y / height\n        r = int(r1 * (1 - ratio) + r2 * ratio)\n        g = int(g1 * (1 - ratio) + g2 * ratio)\n        b = int(b1 * (1 - ratio) + b2 * ratio)\n\n        # Draw horizontal line\n        draw.line([(0, y), (width, y)], fill=(r, g, b))\n\n    return frame\n\n\ndef draw_star(\n    frame: Image.Image,\n    center: tuple[int, int],\n    size: int,\n    fill_color: tuple[int, int, int],\n    outline_color: Optional[tuple[int, int, int]] = None,\n    outline_width: int = 1,\n) -> Image.Image:\n    \"\"\"\n    Draw a 5-pointed star.\n\n    Args:\n        frame: PIL Image to draw on\n        center: (x, y) center position\n        size: Star size (outer radius)\n        fill_color: RGB fill color\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width\n\n    Returns:\n        Modified frame\n    \"\"\"\n    import math\n\n    draw = ImageDraw.Draw(frame)\n    x, y = center\n\n    # Calculate star points\n    points = []\n    for i in range(10):\n        angle = (i * 36 - 90) * math.pi / 180  # 36 degrees per point, start at top\n        radius = size if i % 2 == 0 else size * 0.4  # Alternate between outer and inner\n        px = x + radius * math.cos(angle)\n        py = y + radius * math.sin(angle)\n        points.append((px, py))\n\n    # Draw star\n    draw.polygon(points, fill=fill_color, outline=outline_color, width=outline_width)\n\n    return frame\n"
  },
  {
    "path": "skills/slack-gif-creator/core/gif_builder.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nGIF Builder - Core module for assembling frames into GIFs optimized for Slack.\n\nThis module provides the main interface for creating GIFs from programmatically\ngenerated frames, with automatic optimization for Slack's requirements.\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Optional\n\nimport imageio.v3 as imageio\nimport numpy as np\nfrom PIL import Image\n\n\nclass GIFBuilder:\n    \"\"\"Builder for creating optimized GIFs from frames.\"\"\"\n\n    def __init__(self, width: int = 480, height: int = 480, fps: int = 15):\n        \"\"\"\n        Initialize GIF builder.\n\n        Args:\n            width: Frame width in pixels\n            height: Frame height in pixels\n            fps: Frames per second\n        \"\"\"\n        self.width = width\n        self.height = height\n        self.fps = fps\n        self.frames: list[np.ndarray] = []\n\n    def add_frame(self, frame: np.ndarray | Image.Image):\n        \"\"\"\n        Add a frame to the GIF.\n\n        Args:\n            frame: Frame as numpy array or PIL Image (will be converted to RGB)\n        \"\"\"\n        if isinstance(frame, Image.Image):\n            frame = np.array(frame.convert(\"RGB\"))\n\n        # Ensure frame is correct size\n        if frame.shape[:2] != (self.height, self.width):\n            pil_frame = Image.fromarray(frame)\n            pil_frame = pil_frame.resize(\n                (self.width, self.height), Image.Resampling.LANCZOS\n            )\n            frame = np.array(pil_frame)\n\n        self.frames.append(frame)\n\n    def add_frames(self, frames: list[np.ndarray | Image.Image]):\n        \"\"\"Add multiple frames at once.\"\"\"\n        for frame in frames:\n            self.add_frame(frame)\n\n    def optimize_colors(\n        self, num_colors: int = 128, use_global_palette: bool = True\n    ) -> list[np.ndarray]:\n        \"\"\"\n        Reduce colors in all frames using quantization.\n\n        Args:\n            num_colors: Target number of colors (8-256)\n            use_global_palette: Use a single palette for all frames (better compression)\n\n        Returns:\n            List of color-optimized frames\n        \"\"\"\n        optimized = []\n\n        if use_global_palette and len(self.frames) > 1:\n            # Create a global palette from all frames\n            # Sample frames to build palette\n            sample_size = min(5, len(self.frames))\n            sample_indices = [\n                int(i * len(self.frames) / sample_size) for i in range(sample_size)\n            ]\n            sample_frames = [self.frames[i] for i in sample_indices]\n\n            # Combine sample frames into a single image for palette generation\n            # Flatten each frame to get all pixels, then stack them\n            all_pixels = np.vstack(\n                [f.reshape(-1, 3) for f in sample_frames]\n            )  # (total_pixels, 3)\n\n            # Create a properly-shaped RGB image from the pixel data\n            # We'll make a roughly square image from all the pixels\n            total_pixels = len(all_pixels)\n            width = min(512, int(np.sqrt(total_pixels)))  # Reasonable width, max 512\n            height = (total_pixels + width - 1) // width  # Ceiling division\n\n            # Pad if necessary to fill the rectangle\n            pixels_needed = width * height\n            if pixels_needed > total_pixels:\n                padding = np.zeros((pixels_needed - total_pixels, 3), dtype=np.uint8)\n                all_pixels = np.vstack([all_pixels, padding])\n\n            # Reshape to proper RGB image format (H, W, 3)\n            img_array = (\n                all_pixels[:pixels_needed].reshape(height, width, 3).astype(np.uint8)\n            )\n            combined_img = Image.fromarray(img_array, mode=\"RGB\")\n\n            # Generate global palette\n            global_palette = combined_img.quantize(colors=num_colors, method=2)\n\n            # Apply global palette to all frames\n            for frame in self.frames:\n                pil_frame = Image.fromarray(frame)\n                quantized = pil_frame.quantize(palette=global_palette, dither=1)\n                optimized.append(np.array(quantized.convert(\"RGB\")))\n        else:\n            # Use per-frame quantization\n            for frame in self.frames:\n                pil_frame = Image.fromarray(frame)\n                quantized = pil_frame.quantize(colors=num_colors, method=2, dither=1)\n                optimized.append(np.array(quantized.convert(\"RGB\")))\n\n        return optimized\n\n    def deduplicate_frames(self, threshold: float = 0.9995) -> int:\n        \"\"\"\n        Remove duplicate or near-duplicate consecutive frames.\n\n        Args:\n            threshold: Similarity threshold (0.0-1.0). Higher = more strict (0.9995 = nearly identical).\n                      Use 0.9995+ to preserve subtle animations, 0.98 for aggressive removal.\n\n        Returns:\n            Number of frames removed\n        \"\"\"\n        if len(self.frames) < 2:\n            return 0\n\n        deduplicated = [self.frames[0]]\n        removed_count = 0\n\n        for i in range(1, len(self.frames)):\n            # Compare with previous frame\n            prev_frame = np.array(deduplicated[-1], dtype=np.float32)\n            curr_frame = np.array(self.frames[i], dtype=np.float32)\n\n            # Calculate similarity (normalized)\n            diff = np.abs(prev_frame - curr_frame)\n            similarity = 1.0 - (np.mean(diff) / 255.0)\n\n            # Keep frame if sufficiently different\n            # High threshold (0.9995+) means only remove nearly identical frames\n            if similarity < threshold:\n                deduplicated.append(self.frames[i])\n            else:\n                removed_count += 1\n\n        self.frames = deduplicated\n        return removed_count\n\n    def save(\n        self,\n        output_path: str | Path,\n        num_colors: int = 128,\n        optimize_for_emoji: bool = False,\n        remove_duplicates: bool = False,\n    ) -> dict:\n        \"\"\"\n        Save frames as optimized GIF for Slack.\n\n        Args:\n            output_path: Where to save the GIF\n            num_colors: Number of colors to use (fewer = smaller file)\n            optimize_for_emoji: If True, optimize for emoji size (128x128, fewer colors)\n            remove_duplicates: If True, remove duplicate consecutive frames (opt-in)\n\n        Returns:\n            Dictionary with file info (path, size, dimensions, frame_count)\n        \"\"\"\n        if not self.frames:\n            raise ValueError(\"No frames to save. Add frames with add_frame() first.\")\n\n        output_path = Path(output_path)\n\n        # Remove duplicate frames to reduce file size\n        if remove_duplicates:\n            removed = self.deduplicate_frames(threshold=0.9995)\n            if removed > 0:\n                print(\n                    f\"  Removed {removed} nearly identical frames (preserved subtle animations)\"\n                )\n\n        # Optimize for emoji if requested\n        if optimize_for_emoji:\n            if self.width > 128 or self.height > 128:\n                print(\n                    f\"  Resizing from {self.width}x{self.height} to 128x128 for emoji\"\n                )\n                self.width = 128\n                self.height = 128\n                # Resize all frames\n                resized_frames = []\n                for frame in self.frames:\n                    pil_frame = Image.fromarray(frame)\n                    pil_frame = pil_frame.resize((128, 128), Image.Resampling.LANCZOS)\n                    resized_frames.append(np.array(pil_frame))\n                self.frames = resized_frames\n            num_colors = min(num_colors, 48)  # More aggressive color limit for emoji\n\n            # More aggressive FPS reduction for emoji\n            if len(self.frames) > 12:\n                print(\n                    f\"  Reducing frames from {len(self.frames)} to ~12 for emoji size\"\n                )\n                # Keep every nth frame to get close to 12 frames\n                keep_every = max(1, len(self.frames) // 12)\n                self.frames = [\n                    self.frames[i] for i in range(0, len(self.frames), keep_every)\n                ]\n\n        # Optimize colors with global palette\n        optimized_frames = self.optimize_colors(num_colors, use_global_palette=True)\n\n        # Calculate frame duration in milliseconds\n        frame_duration = 1000 / self.fps\n\n        # Save GIF\n        imageio.imwrite(\n            output_path,\n            optimized_frames,\n            duration=frame_duration,\n            loop=0,  # Infinite loop\n        )\n\n        # Get file info\n        file_size_kb = output_path.stat().st_size / 1024\n        file_size_mb = file_size_kb / 1024\n\n        info = {\n            \"path\": str(output_path),\n            \"size_kb\": file_size_kb,\n            \"size_mb\": file_size_mb,\n            \"dimensions\": f\"{self.width}x{self.height}\",\n            \"frame_count\": len(optimized_frames),\n            \"fps\": self.fps,\n            \"duration_seconds\": len(optimized_frames) / self.fps,\n            \"colors\": num_colors,\n        }\n\n        # Print info\n        print(f\"\\n✓ GIF created successfully!\")\n        print(f\"  Path: {output_path}\")\n        print(f\"  Size: {file_size_kb:.1f} KB ({file_size_mb:.2f} MB)\")\n        print(f\"  Dimensions: {self.width}x{self.height}\")\n        print(f\"  Frames: {len(optimized_frames)} @ {self.fps} fps\")\n        print(f\"  Duration: {info['duration_seconds']:.1f}s\")\n        print(f\"  Colors: {num_colors}\")\n\n        # Size info\n        if optimize_for_emoji:\n            print(f\"  Optimized for emoji (128x128, reduced colors)\")\n        if file_size_mb > 1.0:\n            print(f\"\\n  Note: Large file size ({file_size_kb:.1f} KB)\")\n            print(\"  Consider: fewer frames, smaller dimensions, or fewer colors\")\n\n        return info\n\n    def clear(self):\n        \"\"\"Clear all frames (useful for creating multiple GIFs).\"\"\"\n        self.frames = []\n"
  },
  {
    "path": "skills/slack-gif-creator/core/validators.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nValidators - Check if GIFs meet Slack's requirements.\n\nThese validators help ensure your GIFs meet Slack's size and dimension constraints.\n\"\"\"\n\nfrom pathlib import Path\n\n\ndef validate_gif(\n    gif_path: str | Path, is_emoji: bool = True, verbose: bool = True\n) -> tuple[bool, dict]:\n    \"\"\"\n    Validate GIF for Slack (dimensions, size, frame count).\n\n    Args:\n        gif_path: Path to GIF file\n        is_emoji: True for emoji (128x128 recommended), False for message GIF\n        verbose: Print validation details\n\n    Returns:\n        Tuple of (passes: bool, results: dict with all details)\n    \"\"\"\n    from PIL import Image\n\n    gif_path = Path(gif_path)\n\n    if not gif_path.exists():\n        return False, {\"error\": f\"File not found: {gif_path}\"}\n\n    # Get file size\n    size_bytes = gif_path.stat().st_size\n    size_kb = size_bytes / 1024\n    size_mb = size_kb / 1024\n\n    # Get dimensions and frame info\n    try:\n        with Image.open(gif_path) as img:\n            width, height = img.size\n\n            # Count frames\n            frame_count = 0\n            try:\n                while True:\n                    img.seek(frame_count)\n                    frame_count += 1\n            except EOFError:\n                pass\n\n            # Get duration\n            try:\n                duration_ms = img.info.get(\"duration\", 100)\n                total_duration = (duration_ms * frame_count) / 1000\n                fps = frame_count / total_duration if total_duration > 0 else 0\n            except:\n                total_duration = None\n                fps = None\n\n    except Exception as e:\n        return False, {\"error\": f\"Failed to read GIF: {e}\"}\n\n    # Validate dimensions\n    if is_emoji:\n        optimal = width == height == 128\n        acceptable = width == height and 64 <= width <= 128\n        dim_pass = acceptable\n    else:\n        aspect_ratio = (\n            max(width, height) / min(width, height)\n            if min(width, height) > 0\n            else float(\"inf\")\n        )\n        dim_pass = aspect_ratio <= 2.0 and 320 <= min(width, height) <= 640\n\n    results = {\n        \"file\": str(gif_path),\n        \"passes\": dim_pass,\n        \"width\": width,\n        \"height\": height,\n        \"size_kb\": size_kb,\n        \"size_mb\": size_mb,\n        \"frame_count\": frame_count,\n        \"duration_seconds\": total_duration,\n        \"fps\": fps,\n        \"is_emoji\": is_emoji,\n        \"optimal\": optimal if is_emoji else None,\n    }\n\n    # Print if verbose\n    if verbose:\n        print(f\"\\nValidating {gif_path.name}:\")\n        print(\n            f\"  Dimensions: {width}x{height}\"\n            + (\n                f\" ({'optimal' if optimal else 'acceptable'})\"\n                if is_emoji and acceptable\n                else \"\"\n            )\n        )\n        print(\n            f\"  Size: {size_kb:.1f} KB\"\n            + (f\" ({size_mb:.2f} MB)\" if size_mb >= 1.0 else \"\")\n        )\n        print(\n            f\"  Frames: {frame_count}\"\n            + (f\" @ {fps:.1f} fps ({total_duration:.1f}s)\" if fps else \"\")\n        )\n\n        if not dim_pass:\n            print(\n                f\"  Note: {'Emoji should be 128x128' if is_emoji else 'Unusual dimensions for Slack'}\"\n            )\n\n        if size_mb > 5.0:\n            print(f\"  Note: Large file size - consider fewer frames/colors\")\n\n    return dim_pass, results\n\n\ndef is_slack_ready(\n    gif_path: str | Path, is_emoji: bool = True, verbose: bool = True\n) -> bool:\n    \"\"\"\n    Quick check if GIF is ready for Slack.\n\n    Args:\n        gif_path: Path to GIF file\n        is_emoji: True for emoji GIF, False for message GIF\n        verbose: Print feedback\n\n    Returns:\n        True if dimensions are acceptable\n    \"\"\"\n    passes, _ = validate_gif(gif_path, is_emoji, verbose)\n    return passes\n"
  },
  {
    "path": "skills/slack-gif-creator/requirements.txt",
    "content": "pillow>=10.0.0\nimageio>=2.31.0\nimageio-ffmpeg>=0.4.9\nnumpy>=1.24.0"
  },
  {
    "path": "skills/theme-factory/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/theme-factory/SKILL.md",
    "content": "---\nname: theme-factory\ndescription: Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.\nlicense: Complete terms in LICENSE.txt\n---\n\n\n# Theme Factory Skill\n\nThis skill provides a curated collection of professional font and color themes themes, each with carefully selected color palettes and font pairings. Once a theme is chosen, it can be applied to any artifact.\n\n## Purpose\n\nTo apply consistent, professional styling to presentation slide decks, use this skill. Each theme includes:\n- A cohesive color palette with hex codes\n- Complementary font pairings for headers and body text\n- A distinct visual identity suitable for different contexts and audiences\n\n## Usage Instructions\n\nTo apply styling to a slide deck or other artifact:\n\n1. **Show the theme showcase**: Display the `theme-showcase.pdf` file to allow users to see all available themes visually. Do not make any modifications to it; simply show the file for viewing.\n2. **Ask for their choice**: Ask which theme to apply to the deck\n3. **Wait for selection**: Get explicit confirmation about the chosen theme\n4. **Apply the theme**: Once a theme has been chosen, apply the selected theme's colors and fonts to the deck/artifact\n\n## Themes Available\n\nThe following 10 themes are available, each showcased in `theme-showcase.pdf`:\n\n1. **Ocean Depths** - Professional and calming maritime theme\n2. **Sunset Boulevard** - Warm and vibrant sunset colors\n3. **Forest Canopy** - Natural and grounded earth tones\n4. **Modern Minimalist** - Clean and contemporary grayscale\n5. **Golden Hour** - Rich and warm autumnal palette\n6. **Arctic Frost** - Cool and crisp winter-inspired theme\n7. **Desert Rose** - Soft and sophisticated dusty tones\n8. **Tech Innovation** - Bold and modern tech aesthetic\n9. **Botanical Garden** - Fresh and organic garden colors\n10. **Midnight Galaxy** - Dramatic and cosmic deep tones\n\n## Theme Details\n\nEach theme is defined in the `themes/` directory with complete specifications including:\n- Cohesive color palette with hex codes\n- Complementary font pairings for headers and body text\n- Distinct visual identity suitable for different contexts and audiences\n\n## Application Process\n\nAfter a preferred theme is selected:\n1. Read the corresponding theme file from the `themes/` directory\n2. Apply the specified colors and fonts consistently throughout the deck\n3. Ensure proper contrast and readability\n4. Maintain the theme's visual identity across all slides\n\n## Create your Own Theme\nTo handle cases where none of the existing themes work for an artifact, create a custom theme. Based on provided inputs, generate a new theme similar to the ones above. Give the theme a similar name describing what the font/color combinations represent. Use any basic description provided to choose appropriate colors/fonts. After generating the theme, show it for review and verification. Following that, apply the theme as described above.\n"
  },
  {
    "path": "skills/theme-factory/themes/arctic-frost.md",
    "content": "# Arctic Frost\n\nA cool and crisp winter-inspired theme that conveys clarity, precision, and professionalism.\n\n## Color Palette\n\n- **Ice Blue**: `#d4e4f7` - Light backgrounds and highlights\n- **Steel Blue**: `#4a6fa5` - Primary accent color\n- **Silver**: `#c0c0c0` - Metallic accent elements\n- **Crisp White**: `#fafafa` - Clean backgrounds and text\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nHealthcare presentations, technology solutions, winter sports, clean tech, pharmaceutical content.\n"
  },
  {
    "path": "skills/theme-factory/themes/botanical-garden.md",
    "content": "# Botanical Garden\n\nA fresh and organic theme featuring vibrant garden-inspired colors for lively presentations.\n\n## Color Palette\n\n- **Fern Green**: `#4a7c59` - Rich natural green\n- **Marigold**: `#f9a620` - Bright floral accent\n- **Terracotta**: `#b7472a` - Earthy warm tone\n- **Cream**: `#f5f3ed` - Soft neutral backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Serif Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nGarden centers, food presentations, farm-to-table content, botanical brands, natural products.\n"
  },
  {
    "path": "skills/theme-factory/themes/desert-rose.md",
    "content": "# Desert Rose\n\nA soft and sophisticated theme with dusty, muted tones perfect for elegant presentations.\n\n## Color Palette\n\n- **Dusty Rose**: `#d4a5a5` - Soft primary color\n- **Clay**: `#b87d6d` - Earthy accent\n- **Sand**: `#e8d5c4` - Warm neutral backgrounds\n- **Deep Burgundy**: `#5d2e46` - Rich dark contrast\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nFashion presentations, beauty brands, wedding planning, interior design, boutique businesses.\n"
  },
  {
    "path": "skills/theme-factory/themes/forest-canopy.md",
    "content": "# Forest Canopy\n\nA natural and grounded theme featuring earth tones inspired by dense forest environments.\n\n## Color Palette\n\n- **Forest Green**: `#2d4a2b` - Primary dark green\n- **Sage**: `#7d8471` - Muted green accent\n- **Olive**: `#a4ac86` - Light accent color\n- **Ivory**: `#faf9f6` - Backgrounds and text\n\n## Typography\n\n- **Headers**: FreeSerif Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nEnvironmental presentations, sustainability reports, outdoor brands, wellness content, organic products.\n"
  },
  {
    "path": "skills/theme-factory/themes/golden-hour.md",
    "content": "# Golden Hour\n\nA rich and warm autumnal palette that creates an inviting and sophisticated atmosphere.\n\n## Color Palette\n\n- **Mustard Yellow**: `#f4a900` - Bold primary accent\n- **Terracotta**: `#c1666b` - Warm secondary color\n- **Warm Beige**: `#d4b896` - Neutral backgrounds\n- **Chocolate Brown**: `#4a403a` - Dark text and anchors\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nRestaurant presentations, hospitality brands, fall campaigns, cozy lifestyle content, artisan products.\n"
  },
  {
    "path": "skills/theme-factory/themes/midnight-galaxy.md",
    "content": "# Midnight Galaxy\n\nA dramatic and cosmic theme with deep purples and mystical tones for impactful presentations.\n\n## Color Palette\n\n- **Deep Purple**: `#2b1e3e` - Rich dark base\n- **Cosmic Blue**: `#4a4e8f` - Mystical mid-tone\n- **Lavender**: `#a490c2` - Soft accent color\n- **Silver**: `#e6e6fa` - Light highlights and text\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nEntertainment industry, gaming presentations, nightlife venues, luxury brands, creative agencies.\n"
  },
  {
    "path": "skills/theme-factory/themes/modern-minimalist.md",
    "content": "# Modern Minimalist\n\nA clean and contemporary theme with a sophisticated grayscale palette for maximum versatility.\n\n## Color Palette\n\n- **Charcoal**: `#36454f` - Primary dark color\n- **Slate Gray**: `#708090` - Medium gray for accents\n- **Light Gray**: `#d3d3d3` - Backgrounds and dividers\n- **White**: `#ffffff` - Text and clean backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nTech presentations, architecture portfolios, design showcases, modern business proposals, data visualization.\n"
  },
  {
    "path": "skills/theme-factory/themes/ocean-depths.md",
    "content": "# Ocean Depths\n\nA professional and calming maritime theme that evokes the serenity of deep ocean waters.\n\n## Color Palette\n\n- **Deep Navy**: `#1a2332` - Primary background color\n- **Teal**: `#2d8b8b` - Accent color for highlights and emphasis\n- **Seafoam**: `#a8dadc` - Secondary accent for lighter elements\n- **Cream**: `#f1faee` - Text and light backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nCorporate presentations, financial reports, professional consulting decks, trust-building content.\n"
  },
  {
    "path": "skills/theme-factory/themes/sunset-boulevard.md",
    "content": "# Sunset Boulevard\n\nA warm and vibrant theme inspired by golden hour sunsets, perfect for energetic and creative presentations.\n\n## Color Palette\n\n- **Burnt Orange**: `#e76f51` - Primary accent color\n- **Coral**: `#f4a261` - Secondary warm accent\n- **Warm Sand**: `#e9c46a` - Highlighting and backgrounds\n- **Deep Purple**: `#264653` - Dark contrast and text\n\n## Typography\n\n- **Headers**: DejaVu Serif Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nCreative pitches, marketing presentations, lifestyle brands, event promotions, inspirational content.\n"
  },
  {
    "path": "skills/theme-factory/themes/tech-innovation.md",
    "content": "# Tech Innovation\n\nA bold and modern theme with high-contrast colors perfect for cutting-edge technology presentations.\n\n## Color Palette\n\n- **Electric Blue**: `#0066ff` - Vibrant primary accent\n- **Neon Cyan**: `#00ffff` - Bright highlight color\n- **Dark Gray**: `#1e1e1e` - Deep backgrounds\n- **White**: `#ffffff` - Clean text and contrast\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nTech startups, software launches, innovation showcases, AI/ML presentations, digital transformation content.\n"
  },
  {
    "path": "skills/web-artifacts-builder/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/web-artifacts-builder/SKILL.md",
    "content": "---\nname: web-artifacts-builder\ndescription: Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Web Artifacts Builder\n\nTo build powerful frontend claude.ai artifacts, follow these steps:\n1. Initialize the frontend repo using `scripts/init-artifact.sh`\n2. Develop your artifact by editing the generated code\n3. Bundle all code into a single HTML file using `scripts/bundle-artifact.sh`\n4. Display artifact to user\n5. (Optional) Test the artifact\n\n**Stack**: React 18 + TypeScript + Vite + Parcel (bundling) + Tailwind CSS + shadcn/ui\n\n## Design & Style Guidelines\n\nVERY IMPORTANT: To avoid what is often referred to as \"AI slop\", avoid using excessive centered layouts, purple gradients, uniform rounded corners, and Inter font.\n\n## Quick Start\n\n### Step 1: Initialize Project\n\nRun the initialization script to create a new React project:\n```bash\nbash scripts/init-artifact.sh <project-name>\ncd <project-name>\n```\n\nThis creates a fully configured project with:\n- ✅ React + TypeScript (via Vite)\n- ✅ Tailwind CSS 3.4.1 with shadcn/ui theming system\n- ✅ Path aliases (`@/`) configured\n- ✅ 40+ shadcn/ui components pre-installed\n- ✅ All Radix UI dependencies included\n- ✅ Parcel configured for bundling (via .parcelrc)\n- ✅ Node 18+ compatibility (auto-detects and pins Vite version)\n\n### Step 2: Develop Your Artifact\n\nTo build the artifact, edit the generated files. See **Common Development Tasks** below for guidance.\n\n### Step 3: Bundle to Single HTML File\n\nTo bundle the React app into a single HTML artifact:\n```bash\nbash scripts/bundle-artifact.sh\n```\n\nThis creates `bundle.html` - a self-contained artifact with all JavaScript, CSS, and dependencies inlined. This file can be directly shared in Claude conversations as an artifact.\n\n**Requirements**: Your project must have an `index.html` in the root directory.\n\n**What the script does**:\n- Installs bundling dependencies (parcel, @parcel/config-default, parcel-resolver-tspaths, html-inline)\n- Creates `.parcelrc` config with path alias support\n- Builds with Parcel (no source maps)\n- Inlines all assets into single HTML using html-inline\n\n### Step 4: Share Artifact with User\n\nFinally, share the bundled HTML file in conversation with the user so they can view it as an artifact.\n\n### Step 5: Testing/Visualizing the Artifact (Optional)\n\nNote: This is a completely optional step. Only perform if necessary or requested.\n\nTo test/visualize the artifact, use available tools (including other Skills or built-in tools like Playwright or Puppeteer). In general, avoid testing the artifact upfront as it adds latency between the request and when the finished artifact can be seen. Test later, after presenting the artifact, if requested or if issues arise.\n\n## Reference\n\n- **shadcn/ui components**: https://ui.shadcn.com/docs/components"
  },
  {
    "path": "skills/web-artifacts-builder/scripts/bundle-artifact.sh",
    "content": "#!/bin/bash\nset -e\n\necho \"📦 Bundling React app to single HTML artifact...\"\n\n# Check if we're in a project directory\nif [ ! -f \"package.json\" ]; then\n  echo \"❌ Error: No package.json found. Run this script from your project root.\"\n  exit 1\nfi\n\n# Check if index.html exists\nif [ ! -f \"index.html\" ]; then\n  echo \"❌ Error: No index.html found in project root.\"\n  echo \"   This script requires an index.html entry point.\"\n  exit 1\nfi\n\n# Install bundling dependencies\necho \"📦 Installing bundling dependencies...\"\npnpm add -D parcel @parcel/config-default parcel-resolver-tspaths html-inline\n\n# Create Parcel config with tspaths resolver\nif [ ! -f \".parcelrc\" ]; then\n  echo \"🔧 Creating Parcel configuration with path alias support...\"\n  cat > .parcelrc << 'EOF'\n{\n  \"extends\": \"@parcel/config-default\",\n  \"resolvers\": [\"parcel-resolver-tspaths\", \"...\"]\n}\nEOF\nfi\n\n# Clean previous build\necho \"🧹 Cleaning previous build...\"\nrm -rf dist bundle.html\n\n# Build with Parcel\necho \"🔨 Building with Parcel...\"\npnpm exec parcel build index.html --dist-dir dist --no-source-maps\n\n# Inline everything into single HTML\necho \"🎯 Inlining all assets into single HTML file...\"\npnpm exec html-inline dist/index.html > bundle.html\n\n# Get file size\nFILE_SIZE=$(du -h bundle.html | cut -f1)\n\necho \"\"\necho \"✅ Bundle complete!\"\necho \"📄 Output: bundle.html ($FILE_SIZE)\"\necho \"\"\necho \"You can now use this single HTML file as an artifact in Claude conversations.\"\necho \"To test locally: open bundle.html in your browser\""
  },
  {
    "path": "skills/web-artifacts-builder/scripts/init-artifact.sh",
    "content": "#!/bin/bash\n\n# Exit on error\nset -e\n\n# Detect Node version\nNODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)\n\necho \"🔍 Detected Node.js version: $NODE_VERSION\"\n\nif [ \"$NODE_VERSION\" -lt 18 ]; then\n  echo \"❌ Error: Node.js 18 or higher is required\"\n  echo \"   Current version: $(node -v)\"\n  exit 1\nfi\n\n# Set Vite version based on Node version\nif [ \"$NODE_VERSION\" -ge 20 ]; then\n  VITE_VERSION=\"latest\"\n  echo \"✅ Using Vite latest (Node 20+)\"\nelse\n  VITE_VERSION=\"5.4.11\"\n  echo \"✅ Using Vite $VITE_VERSION (Node 18 compatible)\"\nfi\n\n# Detect OS and set sed syntax\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n  SED_INPLACE=\"sed -i ''\"\nelse\n  SED_INPLACE=\"sed -i\"\nfi\n\n# Check if pnpm is installed\nif ! command -v pnpm &> /dev/null; then\n  echo \"📦 pnpm not found. Installing pnpm...\"\n  npm install -g pnpm\nfi\n\n# Check if project name is provided\nif [ -z \"$1\" ]; then\n  echo \"❌ Usage: ./create-react-shadcn-complete.sh <project-name>\"\n  exit 1\nfi\n\nPROJECT_NAME=\"$1\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCOMPONENTS_TARBALL=\"$SCRIPT_DIR/shadcn-components.tar.gz\"\n\n# Check if components tarball exists\nif [ ! -f \"$COMPONENTS_TARBALL\" ]; then\n  echo \"❌ Error: shadcn-components.tar.gz not found in script directory\"\n  echo \"   Expected location: $COMPONENTS_TARBALL\"\n  exit 1\nfi\n\necho \"🚀 Creating new React + Vite project: $PROJECT_NAME\"\n\n# Create new Vite project (always use latest create-vite, pin vite version later)\npnpm create vite \"$PROJECT_NAME\" --template react-ts\n\n# Navigate into project directory\ncd \"$PROJECT_NAME\"\n\necho \"🧹 Cleaning up Vite template...\"\n$SED_INPLACE '/<link rel=\"icon\".*vite\\.svg/d' index.html\n$SED_INPLACE 's/<title>.*<\\/title>/<title>'\"$PROJECT_NAME\"'<\\/title>/' index.html\n\necho \"📦 Installing base dependencies...\"\npnpm install\n\n# Pin Vite version for Node 18\nif [ \"$NODE_VERSION\" -lt 20 ]; then\n  echo \"📌 Pinning Vite to $VITE_VERSION for Node 18 compatibility...\"\n  pnpm add -D vite@$VITE_VERSION\nfi\n\necho \"📦 Installing Tailwind CSS and dependencies...\"\npnpm install -D tailwindcss@3.4.1 postcss autoprefixer @types/node tailwindcss-animate\npnpm install class-variance-authority clsx tailwind-merge lucide-react next-themes\n\necho \"⚙️  Creating Tailwind and PostCSS configuration...\"\ncat > postcss.config.js << 'EOF'\nexport default {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\nEOF\n\necho \"📝 Configuring Tailwind with shadcn theme...\"\ncat > tailwind.config.js << 'EOF'\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  darkMode: [\"class\"],\n  content: [\n    \"./index.html\",\n    \"./src/**/*.{js,ts,jsx,tsx}\",\n  ],\n  theme: {\n    extend: {\n      colors: {\n        border: \"hsl(var(--border))\",\n        input: \"hsl(var(--input))\",\n        ring: \"hsl(var(--ring))\",\n        background: \"hsl(var(--background))\",\n        foreground: \"hsl(var(--foreground))\",\n        primary: {\n          DEFAULT: \"hsl(var(--primary))\",\n          foreground: \"hsl(var(--primary-foreground))\",\n        },\n        secondary: {\n          DEFAULT: \"hsl(var(--secondary))\",\n          foreground: \"hsl(var(--secondary-foreground))\",\n        },\n        destructive: {\n          DEFAULT: \"hsl(var(--destructive))\",\n          foreground: \"hsl(var(--destructive-foreground))\",\n        },\n        muted: {\n          DEFAULT: \"hsl(var(--muted))\",\n          foreground: \"hsl(var(--muted-foreground))\",\n        },\n        accent: {\n          DEFAULT: \"hsl(var(--accent))\",\n          foreground: \"hsl(var(--accent-foreground))\",\n        },\n        popover: {\n          DEFAULT: \"hsl(var(--popover))\",\n          foreground: \"hsl(var(--popover-foreground))\",\n        },\n        card: {\n          DEFAULT: \"hsl(var(--card))\",\n          foreground: \"hsl(var(--card-foreground))\",\n        },\n      },\n      borderRadius: {\n        lg: \"var(--radius)\",\n        md: \"calc(var(--radius) - 2px)\",\n        sm: \"calc(var(--radius) - 4px)\",\n      },\n      keyframes: {\n        \"accordion-down\": {\n          from: { height: \"0\" },\n          to: { height: \"var(--radix-accordion-content-height)\" },\n        },\n        \"accordion-up\": {\n          from: { height: \"var(--radix-accordion-content-height)\" },\n          to: { height: \"0\" },\n        },\n      },\n      animation: {\n        \"accordion-down\": \"accordion-down 0.2s ease-out\",\n        \"accordion-up\": \"accordion-up 0.2s ease-out\",\n      },\n    },\n  },\n  plugins: [require(\"tailwindcss-animate\")],\n}\nEOF\n\n# Add Tailwind directives and CSS variables to index.css\necho \"🎨 Adding Tailwind directives and CSS variables...\"\ncat > src/index.css << 'EOF'\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 0 0% 3.9%;\n    --card: 0 0% 100%;\n    --card-foreground: 0 0% 3.9%;\n    --popover: 0 0% 100%;\n    --popover-foreground: 0 0% 3.9%;\n    --primary: 0 0% 9%;\n    --primary-foreground: 0 0% 98%;\n    --secondary: 0 0% 96.1%;\n    --secondary-foreground: 0 0% 9%;\n    --muted: 0 0% 96.1%;\n    --muted-foreground: 0 0% 45.1%;\n    --accent: 0 0% 96.1%;\n    --accent-foreground: 0 0% 9%;\n    --destructive: 0 84.2% 60.2%;\n    --destructive-foreground: 0 0% 98%;\n    --border: 0 0% 89.8%;\n    --input: 0 0% 89.8%;\n    --ring: 0 0% 3.9%;\n    --radius: 0.5rem;\n  }\n\n  .dark {\n    --background: 0 0% 3.9%;\n    --foreground: 0 0% 98%;\n    --card: 0 0% 3.9%;\n    --card-foreground: 0 0% 98%;\n    --popover: 0 0% 3.9%;\n    --popover-foreground: 0 0% 98%;\n    --primary: 0 0% 98%;\n    --primary-foreground: 0 0% 9%;\n    --secondary: 0 0% 14.9%;\n    --secondary-foreground: 0 0% 98%;\n    --muted: 0 0% 14.9%;\n    --muted-foreground: 0 0% 63.9%;\n    --accent: 0 0% 14.9%;\n    --accent-foreground: 0 0% 98%;\n    --destructive: 0 62.8% 30.6%;\n    --destructive-foreground: 0 0% 98%;\n    --border: 0 0% 14.9%;\n    --input: 0 0% 14.9%;\n    --ring: 0 0% 83.1%;\n  }\n}\n\n@layer base {\n  * {\n    @apply border-border;\n  }\n  body {\n    @apply bg-background text-foreground;\n  }\n}\nEOF\n\n# Add path aliases to tsconfig.json\necho \"🔧 Adding path aliases to tsconfig.json...\"\nnode -e \"\nconst fs = require('fs');\nconst config = JSON.parse(fs.readFileSync('tsconfig.json', 'utf8'));\nconfig.compilerOptions = config.compilerOptions || {};\nconfig.compilerOptions.baseUrl = '.';\nconfig.compilerOptions.paths = { '@/*': ['./src/*'] };\nfs.writeFileSync('tsconfig.json', JSON.stringify(config, null, 2));\n\"\n\n# Add path aliases to tsconfig.app.json\necho \"🔧 Adding path aliases to tsconfig.app.json...\"\nnode -e \"\nconst fs = require('fs');\nconst path = 'tsconfig.app.json';\nconst content = fs.readFileSync(path, 'utf8');\n// Remove comments manually\nconst lines = content.split('\\n').filter(line => !line.trim().startsWith('//'));\nconst jsonContent = lines.join('\\n');\nconst config = JSON.parse(jsonContent.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/,(\\s*[}\\]])/g, '\\$1'));\nconfig.compilerOptions = config.compilerOptions || {};\nconfig.compilerOptions.baseUrl = '.';\nconfig.compilerOptions.paths = { '@/*': ['./src/*'] };\nfs.writeFileSync(path, JSON.stringify(config, null, 2));\n\"\n\n# Update vite.config.ts\necho \"⚙️  Updating Vite configuration...\"\ncat > vite.config.ts << 'EOF'\nimport path from \"path\";\nimport react from \"@vitejs/plugin-react\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n  plugins: [react()],\n  resolve: {\n    alias: {\n      \"@\": path.resolve(__dirname, \"./src\"),\n    },\n  },\n});\nEOF\n\n# Install all shadcn/ui dependencies\necho \"📦 Installing shadcn/ui dependencies...\"\npnpm install @radix-ui/react-accordion @radix-ui/react-aspect-ratio @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-collapsible @radix-ui/react-context-menu @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-hover-card @radix-ui/react-label @radix-ui/react-menubar @radix-ui/react-navigation-menu @radix-ui/react-popover @radix-ui/react-progress @radix-ui/react-radio-group @radix-ui/react-scroll-area @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slider @radix-ui/react-slot @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-toast @radix-ui/react-toggle @radix-ui/react-toggle-group @radix-ui/react-tooltip\npnpm install sonner cmdk vaul embla-carousel-react react-day-picker react-resizable-panels date-fns react-hook-form @hookform/resolvers zod\n\n# Extract shadcn components from tarball\necho \"📦 Extracting shadcn/ui components...\"\ntar -xzf \"$COMPONENTS_TARBALL\" -C src/\n\n# Create components.json for reference\necho \"📝 Creating components.json config...\"\ncat > components.json << 'EOF'\n{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": false,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"tailwind.config.js\",\n    \"css\": \"src/index.css\",\n    \"baseColor\": \"slate\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\",\n    \"utils\": \"@/lib/utils\",\n    \"ui\": \"@/components/ui\",\n    \"lib\": \"@/lib\",\n    \"hooks\": \"@/hooks\"\n  }\n}\nEOF\n\necho \"✅ Setup complete! You can now use Tailwind CSS and shadcn/ui in your project.\"\necho \"\"\necho \"📦 Included components (40+ total):\"\necho \"  - accordion, alert, aspect-ratio, avatar, badge, breadcrumb\"\necho \"  - button, calendar, card, carousel, checkbox, collapsible\"\necho \"  - command, context-menu, dialog, drawer, dropdown-menu\"\necho \"  - form, hover-card, input, label, menubar, navigation-menu\"\necho \"  - popover, progress, radio-group, resizable, scroll-area\"\necho \"  - select, separator, sheet, skeleton, slider, sonner\"\necho \"  - switch, table, tabs, textarea, toast, toggle, toggle-group, tooltip\"\necho \"\"\necho \"To start developing:\"\necho \"  cd $PROJECT_NAME\"\necho \"  pnpm dev\"\necho \"\"\necho \"📚 Import components like:\"\necho \"  import { Button } from '@/components/ui/button'\"\necho \"  import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'\"\necho \"  import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog'\"\n"
  },
  {
    "path": "skills/webapp-testing/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skills/webapp-testing/SKILL.md",
    "content": "---\nname: webapp-testing\ndescription: Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Web Application Testing\n\nTo test local web applications, write native Python Playwright scripts.\n\n**Helper Scripts Available**:\n- `scripts/with_server.py` - Manages server lifecycle (supports multiple servers)\n\n**Always run scripts with `--help` first** to see usage. DO NOT read the source until you try running the script first and find that a customized solution is abslutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window.\n\n## Decision Tree: Choosing Your Approach\n\n```\nUser task → Is it static HTML?\n    ├─ Yes → Read HTML file directly to identify selectors\n    │         ├─ Success → Write Playwright script using selectors\n    │         └─ Fails/Incomplete → Treat as dynamic (below)\n    │\n    └─ No (dynamic webapp) → Is the server already running?\n        ├─ No → Run: python scripts/with_server.py --help\n        │        Then use the helper + write simplified Playwright script\n        │\n        └─ Yes → Reconnaissance-then-action:\n            1. Navigate and wait for networkidle\n            2. Take screenshot or inspect DOM\n            3. Identify selectors from rendered state\n            4. Execute actions with discovered selectors\n```\n\n## Example: Using with_server.py\n\nTo start a server, run `--help` first, then use the helper:\n\n**Single server:**\n```bash\npython scripts/with_server.py --server \"npm run dev\" --port 5173 -- python your_automation.py\n```\n\n**Multiple servers (e.g., backend + frontend):**\n```bash\npython scripts/with_server.py \\\n  --server \"cd backend && python server.py\" --port 3000 \\\n  --server \"cd frontend && npm run dev\" --port 5173 \\\n  -- python your_automation.py\n```\n\nTo create an automation script, include only Playwright logic (servers are managed automatically):\n```python\nfrom playwright.sync_api import sync_playwright\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode\n    page = browser.new_page()\n    page.goto('http://localhost:5173') # Server already running and ready\n    page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute\n    # ... your automation logic\n    browser.close()\n```\n\n## Reconnaissance-Then-Action Pattern\n\n1. **Inspect rendered DOM**:\n   ```python\n   page.screenshot(path='/tmp/inspect.png', full_page=True)\n   content = page.content()\n   page.locator('button').all()\n   ```\n\n2. **Identify selectors** from inspection results\n\n3. **Execute actions** using discovered selectors\n\n## Common Pitfall\n\n❌ **Don't** inspect the DOM before waiting for `networkidle` on dynamic apps\n✅ **Do** wait for `page.wait_for_load_state('networkidle')` before inspection\n\n## Best Practices\n\n- **Use bundled scripts as black boxes** - To accomplish a task, consider whether one of the scripts available in `scripts/` can help. These scripts handle common, complex workflows reliably without cluttering the context window. Use `--help` to see usage, then invoke directly. \n- Use `sync_playwright()` for synchronous scripts\n- Always close the browser when done\n- Use descriptive selectors: `text=`, `role=`, CSS selectors, or IDs\n- Add appropriate waits: `page.wait_for_selector()` or `page.wait_for_timeout()`\n\n## Reference Files\n\n- **examples/** - Examples showing common patterns:\n  - `element_discovery.py` - Discovering buttons, links, and inputs on a page\n  - `static_html_automation.py` - Using file:// URLs for local HTML\n  - `console_logging.py` - Capturing console logs during automation"
  },
  {
    "path": "skills/webapp-testing/examples/console_logging.py",
    "content": "from playwright.sync_api import sync_playwright\n\n# Example: Capturing console logs during browser automation\n\nurl = 'http://localhost:5173'  # Replace with your URL\n\nconsole_logs = []\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page(viewport={'width': 1920, 'height': 1080})\n\n    # Set up console log capture\n    def handle_console_message(msg):\n        console_logs.append(f\"[{msg.type}] {msg.text}\")\n        print(f\"Console: [{msg.type}] {msg.text}\")\n\n    page.on(\"console\", handle_console_message)\n\n    # Navigate to page\n    page.goto(url)\n    page.wait_for_load_state('networkidle')\n\n    # Interact with the page (triggers console logs)\n    page.click('text=Dashboard')\n    page.wait_for_timeout(1000)\n\n    browser.close()\n\n# Save console logs to file\nwith open('/mnt/user-data/outputs/console.log', 'w') as f:\n    f.write('\\n'.join(console_logs))\n\nprint(f\"\\nCaptured {len(console_logs)} console messages\")\nprint(f\"Logs saved to: /mnt/user-data/outputs/console.log\")"
  },
  {
    "path": "skills/webapp-testing/examples/element_discovery.py",
    "content": "from playwright.sync_api import sync_playwright\n\n# Example: Discovering buttons and other elements on a page\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page()\n\n    # Navigate to page and wait for it to fully load\n    page.goto('http://localhost:5173')\n    page.wait_for_load_state('networkidle')\n\n    # Discover all buttons on the page\n    buttons = page.locator('button').all()\n    print(f\"Found {len(buttons)} buttons:\")\n    for i, button in enumerate(buttons):\n        text = button.inner_text() if button.is_visible() else \"[hidden]\"\n        print(f\"  [{i}] {text}\")\n\n    # Discover links\n    links = page.locator('a[href]').all()\n    print(f\"\\nFound {len(links)} links:\")\n    for link in links[:5]:  # Show first 5\n        text = link.inner_text().strip()\n        href = link.get_attribute('href')\n        print(f\"  - {text} -> {href}\")\n\n    # Discover input fields\n    inputs = page.locator('input, textarea, select').all()\n    print(f\"\\nFound {len(inputs)} input fields:\")\n    for input_elem in inputs:\n        name = input_elem.get_attribute('name') or input_elem.get_attribute('id') or \"[unnamed]\"\n        input_type = input_elem.get_attribute('type') or 'text'\n        print(f\"  - {name} ({input_type})\")\n\n    # Take screenshot for visual reference\n    page.screenshot(path='/tmp/page_discovery.png', full_page=True)\n    print(\"\\nScreenshot saved to /tmp/page_discovery.png\")\n\n    browser.close()"
  },
  {
    "path": "skills/webapp-testing/examples/static_html_automation.py",
    "content": "from playwright.sync_api import sync_playwright\nimport os\n\n# Example: Automating interaction with static HTML files using file:// URLs\n\nhtml_file_path = os.path.abspath('path/to/your/file.html')\nfile_url = f'file://{html_file_path}'\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page(viewport={'width': 1920, 'height': 1080})\n\n    # Navigate to local HTML file\n    page.goto(file_url)\n\n    # Take screenshot\n    page.screenshot(path='/mnt/user-data/outputs/static_page.png', full_page=True)\n\n    # Interact with elements\n    page.click('text=Click Me')\n    page.fill('#name', 'John Doe')\n    page.fill('#email', 'john@example.com')\n\n    # Submit form\n    page.click('button[type=\"submit\"]')\n    page.wait_for_timeout(500)\n\n    # Take final screenshot\n    page.screenshot(path='/mnt/user-data/outputs/after_submit.png', full_page=True)\n\n    browser.close()\n\nprint(\"Static HTML automation completed!\")"
  },
  {
    "path": "skills/webapp-testing/scripts/with_server.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nStart one or more servers, wait for them to be ready, run a command, then clean up.\n\nUsage:\n    # Single server\n    python scripts/with_server.py --server \"npm run dev\" --port 5173 -- python automation.py\n    python scripts/with_server.py --server \"npm start\" --port 3000 -- python test.py\n\n    # Multiple servers\n    python scripts/with_server.py \\\n      --server \"cd backend && python server.py\" --port 3000 \\\n      --server \"cd frontend && npm run dev\" --port 5173 \\\n      -- python test.py\n\"\"\"\n\nimport subprocess\nimport socket\nimport time\nimport sys\nimport argparse\n\ndef is_server_ready(port, timeout=30):\n    \"\"\"Wait for server to be ready by polling the port.\"\"\"\n    start_time = time.time()\n    while time.time() - start_time < timeout:\n        try:\n            with socket.create_connection(('localhost', port), timeout=1):\n                return True\n        except (socket.error, ConnectionRefusedError):\n            time.sleep(0.5)\n    return False\n\n\ndef main():\n    parser = argparse.ArgumentParser(description='Run command with one or more servers')\n    parser.add_argument('--server', action='append', dest='servers', required=True, help='Server command (can be repeated)')\n    parser.add_argument('--port', action='append', dest='ports', type=int, required=True, help='Port for each server (must match --server count)')\n    parser.add_argument('--timeout', type=int, default=30, help='Timeout in seconds per server (default: 30)')\n    parser.add_argument('command', nargs=argparse.REMAINDER, help='Command to run after server(s) ready')\n\n    args = parser.parse_args()\n\n    # Remove the '--' separator if present\n    if args.command and args.command[0] == '--':\n        args.command = args.command[1:]\n\n    if not args.command:\n        print(\"Error: No command specified to run\")\n        sys.exit(1)\n\n    # Parse server configurations\n    if len(args.servers) != len(args.ports):\n        print(\"Error: Number of --server and --port arguments must match\")\n        sys.exit(1)\n\n    servers = []\n    for cmd, port in zip(args.servers, args.ports):\n        servers.append({'cmd': cmd, 'port': port})\n\n    server_processes = []\n\n    try:\n        # Start all servers\n        for i, server in enumerate(servers):\n            print(f\"Starting server {i+1}/{len(servers)}: {server['cmd']}\")\n\n            # Use shell=True to support commands with cd and &&\n            process = subprocess.Popen(\n                server['cmd'],\n                shell=True,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE\n            )\n            server_processes.append(process)\n\n            # Wait for this server to be ready\n            print(f\"Waiting for server on port {server['port']}...\")\n            if not is_server_ready(server['port'], timeout=args.timeout):\n                raise RuntimeError(f\"Server failed to start on port {server['port']} within {args.timeout}s\")\n\n            print(f\"Server ready on port {server['port']}\")\n\n        print(f\"\\nAll {len(servers)} server(s) ready\")\n\n        # Run the command\n        print(f\"Running: {' '.join(args.command)}\\n\")\n        result = subprocess.run(args.command)\n        sys.exit(result.returncode)\n\n    finally:\n        # Clean up all servers\n        print(f\"\\nStopping {len(server_processes)} server(s)...\")\n        for i, process in enumerate(server_processes):\n            try:\n                process.terminate()\n                process.wait(timeout=5)\n            except subprocess.TimeoutExpired:\n                process.kill()\n                process.wait()\n            print(f\"Server {i+1} stopped\")\n        print(\"All servers stopped\")\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "skills/xlsx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "skills/xlsx/SKILL.md",
    "content": "---\nname: xlsx\ndescription: \"Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like \\\"the xlsx in my downloads\\\") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# Requirements for Outputs\n\n## All Excel files\n\n### Professional Font\n- Use a consistent, professional font (e.g., Arial, Times New Roman) for all deliverables unless otherwise instructed by the user\n\n### Zero Formula Errors\n- Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)\n\n### Preserve Existing Templates (when updating templates)\n- Study and EXACTLY match existing format, style, and conventions when modifying files\n- Never impose standardized formatting on files with established patterns\n- Existing template conventions ALWAYS override these guidelines\n\n## Financial models\n\n### Color Coding Standards\nUnless otherwise stated by the user or existing template\n\n#### Industry-Standard Color Conventions\n- **Blue text (RGB: 0,0,255)**: Hardcoded inputs, and numbers users will change for scenarios\n- **Black text (RGB: 0,0,0)**: ALL formulas and calculations\n- **Green text (RGB: 0,128,0)**: Links pulling from other worksheets within same workbook\n- **Red text (RGB: 255,0,0)**: External links to other files\n- **Yellow background (RGB: 255,255,0)**: Key assumptions needing attention or cells that need to be updated\n\n### Number Formatting Standards\n\n#### Required Format Rules\n- **Years**: Format as text strings (e.g., \"2024\" not \"2,024\")\n- **Currency**: Use $#,##0 format; ALWAYS specify units in headers (\"Revenue ($mm)\")\n- **Zeros**: Use number formatting to make all zeros \"-\", including percentages (e.g., \"$#,##0;($#,##0);-\")\n- **Percentages**: Default to 0.0% format (one decimal)\n- **Multiples**: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)\n- **Negative numbers**: Use parentheses (123) not minus -123\n\n### Formula Construction Rules\n\n#### Assumptions Placement\n- Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells\n- Use cell references instead of hardcoded values in formulas\n- Example: Use =B5*(1+$B$6) instead of =B5*1.05\n\n#### Formula Error Prevention\n- Verify all cell references are correct\n- Check for off-by-one errors in ranges\n- Ensure consistent formulas across all projection periods\n- Test with edge cases (zero values, negative numbers)\n- Verify no unintended circular references\n\n#### Documentation Requirements for Hardcodes\n- Comment or in cells beside (if end of table). Format: \"Source: [System/Document], [Date], [Specific Reference], [URL if applicable]\"\n- Examples:\n  - \"Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]\"\n  - \"Source: Company 10-Q, Q2 2025, Exhibit 99.1, [SEC EDGAR URL]\"\n  - \"Source: Bloomberg Terminal, 8/15/2025, AAPL US Equity\"\n  - \"Source: FactSet, 8/20/2025, Consensus Estimates Screen\"\n\n# XLSX creation, editing, and analysis\n\n## Overview\n\nA user may ask you to create, edit, or analyze the contents of an .xlsx file. You have different tools and workflows available for different tasks.\n\n## Important Requirements\n\n**LibreOffice Required for Formula Recalculation**: You can assume LibreOffice is installed for recalculating formula values using the `scripts/recalc.py` script. The script automatically configures LibreOffice on first run, including in sandboxed environments where Unix sockets are restricted (handled by `scripts/office/soffice.py`)\n\n## Reading and analyzing data\n\n### Data analysis with pandas\nFor data analysis, visualization, and basic operations, use **pandas** which provides powerful data manipulation capabilities:\n\n```python\nimport pandas as pd\n\n# Read Excel\ndf = pd.read_excel('file.xlsx')  # Default: first sheet\nall_sheets = pd.read_excel('file.xlsx', sheet_name=None)  # All sheets as dict\n\n# Analyze\ndf.head()      # Preview data\ndf.info()      # Column info\ndf.describe()  # Statistics\n\n# Write Excel\ndf.to_excel('output.xlsx', index=False)\n```\n\n## Excel File Workflows\n\n## CRITICAL: Use Formulas, Not Hardcoded Values\n\n**Always use Excel formulas instead of calculating values in Python and hardcoding them.** This ensures the spreadsheet remains dynamic and updateable.\n\n### ❌ WRONG - Hardcoding Calculated Values\n```python\n# Bad: Calculating in Python and hardcoding result\ntotal = df['Sales'].sum()\nsheet['B10'] = total  # Hardcodes 5000\n\n# Bad: Computing growth rate in Python\ngrowth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']\nsheet['C5'] = growth  # Hardcodes 0.15\n\n# Bad: Python calculation for average\navg = sum(values) / len(values)\nsheet['D20'] = avg  # Hardcodes 42.5\n```\n\n### ✅ CORRECT - Using Excel Formulas\n```python\n# Good: Let Excel calculate the sum\nsheet['B10'] = '=SUM(B2:B9)'\n\n# Good: Growth rate as Excel formula\nsheet['C5'] = '=(C4-C2)/C2'\n\n# Good: Average using Excel function\nsheet['D20'] = '=AVERAGE(D2:D19)'\n```\n\nThis applies to ALL calculations - totals, percentages, ratios, differences, etc. The spreadsheet should be able to recalculate when source data changes.\n\n## Common Workflow\n1. **Choose tool**: pandas for data, openpyxl for formulas/formatting\n2. **Create/Load**: Create new workbook or load existing file\n3. **Modify**: Add/edit data, formulas, and formatting\n4. **Save**: Write to file\n5. **Recalculate formulas (MANDATORY IF USING FORMULAS)**: Use the scripts/recalc.py script\n   ```bash\n   python scripts/recalc.py output.xlsx\n   ```\n6. **Verify and fix any errors**: \n   - The script returns JSON with error details\n   - If `status` is `errors_found`, check `error_summary` for specific error types and locations\n   - Fix the identified errors and recalculate again\n   - Common errors to fix:\n     - `#REF!`: Invalid cell references\n     - `#DIV/0!`: Division by zero\n     - `#VALUE!`: Wrong data type in formula\n     - `#NAME?`: Unrecognized formula name\n\n### Creating new Excel files\n\n```python\n# Using openpyxl for formulas and formatting\nfrom openpyxl import Workbook\nfrom openpyxl.styles import Font, PatternFill, Alignment\n\nwb = Workbook()\nsheet = wb.active\n\n# Add data\nsheet['A1'] = 'Hello'\nsheet['B1'] = 'World'\nsheet.append(['Row', 'of', 'data'])\n\n# Add formula\nsheet['B2'] = '=SUM(A1:A10)'\n\n# Formatting\nsheet['A1'].font = Font(bold=True, color='FF0000')\nsheet['A1'].fill = PatternFill('solid', start_color='FFFF00')\nsheet['A1'].alignment = Alignment(horizontal='center')\n\n# Column width\nsheet.column_dimensions['A'].width = 20\n\nwb.save('output.xlsx')\n```\n\n### Editing existing Excel files\n\n```python\n# Using openpyxl to preserve formulas and formatting\nfrom openpyxl import load_workbook\n\n# Load existing file\nwb = load_workbook('existing.xlsx')\nsheet = wb.active  # or wb['SheetName'] for specific sheet\n\n# Working with multiple sheets\nfor sheet_name in wb.sheetnames:\n    sheet = wb[sheet_name]\n    print(f\"Sheet: {sheet_name}\")\n\n# Modify cells\nsheet['A1'] = 'New Value'\nsheet.insert_rows(2)  # Insert row at position 2\nsheet.delete_cols(3)  # Delete column 3\n\n# Add new sheet\nnew_sheet = wb.create_sheet('NewSheet')\nnew_sheet['A1'] = 'Data'\n\nwb.save('modified.xlsx')\n```\n\n## Recalculating formulas\n\nExcel files created or modified by openpyxl contain formulas as strings but not calculated values. Use the provided `scripts/recalc.py` script to recalculate formulas:\n\n```bash\npython scripts/recalc.py <excel_file> [timeout_seconds]\n```\n\nExample:\n```bash\npython scripts/recalc.py output.xlsx 30\n```\n\nThe script:\n- Automatically sets up LibreOffice macro on first run\n- Recalculates all formulas in all sheets\n- Scans ALL cells for Excel errors (#REF!, #DIV/0!, etc.)\n- Returns JSON with detailed error locations and counts\n- Works on both Linux and macOS\n\n## Formula Verification Checklist\n\nQuick checks to ensure formulas work correctly:\n\n### Essential Verification\n- [ ] **Test 2-3 sample references**: Verify they pull correct values before building full model\n- [ ] **Column mapping**: Confirm Excel columns match (e.g., column 64 = BL, not BK)\n- [ ] **Row offset**: Remember Excel rows are 1-indexed (DataFrame row 5 = Excel row 6)\n\n### Common Pitfalls\n- [ ] **NaN handling**: Check for null values with `pd.notna()`\n- [ ] **Far-right columns**: FY data often in columns 50+ \n- [ ] **Multiple matches**: Search all occurrences, not just first\n- [ ] **Division by zero**: Check denominators before using `/` in formulas (#DIV/0!)\n- [ ] **Wrong references**: Verify all cell references point to intended cells (#REF!)\n- [ ] **Cross-sheet references**: Use correct format (Sheet1!A1) for linking sheets\n\n### Formula Testing Strategy\n- [ ] **Start small**: Test formulas on 2-3 cells before applying broadly\n- [ ] **Verify dependencies**: Check all cells referenced in formulas exist\n- [ ] **Test edge cases**: Include zero, negative, and very large values\n\n### Interpreting scripts/recalc.py Output\nThe script returns JSON with error details:\n```json\n{\n  \"status\": \"success\",           // or \"errors_found\"\n  \"total_errors\": 0,              // Total error count\n  \"total_formulas\": 42,           // Number of formulas in file\n  \"error_summary\": {              // Only present if errors found\n    \"#REF!\": {\n      \"count\": 2,\n      \"locations\": [\"Sheet1!B5\", \"Sheet1!C10\"]\n    }\n  }\n}\n```\n\n## Best Practices\n\n### Library Selection\n- **pandas**: Best for data analysis, bulk operations, and simple data export\n- **openpyxl**: Best for complex formatting, formulas, and Excel-specific features\n\n### Working with openpyxl\n- Cell indices are 1-based (row=1, column=1 refers to cell A1)\n- Use `data_only=True` to read calculated values: `load_workbook('file.xlsx', data_only=True)`\n- **Warning**: If opened with `data_only=True` and saved, formulas are replaced with values and permanently lost\n- For large files: Use `read_only=True` for reading or `write_only=True` for writing\n- Formulas are preserved but not evaluated - use scripts/recalc.py to update values\n\n### Working with pandas\n- Specify data types to avoid inference issues: `pd.read_excel('file.xlsx', dtype={'id': str})`\n- For large files, read specific columns: `pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])`\n- Handle dates properly: `pd.read_excel('file.xlsx', parse_dates=['date_column'])`\n\n## Code Style Guidelines\n**IMPORTANT**: When generating Python code for Excel operations:\n- Write minimal, concise Python code without unnecessary comments\n- Avoid verbose variable names and redundant operations\n- Avoid unnecessary print statements\n\n**For Excel files themselves**:\n- Add comments to cells with complex formulas or important assumptions\n- Document data sources for hardcoded values\n- Include notes for key calculations and model sections"
  },
  {
    "path": "skills/xlsx/scripts/office/helpers/__init__.py",
    "content": ""
  },
  {
    "path": "skills/xlsx/scripts/office/helpers/merge_runs.py",
    "content": "\"\"\"Merge adjacent runs with identical formatting in DOCX.\n\nMerges adjacent <w:r> elements that have identical <w:rPr> properties.\nWorks on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).\n\nAlso:\n- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)\n- Removes proofErr elements (spell/grammar markers that block merging)\n\"\"\"\n\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\n\ndef merge_runs(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        _remove_elements(root, \"proofErr\")\n        _strip_run_rsid_attrs(root)\n\n        containers = {run.parentNode for run in _find_elements(root, \"r\")}\n\n        merge_count = 0\n        for container in containers:\n            merge_count += _merge_runs_in(container)\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Merged {merge_count} runs\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef _get_child(parent, tag: str):\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                return child\n    return None\n\n\ndef _get_children(parent, tag: str) -> list:\n    results = []\n    for child in parent.childNodes:\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(child)\n    return results\n\n\ndef _is_adjacent(elem1, elem2) -> bool:\n    node = elem1.nextSibling\n    while node:\n        if node == elem2:\n            return True\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n    return False\n\n\n\n\ndef _remove_elements(root, tag: str):\n    for elem in _find_elements(root, tag):\n        if elem.parentNode:\n            elem.parentNode.removeChild(elem)\n\n\ndef _strip_run_rsid_attrs(root):\n    for run in _find_elements(root, \"r\"):\n        for attr in list(run.attributes.values()):\n            if \"rsid\" in attr.name.lower():\n                run.removeAttribute(attr.name)\n\n\n\n\ndef _merge_runs_in(container) -> int:\n    merge_count = 0\n    run = _first_child_run(container)\n\n    while run:\n        while True:\n            next_elem = _next_element_sibling(run)\n            if next_elem and _is_run(next_elem) and _can_merge(run, next_elem):\n                _merge_run_content(run, next_elem)\n                container.removeChild(next_elem)\n                merge_count += 1\n            else:\n                break\n\n        _consolidate_text(run)\n        run = _next_sibling_run(run)\n\n    return merge_count\n\n\ndef _first_child_run(container):\n    for child in container.childNodes:\n        if child.nodeType == child.ELEMENT_NODE and _is_run(child):\n            return child\n    return None\n\n\ndef _next_element_sibling(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _next_sibling_run(node):\n    sibling = node.nextSibling\n    while sibling:\n        if sibling.nodeType == sibling.ELEMENT_NODE:\n            if _is_run(sibling):\n                return sibling\n        sibling = sibling.nextSibling\n    return None\n\n\ndef _is_run(node) -> bool:\n    name = node.localName or node.tagName\n    return name == \"r\" or name.endswith(\":r\")\n\n\ndef _can_merge(run1, run2) -> bool:\n    rpr1 = _get_child(run1, \"rPr\")\n    rpr2 = _get_child(run2, \"rPr\")\n\n    if (rpr1 is None) != (rpr2 is None):\n        return False\n    if rpr1 is None:\n        return True\n    return rpr1.toxml() == rpr2.toxml()  \n\n\ndef _merge_run_content(target, source):\n    for child in list(source.childNodes):\n        if child.nodeType == child.ELEMENT_NODE:\n            name = child.localName or child.tagName\n            if name != \"rPr\" and not name.endswith(\":rPr\"):\n                target.appendChild(child)\n\n\ndef _consolidate_text(run):\n    t_elements = _get_children(run, \"t\")\n\n    for i in range(len(t_elements) - 1, 0, -1):\n        curr, prev = t_elements[i], t_elements[i - 1]\n\n        if _is_adjacent(prev, curr):\n            prev_text = prev.firstChild.data if prev.firstChild else \"\"\n            curr_text = curr.firstChild.data if curr.firstChild else \"\"\n            merged = prev_text + curr_text\n\n            if prev.firstChild:\n                prev.firstChild.data = merged\n            else:\n                prev.appendChild(run.ownerDocument.createTextNode(merged))\n\n            if merged.startswith(\" \") or merged.endswith(\" \"):\n                prev.setAttribute(\"xml:space\", \"preserve\")\n            elif prev.hasAttribute(\"xml:space\"):\n                prev.removeAttribute(\"xml:space\")\n\n            run.removeChild(curr)\n"
  },
  {
    "path": "skills/xlsx/scripts/office/helpers/simplify_redlines.py",
    "content": "\"\"\"Simplify tracked changes by merging adjacent w:ins or w:del elements.\n\nMerges adjacent <w:ins> elements from the same author into a single element.\nSame for <w:del> elements. This makes heavily-redlined documents easier to\nwork with by reducing the number of tracked change wrappers.\n\nRules:\n- Only merges w:ins with w:ins, w:del with w:del (same element type)\n- Only merges if same author (ignores timestamp differences)\n- Only merges if truly adjacent (only whitespace between them)\n\"\"\"\n\nimport xml.etree.ElementTree as ET\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nWORD_NS = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\n\ndef simplify_redlines(input_dir: str) -> tuple[int, str]:\n    doc_xml = Path(input_dir) / \"word\" / \"document.xml\"\n\n    if not doc_xml.exists():\n        return 0, f\"Error: {doc_xml} not found\"\n\n    try:\n        dom = defusedxml.minidom.parseString(doc_xml.read_text(encoding=\"utf-8\"))\n        root = dom.documentElement\n\n        merge_count = 0\n\n        containers = _find_elements(root, \"p\") + _find_elements(root, \"tc\")\n\n        for container in containers:\n            merge_count += _merge_tracked_changes_in(container, \"ins\")\n            merge_count += _merge_tracked_changes_in(container, \"del\")\n\n        doc_xml.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n        return merge_count, f\"Simplified {merge_count} tracked changes\"\n\n    except Exception as e:\n        return 0, f\"Error: {e}\"\n\n\ndef _merge_tracked_changes_in(container, tag: str) -> int:\n    merge_count = 0\n\n    tracked = [\n        child\n        for child in container.childNodes\n        if child.nodeType == child.ELEMENT_NODE and _is_element(child, tag)\n    ]\n\n    if len(tracked) < 2:\n        return 0\n\n    i = 0\n    while i < len(tracked) - 1:\n        curr = tracked[i]\n        next_elem = tracked[i + 1]\n\n        if _can_merge_tracked(curr, next_elem):\n            _merge_tracked_content(curr, next_elem)\n            container.removeChild(next_elem)\n            tracked.pop(i + 1)\n            merge_count += 1\n        else:\n            i += 1\n\n    return merge_count\n\n\ndef _is_element(node, tag: str) -> bool:\n    name = node.localName or node.tagName\n    return name == tag or name.endswith(f\":{tag}\")\n\n\ndef _get_author(elem) -> str:\n    author = elem.getAttribute(\"w:author\")\n    if not author:\n        for attr in elem.attributes.values():\n            if attr.localName == \"author\" or attr.name.endswith(\":author\"):\n                return attr.value\n    return author\n\n\ndef _can_merge_tracked(elem1, elem2) -> bool:\n    if _get_author(elem1) != _get_author(elem2):\n        return False\n\n    node = elem1.nextSibling\n    while node and node != elem2:\n        if node.nodeType == node.ELEMENT_NODE:\n            return False\n        if node.nodeType == node.TEXT_NODE and node.data.strip():\n            return False\n        node = node.nextSibling\n\n    return True\n\n\ndef _merge_tracked_content(target, source):\n    while source.firstChild:\n        child = source.firstChild\n        source.removeChild(child)\n        target.appendChild(child)\n\n\ndef _find_elements(root, tag: str) -> list:\n    results = []\n\n    def traverse(node):\n        if node.nodeType == node.ELEMENT_NODE:\n            name = node.localName or node.tagName\n            if name == tag or name.endswith(f\":{tag}\"):\n                results.append(node)\n            for child in node.childNodes:\n                traverse(child)\n\n    traverse(root)\n    return results\n\n\ndef get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]:\n    if not doc_xml_path.exists():\n        return {}\n\n    try:\n        tree = ET.parse(doc_xml_path)\n        root = tree.getroot()\n    except ET.ParseError:\n        return {}\n\n    namespaces = {\"w\": WORD_NS}\n    author_attr = f\"{{{WORD_NS}}}author\"\n\n    authors: dict[str, int] = {}\n    for tag in [\"ins\", \"del\"]:\n        for elem in root.findall(f\".//w:{tag}\", namespaces):\n            author = elem.get(author_attr)\n            if author:\n                authors[author] = authors.get(author, 0) + 1\n\n    return authors\n\n\ndef _get_authors_from_docx(docx_path: Path) -> dict[str, int]:\n    try:\n        with zipfile.ZipFile(docx_path, \"r\") as zf:\n            if \"word/document.xml\" not in zf.namelist():\n                return {}\n            with zf.open(\"word/document.xml\") as f:\n                tree = ET.parse(f)\n                root = tree.getroot()\n\n                namespaces = {\"w\": WORD_NS}\n                author_attr = f\"{{{WORD_NS}}}author\"\n\n                authors: dict[str, int] = {}\n                for tag in [\"ins\", \"del\"]:\n                    for elem in root.findall(f\".//w:{tag}\", namespaces):\n                        author = elem.get(author_attr)\n                        if author:\n                            authors[author] = authors.get(author, 0) + 1\n                return authors\n    except (zipfile.BadZipFile, ET.ParseError):\n        return {}\n\n\ndef infer_author(modified_dir: Path, original_docx: Path, default: str = \"Claude\") -> str:\n    modified_xml = modified_dir / \"word\" / \"document.xml\"\n    modified_authors = get_tracked_change_authors(modified_xml)\n\n    if not modified_authors:\n        return default\n\n    original_authors = _get_authors_from_docx(original_docx)\n\n    new_changes: dict[str, int] = {}\n    for author, count in modified_authors.items():\n        original_count = original_authors.get(author, 0)\n        diff = count - original_count\n        if diff > 0:\n            new_changes[author] = diff\n\n    if not new_changes:\n        return default\n\n    if len(new_changes) == 1:\n        return next(iter(new_changes))\n\n    raise ValueError(\n        f\"Multiple authors added new changes: {new_changes}. \"\n        \"Cannot infer which author to validate.\"\n    )\n"
  },
  {
    "path": "skills/xlsx/scripts/office/pack.py",
    "content": "\"\"\"Pack a directory into a DOCX, PPTX, or XLSX file.\n\nValidates with auto-repair, condenses XML formatting, and creates the Office file.\n\nUsage:\n    python pack.py <input_directory> <output_file> [--original <file>] [--validate true|false]\n\nExamples:\n    python pack.py unpacked/ output.docx --original input.docx\n    python pack.py unpacked/ output.pptx --validate false\n\"\"\"\n\nimport argparse\nimport sys\nimport shutil\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\ndef pack(\n    input_directory: str,\n    output_file: str,\n    original_file: str | None = None,\n    validate: bool = True,\n    infer_author_func=None,\n) -> tuple[None, str]:\n    input_dir = Path(input_directory)\n    output_path = Path(output_file)\n    suffix = output_path.suffix.lower()\n\n    if not input_dir.is_dir():\n        return None, f\"Error: {input_dir} is not a directory\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {output_file} must be a .docx, .pptx, or .xlsx file\"\n\n    if validate and original_file:\n        original_path = Path(original_file)\n        if original_path.exists():\n            success, output = _run_validation(\n                input_dir, original_path, suffix, infer_author_func\n            )\n            if output:\n                print(output)\n            if not success:\n                return None, f\"Error: Validation failed for {input_dir}\"\n\n    with tempfile.TemporaryDirectory() as temp_dir:\n        temp_content_dir = Path(temp_dir) / \"content\"\n        shutil.copytree(input_dir, temp_content_dir)\n\n        for pattern in [\"*.xml\", \"*.rels\"]:\n            for xml_file in temp_content_dir.rglob(pattern):\n                _condense_xml(xml_file)\n\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n            for f in temp_content_dir.rglob(\"*\"):\n                if f.is_file():\n                    zf.write(f, f.relative_to(temp_content_dir))\n\n    return None, f\"Successfully packed {input_dir} to {output_file}\"\n\n\ndef _run_validation(\n    unpacked_dir: Path,\n    original_file: Path,\n    suffix: str,\n    infer_author_func=None,\n) -> tuple[bool, str | None]:\n    output_lines = []\n    validators = []\n\n    if suffix == \".docx\":\n        author = \"Claude\"\n        if infer_author_func:\n            try:\n                author = infer_author_func(unpacked_dir, original_file)\n            except ValueError as e:\n                print(f\"Warning: {e} Using default author 'Claude'.\", file=sys.stderr)\n\n        validators = [\n            DOCXSchemaValidator(unpacked_dir, original_file),\n            RedliningValidator(unpacked_dir, original_file, author=author),\n        ]\n    elif suffix == \".pptx\":\n        validators = [PPTXSchemaValidator(unpacked_dir, original_file)]\n\n    if not validators:\n        return True, None\n\n    total_repairs = sum(v.repair() for v in validators)\n    if total_repairs:\n        output_lines.append(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        output_lines.append(\"All validations PASSED!\")\n\n    return success, \"\\n\".join(output_lines) if output_lines else None\n\n\ndef _condense_xml(xml_file: Path) -> None:\n    try:\n        with open(xml_file, encoding=\"utf-8\") as f:\n            dom = defusedxml.minidom.parse(f)\n\n        for element in dom.getElementsByTagName(\"*\"):\n            if element.tagName.endswith(\":t\"):\n                continue\n\n            for child in list(element.childNodes):\n                if (\n                    child.nodeType == child.TEXT_NODE\n                    and child.nodeValue\n                    and child.nodeValue.strip() == \"\"\n                ) or child.nodeType == child.COMMENT_NODE:\n                    element.removeChild(child)\n\n        xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n    except Exception as e:\n        print(f\"ERROR: Failed to parse {xml_file.name}: {e}\", file=sys.stderr)\n        raise\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Pack a directory into a DOCX, PPTX, or XLSX file\"\n    )\n    parser.add_argument(\"input_directory\", help=\"Unpacked Office document directory\")\n    parser.add_argument(\"output_file\", help=\"Output Office file (.docx/.pptx/.xlsx)\")\n    parser.add_argument(\n        \"--original\",\n        help=\"Original file for validation comparison\",\n    )\n    parser.add_argument(\n        \"--validate\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Run validation with auto-repair (default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = pack(\n        args.input_directory,\n        args.output_file,\n        original_file=args.original,\n        validate=args.validate,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  xmlns:cdr=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n    schemaLocation=\"dml-chartDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Double\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedInt\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumData\">\n    <xsd:sequence>\n      <xsd:element name=\"formatCode\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_NumVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numCache\" type=\"CT_NumData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strCache\" type=\"CT_StrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"rich\" type=\"a:CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLanguageID\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"multiLvlStrCache\" type=\"CT_MultiLvlStrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AxDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"multiLvlStrRef\" type=\"CT_MultiLvlStrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strLit\" type=\"CT_StrData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerTx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutTarget\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inner\"/>\n      <xsd:enumeration value=\"outer\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutTarget\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutTarget\" default=\"outer\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"edge\"/>\n      <xsd:enumeration value=\"factor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutMode\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutMode\" default=\"factor\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualLayout\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutTarget\" type=\"CT_LayoutTarget\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"x\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"w\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"h\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Layout\">\n    <xsd:sequence>\n      <xsd:element name=\"manualLayout\" type=\"CT_ManualLayout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Title\">\n    <xsd:sequence>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotX\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-90\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotX\">\n    <xsd:attribute name=\"val\" type=\"ST_RotX\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HPercent\">\n    <xsd:union memberTypes=\"ST_HPercentWithSymbol ST_HPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_HPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotY\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotY\">\n    <xsd:attribute name=\"val\" type=\"ST_RotY\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DepthPercent\">\n    <xsd:union memberTypes=\"ST_DepthPercentWithSymbol ST_DepthPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"20\"/>\n      <xsd:maxInclusive value=\"2000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DepthPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_DepthPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Perspective\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"240\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perspective\">\n    <xsd:attribute name=\"val\" type=\"ST_Perspective\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_View3D\">\n    <xsd:sequence>\n      <xsd:element name=\"rotX\" type=\"CT_RotX\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hPercent\" type=\"CT_HPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rotY\" type=\"CT_RotY\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"depthPercent\" type=\"CT_DepthPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rAngAx\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"perspective\" type=\"CT_Perspective\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface\">\n    <xsd:sequence>\n      <xsd:element name=\"thickness\" type=\"CT_Thickness\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Thickness\">\n    <xsd:union memberTypes=\"ST_ThicknessPercent xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ThicknessPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"([0-9]+)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Thickness\">\n    <xsd:attribute name=\"val\" type=\"ST_Thickness\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DTable\">\n    <xsd:sequence>\n      <xsd:element name=\"showHorzBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVertBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showOutline\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showKeys\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GapAmount\">\n    <xsd:union memberTypes=\"ST_GapAmountPercent ST_GapAmountUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GapAmount\">\n    <xsd:attribute name=\"val\" type=\"ST_GapAmount\" default=\"150%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Overlap\">\n    <xsd:union memberTypes=\"ST_OverlapPercent ST_OverlapByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"(-?0*(([0-9])|([1-9][0-9])|100))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapByte\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-100\"/>\n      <xsd:maxInclusive value=\"100\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Overlap\">\n    <xsd:attribute name=\"val\" type=\"ST_Overlap\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BubbleScale\">\n    <xsd:union memberTypes=\"ST_BubbleScalePercent ST_BubbleScaleUInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-2][0-9][0-9])|300)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScaleUInt\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"300\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BubbleScale\">\n    <xsd:attribute name=\"val\" type=\"ST_BubbleScale\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SizeRepresents\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"w\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SizeRepresents\">\n    <xsd:attribute name=\"val\" type=\"ST_SizeRepresents\" default=\"area\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FirstSliceAng\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FirstSliceAng\">\n    <xsd:attribute name=\"val\" type=\"ST_FirstSliceAng\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HoleSize\">\n    <xsd:union memberTypes=\"ST_HoleSizePercent ST_HoleSizeUByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*([1-9]|([1-8][0-9])|90)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizeUByte\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HoleSize\">\n    <xsd:attribute name=\"val\" type=\"ST_HoleSize\" default=\"10%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SplitType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"val\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SplitType\">\n    <xsd:attribute name=\"val\" type=\"ST_SplitType\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustSplit\">\n    <xsd:sequence>\n      <xsd:element name=\"secondPiePt\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SecondPieSize\">\n    <xsd:union memberTypes=\"ST_SecondPieSizePercent ST_SecondPieSizeUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|(1[0-9][0-9])|200)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizeUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SecondPieSize\">\n    <xsd:attribute name=\"val\" type=\"ST_SecondPieSize\" default=\"75%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceLinked\" type=\"xsd:boolean\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblAlgn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblAlgn\">\n    <xsd:attribute name=\"val\" type=\"ST_LblAlgn\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"inBase\"/>\n      <xsd:enumeration value=\"inEnd\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"outEnd\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_DLblPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_DLblShared\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLblPos\" type=\"CT_DLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLegendKey\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVal\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showCatName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showSerName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPercent\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showBubbleSize\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"separator\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"Group_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbl\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"Group_DLbls\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLeaderLines\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"leaderLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbls\">\n    <xsd:sequence>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbls\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"picture\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"star\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerStyle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerSize\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"72\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerSize\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerSize\" default=\"5\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"symbol\" type=\"CT_MarkerStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"size\" type=\"CT_MarkerSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TrendlineType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"exp\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"log\"/>\n      <xsd:enumeration value=\"movingAvg\"/>\n      <xsd:enumeration value=\"poly\"/>\n      <xsd:enumeration value=\"power\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TrendlineType\">\n    <xsd:attribute name=\"val\" type=\"ST_TrendlineType\" default=\"linear\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Order\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"6\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Order\">\n    <xsd:attribute name=\"val\" type=\"ST_Order\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Period\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Period\">\n    <xsd:attribute name=\"val\" type=\"ST_Period\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrendlineLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Trendline\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineType\" type=\"CT_TrendlineType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_Order\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"period\" type=\"CT_Period\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"intercept\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispRSqr\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispEq\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineLbl\" type=\"CT_TrendlineLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrDir\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrDir\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrBarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"minus\"/>\n      <xsd:enumeration value=\"plus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrBarType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrBarType\" default=\"both\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrValType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"fixedVal\"/>\n      <xsd:enumeration value=\"percentage\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdErr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrValType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrValType\" default=\"fixedVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ErrBars\">\n    <xsd:sequence>\n      <xsd:element name=\"errDir\" type=\"CT_ErrDir\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errBarType\" type=\"CT_ErrBarType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errValType\" type=\"CT_ErrValType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noEndCap\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBar\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBars\">\n    <xsd:sequence>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"downBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SerShared\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_SerTx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AreaSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PieSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleSize\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SurfaceSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Grouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Grouping\">\n    <xsd:attribute name=\"val\" type=\"ST_Grouping\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartLines\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StockChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"3\" maxOccurs=\"4\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ScatterStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineMarker\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"smooth\"/>\n      <xsd:enumeration value=\"smoothMarker\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ScatterStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_ScatterStyle\" default=\"marker\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterChart\">\n    <xsd:sequence>\n      <xsd:element name=\"scatterStyle\" type=\"CT_ScatterStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_ScatterSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RadarStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"filled\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RadarStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_RadarStyle\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarChart\">\n    <xsd:sequence>\n      <xsd:element name=\"radarStyle\" type=\"CT_RadarStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_RadarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"clustered\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarGrouping\">\n    <xsd:attribute name=\"val\" type=\"ST_BarGrouping\" default=\"clustered\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarDir\">\n    <xsd:attribute name=\"val\" type=\"ST_BarDir\" default=\"col\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shape\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cone\"/>\n      <xsd:enumeration value=\"coneToMax\"/>\n      <xsd:enumeration value=\"box\"/>\n      <xsd:enumeration value=\"cylinder\"/>\n      <xsd:enumeration value=\"pyramid\"/>\n      <xsd:enumeration value=\"pyramidToMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:attribute name=\"val\" type=\"ST_Shape\" default=\"box\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_BarChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"barDir\" type=\"CT_BarDir\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grouping\" type=\"CT_BarGrouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_BarChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlap\" type=\"CT_Overlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AreaChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_AreaSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AreaChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Area3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PieChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_PieSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_PieChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pie3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DoughnutChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"holeSize\" type=\"CT_HoleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_OfPieType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"bar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OfPieType\">\n    <xsd:attribute name=\"val\" type=\"ST_OfPieType\" default=\"pie\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfPieChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ofPieType\" type=\"CT_OfPieType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitType\" type=\"CT_SplitType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitPos\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custSplit\" type=\"CT_CustSplit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"secondPieSize\" type=\"CT_SecondPieSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleChart\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BubbleSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleScale\" type=\"CT_BubbleScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showNegBubbles\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sizeRepresents\" type=\"CT_SizeRepresents\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"bandFmt\" type=\"CT_BandFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SurfaceChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"wireframe\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_SurfaceSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"bandFmts\" type=\"CT_BandFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SurfaceChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxPos\">\n    <xsd:attribute name=\"val\" type=\"ST_AxPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Crosses\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"autoZero\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Crosses\">\n    <xsd:attribute name=\"val\" type=\"ST_Crosses\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CrossBetween\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"midCat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CrossBetween\">\n    <xsd:attribute name=\"val\" type=\"ST_CrossBetween\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"out\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickMark\">\n    <xsd:attribute name=\"val\" type=\"ST_TickMark\" default=\"cross\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"high\"/>\n      <xsd:enumeration value=\"low\"/>\n      <xsd:enumeration value=\"nextTo\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_TickLblPos\" default=\"nextTo\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Skip\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Skip\">\n    <xsd:attribute name=\"val\" type=\"ST_Skip\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TimeUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TimeUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_TimeUnit\" default=\"days\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxisUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxisUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_AxisUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BuiltInUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hundreds\"/>\n      <xsd:enumeration value=\"thousands\"/>\n      <xsd:enumeration value=\"tenThousands\"/>\n      <xsd:enumeration value=\"hundredThousands\"/>\n      <xsd:enumeration value=\"millions\"/>\n      <xsd:enumeration value=\"tenMillions\"/>\n      <xsd:enumeration value=\"hundredMillions\"/>\n      <xsd:enumeration value=\"billions\"/>\n      <xsd:enumeration value=\"trillions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BuiltInUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_BuiltInUnit\" default=\"thousands\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stretch\"/>\n      <xsd:enumeration value=\"stack\"/>\n      <xsd:enumeration value=\"stackScale\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureFormat\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureFormat\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureStackUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureStackUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureStackUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureOptions\">\n    <xsd:sequence>\n      <xsd:element name=\"applyToFront\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToSides\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToEnd\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureFormat\" type=\"CT_PictureFormat\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureStackUnit\" type=\"CT_PictureStackUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnitsLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnits\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"custUnit\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"builtInUnit\" type=\"CT_BuiltInUnit\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dispUnitsLbl\" type=\"CT_DispUnitsLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"maxMin\"/>\n      <xsd:enumeration value=\"minMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Orientation\">\n    <xsd:attribute name=\"val\" type=\"ST_Orientation\" default=\"minMax\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LogBase\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LogBase\">\n    <xsd:attribute name=\"val\" type=\"ST_LogBase\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scaling\">\n    <xsd:sequence>\n      <xsd:element name=\"logBase\" type=\"CT_LogBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"orientation\" type=\"CT_Orientation\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"max\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"min\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblOffset\">\n    <xsd:union memberTypes=\"ST_LblOffsetPercent ST_LblOffsetUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblOffset\">\n    <xsd:attribute name=\"val\" type=\"ST_LblOffset\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AxShared\">\n    <xsd:sequence>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scaling\" type=\"CT_Scaling\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axPos\" type=\"CT_AxPos\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblPos\" type=\"CT_TickLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossAx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"crosses\" type=\"CT_Crosses\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"crossesAt\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CatAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblAlgn\" type=\"CT_LblAlgn\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noMultiLvlLbl\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"baseTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ValAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossBetween\" type=\"CT_CrossBetween\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispUnits\" type=\"CT_DispUnits\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PlotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"areaChart\" type=\"CT_AreaChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"area3DChart\" type=\"CT_Area3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lineChart\" type=\"CT_LineChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"line3DChart\" type=\"CT_Line3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"stockChart\" type=\"CT_StockChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"radarChart\" type=\"CT_RadarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"scatterChart\" type=\"CT_ScatterChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pieChart\" type=\"CT_PieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pie3DChart\" type=\"CT_Pie3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"doughnutChart\" type=\"CT_DoughnutChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"barChart\" type=\"CT_BarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bar3DChart\" type=\"CT_Bar3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ofPieChart\" type=\"CT_OfPieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surfaceChart\" type=\"CT_SurfaceChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surface3DChart\" type=\"CT_Surface3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bubbleChart\" type=\"CT_BubbleChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"valAx\" type=\"CT_ValAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"catAx\" type=\"CT_CatAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"dateAx\" type=\"CT_DateAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"serAx\" type=\"CT_SerAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dTable\" type=\"CT_DTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotFmt\" type=\"CT_PivotFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LegendPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LegendPos\">\n    <xsd:attribute name=\"val\" type=\"ST_LegendPos\" default=\"r\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LegendEntryData\">\n    <xsd:sequence>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LegendEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"EG_LegendEntryData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Legend\">\n    <xsd:sequence>\n      <xsd:element name=\"legendPos\" type=\"CT_LegendPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legendEntry\" type=\"CT_LegendEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DispBlanksAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"gap\"/>\n      <xsd:enumeration value=\"zero\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DispBlanksAs\">\n    <xsd:attribute name=\"val\" type=\"ST_DispBlanksAs\" default=\"zero\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chart\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoTitleDeleted\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotFmts\" type=\"CT_PivotFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"view3D\" type=\"CT_View3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"floor\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sideWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotArea\" type=\"CT_PlotArea\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legend\" type=\"CT_Legend\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotVisOnly\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispBlanksAs\" type=\"CT_DispBlanksAs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showDLblsOverMax\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"48\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSource\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Protection\">\n    <xsd:sequence>\n      <xsd:element name=\"chartObject\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"data\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formatting\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userInterface\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"l\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageSetupOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ExternalData\">\n    <xsd:sequence>\n      <xsd:element name=\"autoUpdate\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_PageSetupOrientation\" use=\"optional\"\n      default=\"default\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartSpace\">\n    <xsd:sequence>\n      <xsd:element name=\"date1904\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lang\" type=\"CT_TextLanguageID\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"roundedCorners\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotSource\" type=\"CT_PivotSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_Protection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chart\" type=\"CT_Chart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalData\" type=\"CT_ExternalData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printSettings\" type=\"CT_PrintSettings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userShapes\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"chartSpace\" type=\"CT_ChartSpace\"/>\n  <xsd:element name=\"userShapes\" type=\"cdr:CT_Drawing\"/>\n  <xsd:element name=\"chart\" type=\"CT_RelId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_MarkerCoordinate\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"0.0\"/>\n      <xsd:maxInclusive value=\"1.0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"relSizeAnchor\" type=\"CT_RelSizeAnchor\"/>\n      <xsd:element name=\"absSizeAnchor\" type=\"CT_AbsSizeAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_CTName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_CTCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ClrAppMethod\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HueDir\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"meth\" type=\"ST_ClrAppMethod\" use=\"optional\" default=\"span\"/>\n    <xsd:attribute name=\"hueDir\" type=\"ST_HueDir\" use=\"optional\" default=\"cw\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTStyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"fillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"linClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txLinClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txFillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txEffectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorTransform\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_CTStyleLabel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDef\" type=\"CT_ColorTransform\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdrLst\" type=\"CT_ColorTransformHeaderLst\"/>\n  <xsd:simpleType name=\"ST_PtType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pt\">\n    <xsd:sequence>\n      <xsd:element name=\"prSet\" type=\"CT_ElemPropSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PtType\" use=\"optional\" default=\"node\"/>\n    <xsd:attribute name=\"cxnId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PtList\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_Pt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CxnType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parOf\"/>\n      <xsd:enumeration value=\"presOf\"/>\n      <xsd:enumeration value=\"presParOf\"/>\n      <xsd:enumeration value=\"unknownRelationship\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cxn\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_CxnType\" use=\"optional\" default=\"parOf\"/>\n    <xsd:attribute name=\"srcId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"destId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"srcOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"destOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"parTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sibTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"presId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CxnList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_Cxn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataModel\">\n    <xsd:sequence>\n      <xsd:element name=\"ptLst\" type=\"CT_PtList\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_CxnList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"dataModel\" type=\"CT_DataModel\"/>\n  <xsd:attributeGroup name=\"AG_IteratorAttributes\">\n    <xsd:attribute name=\"axis\" type=\"ST_AxisTypes\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementTypes\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"hideLastTrans\" type=\"ST_Booleans\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"st\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cnt\" type=\"ST_UnsignedInts\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"step\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintAttributes\">\n    <xsd:attribute name=\"type\" type=\"ST_ConstraintType\" use=\"required\"/>\n    <xsd:attribute name=\"for\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"forName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintRefAttributes\">\n    <xsd:attribute name=\"refType\" type=\"ST_ConstraintType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"refFor\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"refForName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"refPtType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_Constraint\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ConstraintRefAttributes\"/>\n    <xsd:attribute name=\"op\" type=\"ST_BoolOperator\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Constraints\">\n    <xsd:sequence>\n      <xsd:element name=\"constr\" type=\"CT_Constraint\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumericRule\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"rule\" type=\"CT_NumericRule\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationOf\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutShapeType\" final=\"restriction\">\n    <xsd:union memberTypes=\"a:ST_ShapeType ST_OutputShapeType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index1\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Adj\">\n    <xsd:attribute name=\"idx\" type=\"ST_Index1\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjLst\">\n    <xsd:sequence>\n      <xsd:element name=\"adj\" type=\"CT_Adj\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"adjLst\" type=\"CT_AdjLst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"type\" type=\"ST_LayoutShapeType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute ref=\"r:blip\" use=\"optional\"/>\n    <xsd:attribute name=\"zOrderOff\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hideGeom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lkTxEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"blipPhldr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"type\" type=\"ST_ParameterId\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ParameterVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Algorithm\">\n    <xsd:sequence>\n      <xsd:element name=\"param\" type=\"CT_Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_AlgorithmType\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutNode\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varLst\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"styleLbl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"chOrder\" type=\"ST_ChildOrderType\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"moveWith\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ForEach\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ref\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_When\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n    <xsd:attribute name=\"func\" type=\"ST_FunctionType\" use=\"required\"/>\n    <xsd:attribute name=\"arg\" type=\"ST_FunctionArgument\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"op\" type=\"ST_FunctionOperator\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FunctionValue\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Otherwise\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Choose\">\n    <xsd:sequence>\n      <xsd:element name=\"if\" type=\"CT_When\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"else\" type=\"CT_Otherwise\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SampleData\">\n    <xsd:sequence>\n      <xsd:element name=\"dataModel\" type=\"CT_DataModel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useDef\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Category\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Categories\">\n    <xsd:sequence>\n      <xsd:element name=\"cat\" type=\"CT_Category\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Name\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Description\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DiagramDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"sampData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"clrData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDef\" type=\"CT_DiagramDefinition\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdrLst\" type=\"CT_DiagramDefinitionHeaderLst\"/>\n  <xsd:complexType name=\"CT_RelIds\">\n    <xsd:attribute ref=\"r:dm\" use=\"required\"/>\n    <xsd:attribute ref=\"r:lo\" use=\"required\"/>\n    <xsd:attribute ref=\"r:qs\" use=\"required\"/>\n    <xsd:attribute ref=\"r:cs\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"relIds\" type=\"CT_RelIds\"/>\n  <xsd:simpleType name=\"ST_ParameterVal\">\n    <xsd:union\n      memberTypes=\"ST_DiagramHorizontalAlignment ST_VerticalAlignment ST_ChildDirection ST_ChildAlignment ST_SecondaryChildAlignment ST_LinearDirection ST_SecondaryLinearDirection ST_StartingElement ST_BendPoint ST_ConnectorRouting ST_ArrowheadStyle ST_ConnectorDimension ST_RotationPath ST_CenterShapeMapping ST_NodeHorizontalAlignment ST_NodeVerticalAlignment ST_FallbackDimension ST_TextDirection ST_PyramidAccentPosition ST_PyramidAccentTextMargin ST_TextBlockDirection ST_TextAnchorHorizontal ST_TextAnchorVertical ST_DiagramTextAlignment ST_AutoTextRotation ST_GrowDirection ST_FlowDirection ST_ContinueDirection ST_Breakpoint ST_Offset ST_HierarchyAlignment xsd:int xsd:double xsd:boolean xsd:string ST_ConnectorPoint\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ModelId\">\n    <xsd:union memberTypes=\"xsd:int s:ST_Guid\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrSetCustVal\">\n    <xsd:union memberTypes=\"s:ST_Percentage xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ElemPropSet\">\n    <xsd:sequence>\n      <xsd:element name=\"presLayoutVars\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"presAssocID\" type=\"ST_ModelId\" use=\"optional\"/>\n    <xsd:attribute name=\"presName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleLbl\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleIdx\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleCnt\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"loTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"loCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coherent3DOff\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"phldrT\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"phldr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custAng\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipVert\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipHor\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzX\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzY\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custT\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleRad\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleInc\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"rev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierBranchStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"hang\"/>\n      <xsd:enumeration value=\"std\"/>\n      <xsd:enumeration value=\"init\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimOneStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"branch\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimLvlStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"lvl\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OrgChart\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NodeCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChildMax\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChildPref\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BulletEnabled\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Direction\">\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" default=\"norm\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierBranchStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_HierBranchStyle\" default=\"std\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimOne\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimOneStr\" default=\"one\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimLvl\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimLvlStr\" default=\"none\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ResizeHandlesStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"rel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ResizeHandles\">\n    <xsd:attribute name=\"val\" type=\"ST_ResizeHandlesStr\" default=\"rel\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutVariablePropertySet\">\n    <xsd:sequence>\n      <xsd:element name=\"orgChart\" type=\"CT_OrgChart\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chMax\" type=\"CT_ChildMax\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chPref\" type=\"CT_ChildPref\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bulletEnabled\" type=\"CT_BulletEnabled\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dir\" type=\"CT_Direction\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hierBranch\" type=\"CT_HierBranchStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animOne\" type=\"CT_AnimOne\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animLvl\" type=\"CT_AnimLvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"resizeHandles\" type=\"CT_ResizeHandles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_SDCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextProps\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"a:CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"CT_TextProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_StyleLabel\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDef\" type=\"CT_StyleDefinition\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdrLst\" type=\"CT_StyleDefinitionHeaderLst\"/>\n  <xsd:simpleType name=\"ST_AlgorithmType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"composite\"/>\n      <xsd:enumeration value=\"conn\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"hierChild\"/>\n      <xsd:enumeration value=\"hierRoot\"/>\n      <xsd:enumeration value=\"pyra\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"snake\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n      <xsd:enumeration value=\"desOrSelf\"/>\n      <xsd:enumeration value=\"par\"/>\n      <xsd:enumeration value=\"ancst\"/>\n      <xsd:enumeration value=\"ancstOrSelf\"/>\n      <xsd:enumeration value=\"followSib\"/>\n      <xsd:enumeration value=\"precedSib\"/>\n      <xsd:enumeration value=\"follow\"/>\n      <xsd:enumeration value=\"preced\"/>\n      <xsd:enumeration value=\"root\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisTypes\">\n    <xsd:list itemType=\"ST_AxisType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BoolOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildOrderType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alignOff\"/>\n      <xsd:enumeration value=\"begMarg\"/>\n      <xsd:enumeration value=\"bendDist\"/>\n      <xsd:enumeration value=\"begPad\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"bMarg\"/>\n      <xsd:enumeration value=\"bOff\"/>\n      <xsd:enumeration value=\"ctrX\"/>\n      <xsd:enumeration value=\"ctrXOff\"/>\n      <xsd:enumeration value=\"ctrY\"/>\n      <xsd:enumeration value=\"ctrYOff\"/>\n      <xsd:enumeration value=\"connDist\"/>\n      <xsd:enumeration value=\"diam\"/>\n      <xsd:enumeration value=\"endMarg\"/>\n      <xsd:enumeration value=\"endPad\"/>\n      <xsd:enumeration value=\"h\"/>\n      <xsd:enumeration value=\"hArH\"/>\n      <xsd:enumeration value=\"hOff\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"lMarg\"/>\n      <xsd:enumeration value=\"lOff\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"rMarg\"/>\n      <xsd:enumeration value=\"rOff\"/>\n      <xsd:enumeration value=\"primFontSz\"/>\n      <xsd:enumeration value=\"pyraAcctRatio\"/>\n      <xsd:enumeration value=\"secFontSz\"/>\n      <xsd:enumeration value=\"sibSp\"/>\n      <xsd:enumeration value=\"secSibSp\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"stemThick\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tMarg\"/>\n      <xsd:enumeration value=\"tOff\"/>\n      <xsd:enumeration value=\"userA\"/>\n      <xsd:enumeration value=\"userB\"/>\n      <xsd:enumeration value=\"userC\"/>\n      <xsd:enumeration value=\"userD\"/>\n      <xsd:enumeration value=\"userE\"/>\n      <xsd:enumeration value=\"userF\"/>\n      <xsd:enumeration value=\"userG\"/>\n      <xsd:enumeration value=\"userH\"/>\n      <xsd:enumeration value=\"userI\"/>\n      <xsd:enumeration value=\"userJ\"/>\n      <xsd:enumeration value=\"userK\"/>\n      <xsd:enumeration value=\"userL\"/>\n      <xsd:enumeration value=\"userM\"/>\n      <xsd:enumeration value=\"userN\"/>\n      <xsd:enumeration value=\"userO\"/>\n      <xsd:enumeration value=\"userP\"/>\n      <xsd:enumeration value=\"userQ\"/>\n      <xsd:enumeration value=\"userR\"/>\n      <xsd:enumeration value=\"userS\"/>\n      <xsd:enumeration value=\"userT\"/>\n      <xsd:enumeration value=\"userU\"/>\n      <xsd:enumeration value=\"userV\"/>\n      <xsd:enumeration value=\"userW\"/>\n      <xsd:enumeration value=\"userX\"/>\n      <xsd:enumeration value=\"userY\"/>\n      <xsd:enumeration value=\"userZ\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"wArH\"/>\n      <xsd:enumeration value=\"wOff\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintRelationship\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"nonNorm\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"nonAsst\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementTypes\">\n    <xsd:list itemType=\"ST_ElementType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ParameterId\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horzAlign\"/>\n      <xsd:enumeration value=\"vertAlign\"/>\n      <xsd:enumeration value=\"chDir\"/>\n      <xsd:enumeration value=\"chAlign\"/>\n      <xsd:enumeration value=\"secChAlign\"/>\n      <xsd:enumeration value=\"linDir\"/>\n      <xsd:enumeration value=\"secLinDir\"/>\n      <xsd:enumeration value=\"stElem\"/>\n      <xsd:enumeration value=\"bendPt\"/>\n      <xsd:enumeration value=\"connRout\"/>\n      <xsd:enumeration value=\"begSty\"/>\n      <xsd:enumeration value=\"endSty\"/>\n      <xsd:enumeration value=\"dim\"/>\n      <xsd:enumeration value=\"rotPath\"/>\n      <xsd:enumeration value=\"ctrShpMap\"/>\n      <xsd:enumeration value=\"nodeHorzAlign\"/>\n      <xsd:enumeration value=\"nodeVertAlign\"/>\n      <xsd:enumeration value=\"fallback\"/>\n      <xsd:enumeration value=\"txDir\"/>\n      <xsd:enumeration value=\"pyraAcctPos\"/>\n      <xsd:enumeration value=\"pyraAcctTxMar\"/>\n      <xsd:enumeration value=\"txBlDir\"/>\n      <xsd:enumeration value=\"txAnchorHorz\"/>\n      <xsd:enumeration value=\"txAnchorVert\"/>\n      <xsd:enumeration value=\"txAnchorHorzCh\"/>\n      <xsd:enumeration value=\"txAnchorVertCh\"/>\n      <xsd:enumeration value=\"parTxLTRAlign\"/>\n      <xsd:enumeration value=\"parTxRTLAlign\"/>\n      <xsd:enumeration value=\"shpTxLTRAlignCh\"/>\n      <xsd:enumeration value=\"shpTxRTLAlignCh\"/>\n      <xsd:enumeration value=\"autoTxRot\"/>\n      <xsd:enumeration value=\"grDir\"/>\n      <xsd:enumeration value=\"flowDir\"/>\n      <xsd:enumeration value=\"contDir\"/>\n      <xsd:enumeration value=\"bkpt\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"hierAlign\"/>\n      <xsd:enumeration value=\"bkPtFixedVal\"/>\n      <xsd:enumeration value=\"stBulletLvl\"/>\n      <xsd:enumeration value=\"stAng\"/>\n      <xsd:enumeration value=\"spanAng\"/>\n      <xsd:enumeration value=\"ar\"/>\n      <xsd:enumeration value=\"lnSpPar\"/>\n      <xsd:enumeration value=\"lnSpAfParP\"/>\n      <xsd:enumeration value=\"lnSpCh\"/>\n      <xsd:enumeration value=\"lnSpAfChP\"/>\n      <xsd:enumeration value=\"rtShortDist\"/>\n      <xsd:enumeration value=\"alignTx\"/>\n      <xsd:enumeration value=\"pyraLvlNode\"/>\n      <xsd:enumeration value=\"pyraAcctBkgdNode\"/>\n      <xsd:enumeration value=\"pyraAcctTxNode\"/>\n      <xsd:enumeration value=\"srcNode\"/>\n      <xsd:enumeration value=\"dstNode\"/>\n      <xsd:enumeration value=\"begPts\"/>\n      <xsd:enumeration value=\"endPts\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ints\">\n    <xsd:list itemType=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedInts\">\n    <xsd:list itemType=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Booleans\">\n    <xsd:list itemType=\"xsd:boolean\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cnt\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"revPos\"/>\n      <xsd:enumeration value=\"posEven\"/>\n      <xsd:enumeration value=\"posOdd\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"depth\"/>\n      <xsd:enumeration value=\"maxDepth\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"neq\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryLinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StartingElement\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"trans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RotationPath\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alongPath\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CenterShapeMapping\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fNode\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BendPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"beg\"/>\n      <xsd:enumeration value=\"def\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorRouting\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"stra\"/>\n      <xsd:enumeration value=\"bend\"/>\n      <xsd:enumeration value=\"curve\"/>\n      <xsd:enumeration value=\"longCurve\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrowheadStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"arr\"/>\n      <xsd:enumeration value=\"noArr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"bCtr\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"midL\"/>\n      <xsd:enumeration value=\"midR\"/>\n      <xsd:enumeration value=\"tCtr\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"radial\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeVerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FallbackDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentPosition\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bef\"/>\n      <xsd:enumeration value=\"aft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentTextMargin\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"step\"/>\n      <xsd:enumeration value=\"stack\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBlockDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorHorizontal\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorVertical\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramTextAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AutoTextRotation\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"upr\"/>\n      <xsd:enumeration value=\"grav\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GrowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FlowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContinueDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"revDir\"/>\n      <xsd:enumeration value=\"sameDir\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Breakpoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"endCnv\"/>\n      <xsd:enumeration value=\"bal\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Offset\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierarchyAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"tCtrCh\"/>\n      <xsd:enumeration value=\"tCtrDes\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"bCtrCh\"/>\n      <xsd:enumeration value=\"bCtrDes\"/>\n      <xsd:enumeration value=\"lT\"/>\n      <xsd:enumeration value=\"lB\"/>\n      <xsd:enumeration value=\"lCtrCh\"/>\n      <xsd:enumeration value=\"lCtrDes\"/>\n      <xsd:enumeration value=\"rT\"/>\n      <xsd:enumeration value=\"rB\"/>\n      <xsd:enumeration value=\"rCtrCh\"/>\n      <xsd:enumeration value=\"rCtrDes\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionValue\" final=\"restriction\">\n    <xsd:union\n      memberTypes=\"xsd:int xsd:boolean ST_Direction ST_HierBranchStyle ST_AnimOneStr ST_AnimLvlStr ST_ResizeHandlesStr\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VariableType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"orgChart\"/>\n      <xsd:enumeration value=\"chMax\"/>\n      <xsd:enumeration value=\"chPref\"/>\n      <xsd:enumeration value=\"bulEnabled\"/>\n      <xsd:enumeration value=\"dir\"/>\n      <xsd:enumeration value=\"hierBranch\"/>\n      <xsd:enumeration value=\"animOne\"/>\n      <xsd:enumeration value=\"animLvl\"/>\n      <xsd:enumeration value=\"resizeHandles\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionArgument\" final=\"restriction\">\n    <xsd:union memberTypes=\"ST_VariableType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OutputShapeType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"conn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:element name=\"lockedCanvas\" type=\"a:CT_GvmlGroupShape\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n    schemaLocation=\"dml-diagram.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n    schemaLocation=\"dml-chart.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n    schemaLocation=\"dml-lockedCanvas.xsd\"/>\n  <xsd:complexType name=\"CT_AudioFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VideoFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QuickTimeFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCDTime\">\n    <xsd:attribute name=\"track\" type=\"xsd:unsignedByte\" use=\"required\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCD\">\n    <xsd:sequence>\n      <xsd:element name=\"st\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Media\">\n    <xsd:choice>\n      <xsd:element name=\"audioCd\" type=\"CT_AudioCD\"/>\n      <xsd:element name=\"wavAudioFile\" type=\"CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"audioFile\" type=\"CT_AudioFile\"/>\n      <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n      <xsd:element name=\"quickTimeFile\" type=\"CT_QuickTimeFile\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n  <xsd:simpleType name=\"ST_StyleMatrixColumnIndex\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontCollectionIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"dk1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dk2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent3\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent4\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent5\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent6\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"folHlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SupplementalFont\">\n    <xsd:attribute name=\"script\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColorList\">\n    <xsd:sequence>\n      <xsd:element name=\"custClr\" type=\"CT_CustomColor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontCollection\">\n    <xsd:sequence>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"font\" type=\"CT_SupplementalFont\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleItem\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"majorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LineStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"effectStyle\" type=\"CT_EffectStyleItem\" minOccurs=\"3\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrix\">\n    <xsd:sequence>\n      <xsd:element name=\"fillStyleLst\" type=\"CT_FillStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnStyleLst\" type=\"CT_LineStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectStyleLst\" type=\"CT_EffectStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgFillStyleLst\" type=\"CT_BackgroundFillStyleList\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeArtExtension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Coordinate\">\n    <xsd:union memberTypes=\"ST_CoordinateUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CoordinateUnqualified\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"-27273042329600\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32\">\n    <xsd:union memberTypes=\"ST_Coordinate32Unqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32Unqualified\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate32\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Angle\">\n    <xsd:attribute name=\"val\" type=\"ST_Angle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minExclusive value=\"-5400000\"/>\n      <xsd:maxExclusive value=\"5400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxExclusive value=\"21600000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedAngle\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:union memberTypes=\"ST_PercentageDecimal s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PercentageDecimal\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Percentage\">\n    <xsd:attribute name=\"val\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:union memberTypes=\"ST_PositivePercentageDecimal s:ST_PositivePercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositivePercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:union memberTypes=\"ST_FixedPercentageDecimal s:ST_FixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"-100000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:union memberTypes=\"ST_PositiveFixedPercentageDecimal s:ST_PositiveFixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ratio\">\n    <xsd:attribute name=\"n\" type=\"xsd:long\" use=\"required\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:long\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point2D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PositiveSize2D\">\n    <xsd:attribute name=\"cx\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ComplementTransform\"/>\n  <xsd:complexType name=\"CT_InverseTransform\"/>\n  <xsd:complexType name=\"CT_GrayscaleTransform\"/>\n  <xsd:complexType name=\"CT_GammaTransform\"/>\n  <xsd:complexType name=\"CT_InverseGammaTransform\"/>\n  <xsd:group name=\"EG_ColorTransform\">\n    <xsd:choice>\n      <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"comp\" type=\"CT_ComplementTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"inv\" type=\"CT_InverseTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gray\" type=\"CT_GrayscaleTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOff\" type=\"CT_FixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hue\" type=\"CT_PositiveFixedAngle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueOff\" type=\"CT_Angle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sat\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"red\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"green\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blue\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gamma\" type=\"CT_GammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invGamma\" type=\"CT_InverseGammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ScRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HslColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SystemColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"scrollBar\"/>\n      <xsd:enumeration value=\"background\"/>\n      <xsd:enumeration value=\"activeCaption\"/>\n      <xsd:enumeration value=\"inactiveCaption\"/>\n      <xsd:enumeration value=\"menu\"/>\n      <xsd:enumeration value=\"window\"/>\n      <xsd:enumeration value=\"windowFrame\"/>\n      <xsd:enumeration value=\"menuText\"/>\n      <xsd:enumeration value=\"windowText\"/>\n      <xsd:enumeration value=\"captionText\"/>\n      <xsd:enumeration value=\"activeBorder\"/>\n      <xsd:enumeration value=\"inactiveBorder\"/>\n      <xsd:enumeration value=\"appWorkspace\"/>\n      <xsd:enumeration value=\"highlight\"/>\n      <xsd:enumeration value=\"highlightText\"/>\n      <xsd:enumeration value=\"btnFace\"/>\n      <xsd:enumeration value=\"btnShadow\"/>\n      <xsd:enumeration value=\"grayText\"/>\n      <xsd:enumeration value=\"btnText\"/>\n      <xsd:enumeration value=\"inactiveCaptionText\"/>\n      <xsd:enumeration value=\"btnHighlight\"/>\n      <xsd:enumeration value=\"3dDkShadow\"/>\n      <xsd:enumeration value=\"3dLight\"/>\n      <xsd:enumeration value=\"infoText\"/>\n      <xsd:enumeration value=\"infoBk\"/>\n      <xsd:enumeration value=\"hotLight\"/>\n      <xsd:enumeration value=\"gradientActiveCaption\"/>\n      <xsd:enumeration value=\"gradientInactiveCaption\"/>\n      <xsd:enumeration value=\"menuHighlight\"/>\n      <xsd:enumeration value=\"menuBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SystemColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SystemColorVal\" use=\"required\"/>\n    <xsd:attribute name=\"lastClr\" type=\"s:ST_HexColorRGB\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SchemeColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bg1\"/>\n      <xsd:enumeration value=\"tx1\"/>\n      <xsd:enumeration value=\"bg2\"/>\n      <xsd:enumeration value=\"tx2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n      <xsd:enumeration value=\"phClr\"/>\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SchemeColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"aliceBlue\"/>\n      <xsd:enumeration value=\"antiqueWhite\"/>\n      <xsd:enumeration value=\"aqua\"/>\n      <xsd:enumeration value=\"aquamarine\"/>\n      <xsd:enumeration value=\"azure\"/>\n      <xsd:enumeration value=\"beige\"/>\n      <xsd:enumeration value=\"bisque\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blanchedAlmond\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"blueViolet\"/>\n      <xsd:enumeration value=\"brown\"/>\n      <xsd:enumeration value=\"burlyWood\"/>\n      <xsd:enumeration value=\"cadetBlue\"/>\n      <xsd:enumeration value=\"chartreuse\"/>\n      <xsd:enumeration value=\"chocolate\"/>\n      <xsd:enumeration value=\"coral\"/>\n      <xsd:enumeration value=\"cornflowerBlue\"/>\n      <xsd:enumeration value=\"cornsilk\"/>\n      <xsd:enumeration value=\"crimson\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGoldenrod\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"darkGrey\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkKhaki\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkOliveGreen\"/>\n      <xsd:enumeration value=\"darkOrange\"/>\n      <xsd:enumeration value=\"darkOrchid\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkSalmon\"/>\n      <xsd:enumeration value=\"darkSeaGreen\"/>\n      <xsd:enumeration value=\"darkSlateBlue\"/>\n      <xsd:enumeration value=\"darkSlateGray\"/>\n      <xsd:enumeration value=\"darkSlateGrey\"/>\n      <xsd:enumeration value=\"darkTurquoise\"/>\n      <xsd:enumeration value=\"darkViolet\"/>\n      <xsd:enumeration value=\"dkBlue\"/>\n      <xsd:enumeration value=\"dkCyan\"/>\n      <xsd:enumeration value=\"dkGoldenrod\"/>\n      <xsd:enumeration value=\"dkGray\"/>\n      <xsd:enumeration value=\"dkGrey\"/>\n      <xsd:enumeration value=\"dkGreen\"/>\n      <xsd:enumeration value=\"dkKhaki\"/>\n      <xsd:enumeration value=\"dkMagenta\"/>\n      <xsd:enumeration value=\"dkOliveGreen\"/>\n      <xsd:enumeration value=\"dkOrange\"/>\n      <xsd:enumeration value=\"dkOrchid\"/>\n      <xsd:enumeration value=\"dkRed\"/>\n      <xsd:enumeration value=\"dkSalmon\"/>\n      <xsd:enumeration value=\"dkSeaGreen\"/>\n      <xsd:enumeration value=\"dkSlateBlue\"/>\n      <xsd:enumeration value=\"dkSlateGray\"/>\n      <xsd:enumeration value=\"dkSlateGrey\"/>\n      <xsd:enumeration value=\"dkTurquoise\"/>\n      <xsd:enumeration value=\"dkViolet\"/>\n      <xsd:enumeration value=\"deepPink\"/>\n      <xsd:enumeration value=\"deepSkyBlue\"/>\n      <xsd:enumeration value=\"dimGray\"/>\n      <xsd:enumeration value=\"dimGrey\"/>\n      <xsd:enumeration value=\"dodgerBlue\"/>\n      <xsd:enumeration value=\"firebrick\"/>\n      <xsd:enumeration value=\"floralWhite\"/>\n      <xsd:enumeration value=\"forestGreen\"/>\n      <xsd:enumeration value=\"fuchsia\"/>\n      <xsd:enumeration value=\"gainsboro\"/>\n      <xsd:enumeration value=\"ghostWhite\"/>\n      <xsd:enumeration value=\"gold\"/>\n      <xsd:enumeration value=\"goldenrod\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"grey\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"greenYellow\"/>\n      <xsd:enumeration value=\"honeydew\"/>\n      <xsd:enumeration value=\"hotPink\"/>\n      <xsd:enumeration value=\"indianRed\"/>\n      <xsd:enumeration value=\"indigo\"/>\n      <xsd:enumeration value=\"ivory\"/>\n      <xsd:enumeration value=\"khaki\"/>\n      <xsd:enumeration value=\"lavender\"/>\n      <xsd:enumeration value=\"lavenderBlush\"/>\n      <xsd:enumeration value=\"lawnGreen\"/>\n      <xsd:enumeration value=\"lemonChiffon\"/>\n      <xsd:enumeration value=\"lightBlue\"/>\n      <xsd:enumeration value=\"lightCoral\"/>\n      <xsd:enumeration value=\"lightCyan\"/>\n      <xsd:enumeration value=\"lightGoldenrodYellow\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"lightGrey\"/>\n      <xsd:enumeration value=\"lightGreen\"/>\n      <xsd:enumeration value=\"lightPink\"/>\n      <xsd:enumeration value=\"lightSalmon\"/>\n      <xsd:enumeration value=\"lightSeaGreen\"/>\n      <xsd:enumeration value=\"lightSkyBlue\"/>\n      <xsd:enumeration value=\"lightSlateGray\"/>\n      <xsd:enumeration value=\"lightSlateGrey\"/>\n      <xsd:enumeration value=\"lightSteelBlue\"/>\n      <xsd:enumeration value=\"lightYellow\"/>\n      <xsd:enumeration value=\"ltBlue\"/>\n      <xsd:enumeration value=\"ltCoral\"/>\n      <xsd:enumeration value=\"ltCyan\"/>\n      <xsd:enumeration value=\"ltGoldenrodYellow\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"ltGrey\"/>\n      <xsd:enumeration value=\"ltGreen\"/>\n      <xsd:enumeration value=\"ltPink\"/>\n      <xsd:enumeration value=\"ltSalmon\"/>\n      <xsd:enumeration value=\"ltSeaGreen\"/>\n      <xsd:enumeration value=\"ltSkyBlue\"/>\n      <xsd:enumeration value=\"ltSlateGray\"/>\n      <xsd:enumeration value=\"ltSlateGrey\"/>\n      <xsd:enumeration value=\"ltSteelBlue\"/>\n      <xsd:enumeration value=\"ltYellow\"/>\n      <xsd:enumeration value=\"lime\"/>\n      <xsd:enumeration value=\"limeGreen\"/>\n      <xsd:enumeration value=\"linen\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"maroon\"/>\n      <xsd:enumeration value=\"medAquamarine\"/>\n      <xsd:enumeration value=\"medBlue\"/>\n      <xsd:enumeration value=\"medOrchid\"/>\n      <xsd:enumeration value=\"medPurple\"/>\n      <xsd:enumeration value=\"medSeaGreen\"/>\n      <xsd:enumeration value=\"medSlateBlue\"/>\n      <xsd:enumeration value=\"medSpringGreen\"/>\n      <xsd:enumeration value=\"medTurquoise\"/>\n      <xsd:enumeration value=\"medVioletRed\"/>\n      <xsd:enumeration value=\"mediumAquamarine\"/>\n      <xsd:enumeration value=\"mediumBlue\"/>\n      <xsd:enumeration value=\"mediumOrchid\"/>\n      <xsd:enumeration value=\"mediumPurple\"/>\n      <xsd:enumeration value=\"mediumSeaGreen\"/>\n      <xsd:enumeration value=\"mediumSlateBlue\"/>\n      <xsd:enumeration value=\"mediumSpringGreen\"/>\n      <xsd:enumeration value=\"mediumTurquoise\"/>\n      <xsd:enumeration value=\"mediumVioletRed\"/>\n      <xsd:enumeration value=\"midnightBlue\"/>\n      <xsd:enumeration value=\"mintCream\"/>\n      <xsd:enumeration value=\"mistyRose\"/>\n      <xsd:enumeration value=\"moccasin\"/>\n      <xsd:enumeration value=\"navajoWhite\"/>\n      <xsd:enumeration value=\"navy\"/>\n      <xsd:enumeration value=\"oldLace\"/>\n      <xsd:enumeration value=\"olive\"/>\n      <xsd:enumeration value=\"oliveDrab\"/>\n      <xsd:enumeration value=\"orange\"/>\n      <xsd:enumeration value=\"orangeRed\"/>\n      <xsd:enumeration value=\"orchid\"/>\n      <xsd:enumeration value=\"paleGoldenrod\"/>\n      <xsd:enumeration value=\"paleGreen\"/>\n      <xsd:enumeration value=\"paleTurquoise\"/>\n      <xsd:enumeration value=\"paleVioletRed\"/>\n      <xsd:enumeration value=\"papayaWhip\"/>\n      <xsd:enumeration value=\"peachPuff\"/>\n      <xsd:enumeration value=\"peru\"/>\n      <xsd:enumeration value=\"pink\"/>\n      <xsd:enumeration value=\"plum\"/>\n      <xsd:enumeration value=\"powderBlue\"/>\n      <xsd:enumeration value=\"purple\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"rosyBrown\"/>\n      <xsd:enumeration value=\"royalBlue\"/>\n      <xsd:enumeration value=\"saddleBrown\"/>\n      <xsd:enumeration value=\"salmon\"/>\n      <xsd:enumeration value=\"sandyBrown\"/>\n      <xsd:enumeration value=\"seaGreen\"/>\n      <xsd:enumeration value=\"seaShell\"/>\n      <xsd:enumeration value=\"sienna\"/>\n      <xsd:enumeration value=\"silver\"/>\n      <xsd:enumeration value=\"skyBlue\"/>\n      <xsd:enumeration value=\"slateBlue\"/>\n      <xsd:enumeration value=\"slateGray\"/>\n      <xsd:enumeration value=\"slateGrey\"/>\n      <xsd:enumeration value=\"snow\"/>\n      <xsd:enumeration value=\"springGreen\"/>\n      <xsd:enumeration value=\"steelBlue\"/>\n      <xsd:enumeration value=\"tan\"/>\n      <xsd:enumeration value=\"teal\"/>\n      <xsd:enumeration value=\"thistle\"/>\n      <xsd:enumeration value=\"tomato\"/>\n      <xsd:enumeration value=\"turquoise\"/>\n      <xsd:enumeration value=\"violet\"/>\n      <xsd:enumeration value=\"wheat\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"whiteSmoke\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"yellowGreen\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_PresetColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_OfficeArtExtension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OfficeArtExtensionList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scale2D\">\n    <xsd:sequence>\n      <xsd:element name=\"sx\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sy\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Transform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupTransform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chOff\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chExt\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point3D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vector3D\">\n    <xsd:attribute name=\"dx\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dy\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dz\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SphereCoords\">\n    <xsd:attribute name=\"lat\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"lon\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeRect\">\n    <xsd:attribute name=\"l\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"t\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RectAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:group name=\"EG_ColorChoice\">\n    <xsd:choice>\n      <xsd:element name=\"scrgbClr\" type=\"CT_ScRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hslClr\" type=\"CT_HslColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sysClr\" type=\"CT_SystemColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstClr\" type=\"CT_PresetColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMRU\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlackWhiteMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clr\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"invGray\"/>\n      <xsd:enumeration value=\"grayWhite\"/>\n      <xsd:enumeration value=\"blackGray\"/>\n      <xsd:enumeration value=\"blackWhite\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Blob\">\n    <xsd:attribute ref=\"r:embed\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:link\" use=\"optional\" default=\"\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_EmbeddedWAVAudioFile\">\n    <xsd:attribute ref=\"r:embed\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:sequence>\n      <xsd:element name=\"snd\" type=\"CT_EmbeddedWAVAudioFile\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalidUrl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"action\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tooltip\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"highlightClick\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"endSnd\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DrawingElementId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Locking\">\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noEditPoints\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noAdjustHandles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeArrowheads\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeShapeType\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_ConnectorLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noTextEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noCrop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noUngrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noDrilldown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ContentPartLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkHover\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"descr\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"spLocks\" type=\"CT_ShapeLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"txBox\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualConnectorProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cxnSpLocks\" type=\"CT_ConnectorLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualPictureProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"picLocks\" type=\"CT_PictureLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preferRelativeResize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGroupDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"grpSpLocks\" type=\"CT_GroupLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGraphicFrameProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicFrameLocks\" type=\"CT_GraphicalObjectFrameLocking\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualContentPartProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cpLocks\" type=\"CT_ContentPartLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isComment\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectData\">\n    <xsd:sequence>\n      <xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"strict\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObject\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicData\" type=\"CT_GraphicalObjectData\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"graphic\" type=\"CT_GraphicalObject\"/>\n  <xsd:simpleType name=\"ST_ChartBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"allPts\"/>\n      <xsd:enumeration value=\"gridLegend\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DgmBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"bg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmElement\">\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"optional\"\n      default=\"{00000000-0000-0000-0000-000000000000}\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_DgmBuildStep\" use=\"optional\" default=\"sp\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationChartElement\">\n    <xsd:attribute name=\"seriesIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"categoryIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_ChartBuildStep\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationElementChoice\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"dgm\" type=\"CT_AnimationDgmElement\"/>\n      <xsd:element name=\"chart\" type=\"CT_AnimationChartElement\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"lvlOne\"/>\n      <xsd:enumeration value=\"lvlAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationDgmOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationDgmBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationChartOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationChartBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationChartOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationChartBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationGraphicalObjectBuildProperties\">\n    <xsd:choice>\n      <xsd:element name=\"bldDgm\" type=\"CT_AnimationDgmBuildProperties\"/>\n      <xsd:element name=\"bldChart\" type=\"CT_AnimationChartBuildProperties\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFormatting\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WholeE2oFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlUseShapeRectangle\"/>\n  <xsd:complexType name=\"CT_GvmlTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"useSpRect\" type=\"CT_GvmlUseShapeRectangle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_GvmlShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_GvmlConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"CT_NonVisualPictureProperties\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPicture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_GvmlPictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GvmlGraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element ref=\"graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GvmlGroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\"/>\n        <xsd:element name=\"sp\" type=\"CT_GvmlShape\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_GvmlConnector\"/>\n        <xsd:element name=\"pic\" type=\"CT_GvmlPicture\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GvmlGraphicalObjectFrame\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GvmlGroupShape\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetCameraType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueTop\"/>\n      <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n      <xsd:enumeration value=\"legacyObliqueLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueFront\"/>\n      <xsd:enumeration value=\"legacyObliqueRight\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueBottom\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n      <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n      <xsd:enumeration value=\"orthographicFront\"/>\n      <xsd:enumeration value=\"isometricTopUp\"/>\n      <xsd:enumeration value=\"isometricTopDown\"/>\n      <xsd:enumeration value=\"isometricBottomUp\"/>\n      <xsd:enumeration value=\"isometricBottomDown\"/>\n      <xsd:enumeration value=\"isometricLeftUp\"/>\n      <xsd:enumeration value=\"isometricLeftDown\"/>\n      <xsd:enumeration value=\"isometricRightUp\"/>\n      <xsd:enumeration value=\"isometricRightDown\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n      <xsd:enumeration value=\"obliqueTopLeft\"/>\n      <xsd:enumeration value=\"obliqueTop\"/>\n      <xsd:enumeration value=\"obliqueTopRight\"/>\n      <xsd:enumeration value=\"obliqueLeft\"/>\n      <xsd:enumeration value=\"obliqueRight\"/>\n      <xsd:enumeration value=\"obliqueBottomLeft\"/>\n      <xsd:enumeration value=\"obliqueBottom\"/>\n      <xsd:enumeration value=\"obliqueBottomRight\"/>\n      <xsd:enumeration value=\"perspectiveFront\"/>\n      <xsd:enumeration value=\"perspectiveLeft\"/>\n      <xsd:enumeration value=\"perspectiveRight\"/>\n      <xsd:enumeration value=\"perspectiveAbove\"/>\n      <xsd:enumeration value=\"perspectiveBelow\"/>\n      <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveRelaxed\"/>\n      <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FOVAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"10800000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Camera\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetCameraType\" use=\"required\"/>\n    <xsd:attribute name=\"fov\" type=\"ST_FOVAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"zoom\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LightRigDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LightRigType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyFlat1\"/>\n      <xsd:enumeration value=\"legacyFlat2\"/>\n      <xsd:enumeration value=\"legacyFlat3\"/>\n      <xsd:enumeration value=\"legacyFlat4\"/>\n      <xsd:enumeration value=\"legacyNormal1\"/>\n      <xsd:enumeration value=\"legacyNormal2\"/>\n      <xsd:enumeration value=\"legacyNormal3\"/>\n      <xsd:enumeration value=\"legacyNormal4\"/>\n      <xsd:enumeration value=\"legacyHarsh1\"/>\n      <xsd:enumeration value=\"legacyHarsh2\"/>\n      <xsd:enumeration value=\"legacyHarsh3\"/>\n      <xsd:enumeration value=\"legacyHarsh4\"/>\n      <xsd:enumeration value=\"threePt\"/>\n      <xsd:enumeration value=\"balanced\"/>\n      <xsd:enumeration value=\"soft\"/>\n      <xsd:enumeration value=\"harsh\"/>\n      <xsd:enumeration value=\"flood\"/>\n      <xsd:enumeration value=\"contrasting\"/>\n      <xsd:enumeration value=\"morning\"/>\n      <xsd:enumeration value=\"sunrise\"/>\n      <xsd:enumeration value=\"sunset\"/>\n      <xsd:enumeration value=\"chilly\"/>\n      <xsd:enumeration value=\"freezing\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"twoPt\"/>\n      <xsd:enumeration value=\"glow\"/>\n      <xsd:enumeration value=\"brightRoom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LightRig\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scene3D\">\n    <xsd:sequence>\n      <xsd:element name=\"camera\" type=\"CT_Camera\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backdrop\" type=\"CT_Backdrop\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Backdrop\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_Point3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"norm\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"up\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BevelPresetType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relaxedInset\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"slope\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"softRound\"/>\n      <xsd:enumeration value=\"convex\"/>\n      <xsd:enumeration value=\"coolSlant\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"riblet\"/>\n      <xsd:enumeration value=\"hardEdge\"/>\n      <xsd:enumeration value=\"artDeco\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Bevel\">\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\" default=\"circle\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetMaterialType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyMatte\"/>\n      <xsd:enumeration value=\"legacyPlastic\"/>\n      <xsd:enumeration value=\"legacyMetal\"/>\n      <xsd:enumeration value=\"legacyWireframe\"/>\n      <xsd:enumeration value=\"matte\"/>\n      <xsd:enumeration value=\"plastic\"/>\n      <xsd:enumeration value=\"metal\"/>\n      <xsd:enumeration value=\"warmMatte\"/>\n      <xsd:enumeration value=\"translucentPowder\"/>\n      <xsd:enumeration value=\"powder\"/>\n      <xsd:enumeration value=\"dkEdge\"/>\n      <xsd:enumeration value=\"softEdge\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"softmetal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"extrusionH\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"contourW\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"\n      default=\"warmMatte\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FlatText\">\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Text3D\">\n    <xsd:choice>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"flatTx\" type=\"CT_FlatText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AlphaBiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaCeilingEffect\"/>\n  <xsd:complexType name=\"CT_AlphaFloorEffect\"/>\n  <xsd:complexType name=\"CT_AlphaInverseEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateFixedEffect\">\n    <xsd:attribute name=\"amt\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaOutsetEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaReplaceEffect\">\n    <xsd:attribute name=\"a\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlurEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"grow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorChangeEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"clrFrom\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrTo\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useA\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorReplaceEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DuotoneEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GrayscaleEffect\"/>\n  <xsd:complexType name=\"CT_HSLEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InnerShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LuminanceEffect\">\n    <xsd:attribute name=\"bright\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"contrast\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OuterShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetShadowVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shdw1\"/>\n      <xsd:enumeration value=\"shdw2\"/>\n      <xsd:enumeration value=\"shdw3\"/>\n      <xsd:enumeration value=\"shdw4\"/>\n      <xsd:enumeration value=\"shdw5\"/>\n      <xsd:enumeration value=\"shdw6\"/>\n      <xsd:enumeration value=\"shdw7\"/>\n      <xsd:enumeration value=\"shdw8\"/>\n      <xsd:enumeration value=\"shdw9\"/>\n      <xsd:enumeration value=\"shdw10\"/>\n      <xsd:enumeration value=\"shdw11\"/>\n      <xsd:enumeration value=\"shdw12\"/>\n      <xsd:enumeration value=\"shdw13\"/>\n      <xsd:enumeration value=\"shdw14\"/>\n      <xsd:enumeration value=\"shdw15\"/>\n      <xsd:enumeration value=\"shdw16\"/>\n      <xsd:enumeration value=\"shdw17\"/>\n      <xsd:enumeration value=\"shdw18\"/>\n      <xsd:enumeration value=\"shdw19\"/>\n      <xsd:enumeration value=\"shdw20\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetShadowVal\" use=\"required\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReflectionEffect\">\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"stA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"stPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fadeDir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"5400000\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeOffsetEffect\">\n    <xsd:attribute name=\"tx\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SoftEdgesEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TintEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"amt\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransformEffect\">\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NoFillProperties\"/>\n  <xsd:complexType name=\"CT_SolidColorFillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinearShadeProperties\">\n    <xsd:attribute name=\"ang\" type=\"ST_PositiveFixedAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"scaled\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PathShadeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shape\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PathShadeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShadeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"path\" type=\"CT_PathShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TileFlipMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n      <xsd:enumeration value=\"xy\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pos\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tileRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TileInfoProperties\">\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StretchInfoProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FillModeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"tile\" type=\"CT_TileInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stretch\" type=\"CT_StretchInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_BlipCompression\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"hqprint\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Blip\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Blob\"/>\n    <xsd:attribute name=\"cstate\" type=\"ST_BlipCompression\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlipFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srcRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillModeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetPatternVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"ltHorz\"/>\n      <xsd:enumeration value=\"ltVert\"/>\n      <xsd:enumeration value=\"dkHorz\"/>\n      <xsd:enumeration value=\"dkVert\"/>\n      <xsd:enumeration value=\"narHorz\"/>\n      <xsd:enumeration value=\"narVert\"/>\n      <xsd:enumeration value=\"dashHorz\"/>\n      <xsd:enumeration value=\"dashVert\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"dnDiag\"/>\n      <xsd:enumeration value=\"upDiag\"/>\n      <xsd:enumeration value=\"ltDnDiag\"/>\n      <xsd:enumeration value=\"ltUpDiag\"/>\n      <xsd:enumeration value=\"dkDnDiag\"/>\n      <xsd:enumeration value=\"dkUpDiag\"/>\n      <xsd:enumeration value=\"wdDnDiag\"/>\n      <xsd:enumeration value=\"wdUpDiag\"/>\n      <xsd:enumeration value=\"dashDnDiag\"/>\n      <xsd:enumeration value=\"dashUpDiag\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"smCheck\"/>\n      <xsd:enumeration value=\"lgCheck\"/>\n      <xsd:enumeration value=\"smGrid\"/>\n      <xsd:enumeration value=\"lgGrid\"/>\n      <xsd:enumeration value=\"dotGrid\"/>\n      <xsd:enumeration value=\"smConfetti\"/>\n      <xsd:enumeration value=\"lgConfetti\"/>\n      <xsd:enumeration value=\"horzBrick\"/>\n      <xsd:enumeration value=\"diagBrick\"/>\n      <xsd:enumeration value=\"solidDmnd\"/>\n      <xsd:enumeration value=\"openDmnd\"/>\n      <xsd:enumeration value=\"dotDmnd\"/>\n      <xsd:enumeration value=\"plaid\"/>\n      <xsd:enumeration value=\"sphere\"/>\n      <xsd:enumeration value=\"weave\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"shingle\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"trellis\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PatternFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetPatternVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupFillProperties\"/>\n  <xsd:group name=\"EG_FillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpFill\" type=\"CT_GroupFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlendMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"over\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"lighten\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FillOverlayEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectReference\">\n    <xsd:attribute name=\"ref\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Effect\">\n    <xsd:choice>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effect\" type=\"CT_EffectReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOutset\" type=\"CT_AlphaOutsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blend\" type=\"CT_BlendEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_FillEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"relOff\" type=\"CT_RelativeOffsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_TransformEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_EffectContainerType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sib\"/>\n      <xsd:enumeration value=\"tree\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EffectContainer\">\n    <xsd:group ref=\"EG_Effect\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"type\" type=\"ST_EffectContainerType\" use=\"optional\" default=\"sib\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlendEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectList\">\n    <xsd:sequence>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_EffectProperties\">\n    <xsd:choice>\n      <xsd:element name=\"effectLst\" type=\"CT_EffectList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectDag\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_EffectProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"blip\" type=\"CT_Blip\"/>\n  <xsd:simpleType name=\"ST_ShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineInv\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"rtTriangle\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"parallelogram\"/>\n      <xsd:enumeration value=\"trapezoid\"/>\n      <xsd:enumeration value=\"nonIsoscelesTrapezoid\"/>\n      <xsd:enumeration value=\"pentagon\"/>\n      <xsd:enumeration value=\"hexagon\"/>\n      <xsd:enumeration value=\"heptagon\"/>\n      <xsd:enumeration value=\"octagon\"/>\n      <xsd:enumeration value=\"decagon\"/>\n      <xsd:enumeration value=\"dodecagon\"/>\n      <xsd:enumeration value=\"star4\"/>\n      <xsd:enumeration value=\"star5\"/>\n      <xsd:enumeration value=\"star6\"/>\n      <xsd:enumeration value=\"star7\"/>\n      <xsd:enumeration value=\"star8\"/>\n      <xsd:enumeration value=\"star10\"/>\n      <xsd:enumeration value=\"star12\"/>\n      <xsd:enumeration value=\"star16\"/>\n      <xsd:enumeration value=\"star24\"/>\n      <xsd:enumeration value=\"star32\"/>\n      <xsd:enumeration value=\"roundRect\"/>\n      <xsd:enumeration value=\"round1Rect\"/>\n      <xsd:enumeration value=\"round2SameRect\"/>\n      <xsd:enumeration value=\"round2DiagRect\"/>\n      <xsd:enumeration value=\"snipRoundRect\"/>\n      <xsd:enumeration value=\"snip1Rect\"/>\n      <xsd:enumeration value=\"snip2SameRect\"/>\n      <xsd:enumeration value=\"snip2DiagRect\"/>\n      <xsd:enumeration value=\"plaque\"/>\n      <xsd:enumeration value=\"ellipse\"/>\n      <xsd:enumeration value=\"teardrop\"/>\n      <xsd:enumeration value=\"homePlate\"/>\n      <xsd:enumeration value=\"chevron\"/>\n      <xsd:enumeration value=\"pieWedge\"/>\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"blockArc\"/>\n      <xsd:enumeration value=\"donut\"/>\n      <xsd:enumeration value=\"noSmoking\"/>\n      <xsd:enumeration value=\"rightArrow\"/>\n      <xsd:enumeration value=\"leftArrow\"/>\n      <xsd:enumeration value=\"upArrow\"/>\n      <xsd:enumeration value=\"downArrow\"/>\n      <xsd:enumeration value=\"stripedRightArrow\"/>\n      <xsd:enumeration value=\"notchedRightArrow\"/>\n      <xsd:enumeration value=\"bentUpArrow\"/>\n      <xsd:enumeration value=\"leftRightArrow\"/>\n      <xsd:enumeration value=\"upDownArrow\"/>\n      <xsd:enumeration value=\"leftUpArrow\"/>\n      <xsd:enumeration value=\"leftRightUpArrow\"/>\n      <xsd:enumeration value=\"quadArrow\"/>\n      <xsd:enumeration value=\"leftArrowCallout\"/>\n      <xsd:enumeration value=\"rightArrowCallout\"/>\n      <xsd:enumeration value=\"upArrowCallout\"/>\n      <xsd:enumeration value=\"downArrowCallout\"/>\n      <xsd:enumeration value=\"leftRightArrowCallout\"/>\n      <xsd:enumeration value=\"upDownArrowCallout\"/>\n      <xsd:enumeration value=\"quadArrowCallout\"/>\n      <xsd:enumeration value=\"bentArrow\"/>\n      <xsd:enumeration value=\"uturnArrow\"/>\n      <xsd:enumeration value=\"circularArrow\"/>\n      <xsd:enumeration value=\"leftCircularArrow\"/>\n      <xsd:enumeration value=\"leftRightCircularArrow\"/>\n      <xsd:enumeration value=\"curvedRightArrow\"/>\n      <xsd:enumeration value=\"curvedLeftArrow\"/>\n      <xsd:enumeration value=\"curvedUpArrow\"/>\n      <xsd:enumeration value=\"curvedDownArrow\"/>\n      <xsd:enumeration value=\"swooshArrow\"/>\n      <xsd:enumeration value=\"cube\"/>\n      <xsd:enumeration value=\"can\"/>\n      <xsd:enumeration value=\"lightningBolt\"/>\n      <xsd:enumeration value=\"heart\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"moon\"/>\n      <xsd:enumeration value=\"smileyFace\"/>\n      <xsd:enumeration value=\"irregularSeal1\"/>\n      <xsd:enumeration value=\"irregularSeal2\"/>\n      <xsd:enumeration value=\"foldedCorner\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"halfFrame\"/>\n      <xsd:enumeration value=\"corner\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"chord\"/>\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"leftBracket\"/>\n      <xsd:enumeration value=\"rightBracket\"/>\n      <xsd:enumeration value=\"leftBrace\"/>\n      <xsd:enumeration value=\"rightBrace\"/>\n      <xsd:enumeration value=\"bracketPair\"/>\n      <xsd:enumeration value=\"bracePair\"/>\n      <xsd:enumeration value=\"straightConnector1\"/>\n      <xsd:enumeration value=\"bentConnector2\"/>\n      <xsd:enumeration value=\"bentConnector3\"/>\n      <xsd:enumeration value=\"bentConnector4\"/>\n      <xsd:enumeration value=\"bentConnector5\"/>\n      <xsd:enumeration value=\"curvedConnector2\"/>\n      <xsd:enumeration value=\"curvedConnector3\"/>\n      <xsd:enumeration value=\"curvedConnector4\"/>\n      <xsd:enumeration value=\"curvedConnector5\"/>\n      <xsd:enumeration value=\"callout1\"/>\n      <xsd:enumeration value=\"callout2\"/>\n      <xsd:enumeration value=\"callout3\"/>\n      <xsd:enumeration value=\"accentCallout1\"/>\n      <xsd:enumeration value=\"accentCallout2\"/>\n      <xsd:enumeration value=\"accentCallout3\"/>\n      <xsd:enumeration value=\"borderCallout1\"/>\n      <xsd:enumeration value=\"borderCallout2\"/>\n      <xsd:enumeration value=\"borderCallout3\"/>\n      <xsd:enumeration value=\"accentBorderCallout1\"/>\n      <xsd:enumeration value=\"accentBorderCallout2\"/>\n      <xsd:enumeration value=\"accentBorderCallout3\"/>\n      <xsd:enumeration value=\"wedgeRectCallout\"/>\n      <xsd:enumeration value=\"wedgeRoundRectCallout\"/>\n      <xsd:enumeration value=\"wedgeEllipseCallout\"/>\n      <xsd:enumeration value=\"cloudCallout\"/>\n      <xsd:enumeration value=\"cloud\"/>\n      <xsd:enumeration value=\"ribbon\"/>\n      <xsd:enumeration value=\"ribbon2\"/>\n      <xsd:enumeration value=\"ellipseRibbon\"/>\n      <xsd:enumeration value=\"ellipseRibbon2\"/>\n      <xsd:enumeration value=\"leftRightRibbon\"/>\n      <xsd:enumeration value=\"verticalScroll\"/>\n      <xsd:enumeration value=\"horizontalScroll\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"flowChartProcess\"/>\n      <xsd:enumeration value=\"flowChartDecision\"/>\n      <xsd:enumeration value=\"flowChartInputOutput\"/>\n      <xsd:enumeration value=\"flowChartPredefinedProcess\"/>\n      <xsd:enumeration value=\"flowChartInternalStorage\"/>\n      <xsd:enumeration value=\"flowChartDocument\"/>\n      <xsd:enumeration value=\"flowChartMultidocument\"/>\n      <xsd:enumeration value=\"flowChartTerminator\"/>\n      <xsd:enumeration value=\"flowChartPreparation\"/>\n      <xsd:enumeration value=\"flowChartManualInput\"/>\n      <xsd:enumeration value=\"flowChartManualOperation\"/>\n      <xsd:enumeration value=\"flowChartConnector\"/>\n      <xsd:enumeration value=\"flowChartPunchedCard\"/>\n      <xsd:enumeration value=\"flowChartPunchedTape\"/>\n      <xsd:enumeration value=\"flowChartSummingJunction\"/>\n      <xsd:enumeration value=\"flowChartOr\"/>\n      <xsd:enumeration value=\"flowChartCollate\"/>\n      <xsd:enumeration value=\"flowChartSort\"/>\n      <xsd:enumeration value=\"flowChartExtract\"/>\n      <xsd:enumeration value=\"flowChartMerge\"/>\n      <xsd:enumeration value=\"flowChartOfflineStorage\"/>\n      <xsd:enumeration value=\"flowChartOnlineStorage\"/>\n      <xsd:enumeration value=\"flowChartMagneticTape\"/>\n      <xsd:enumeration value=\"flowChartMagneticDisk\"/>\n      <xsd:enumeration value=\"flowChartMagneticDrum\"/>\n      <xsd:enumeration value=\"flowChartDisplay\"/>\n      <xsd:enumeration value=\"flowChartDelay\"/>\n      <xsd:enumeration value=\"flowChartAlternateProcess\"/>\n      <xsd:enumeration value=\"flowChartOffpageConnector\"/>\n      <xsd:enumeration value=\"actionButtonBlank\"/>\n      <xsd:enumeration value=\"actionButtonHome\"/>\n      <xsd:enumeration value=\"actionButtonHelp\"/>\n      <xsd:enumeration value=\"actionButtonInformation\"/>\n      <xsd:enumeration value=\"actionButtonForwardNext\"/>\n      <xsd:enumeration value=\"actionButtonBackPrevious\"/>\n      <xsd:enumeration value=\"actionButtonEnd\"/>\n      <xsd:enumeration value=\"actionButtonBeginning\"/>\n      <xsd:enumeration value=\"actionButtonReturn\"/>\n      <xsd:enumeration value=\"actionButtonDocument\"/>\n      <xsd:enumeration value=\"actionButtonSound\"/>\n      <xsd:enumeration value=\"actionButtonMovie\"/>\n      <xsd:enumeration value=\"gear6\"/>\n      <xsd:enumeration value=\"gear9\"/>\n      <xsd:enumeration value=\"funnel\"/>\n      <xsd:enumeration value=\"mathPlus\"/>\n      <xsd:enumeration value=\"mathMinus\"/>\n      <xsd:enumeration value=\"mathMultiply\"/>\n      <xsd:enumeration value=\"mathDivide\"/>\n      <xsd:enumeration value=\"mathEqual\"/>\n      <xsd:enumeration value=\"mathNotEqual\"/>\n      <xsd:enumeration value=\"cornerTabs\"/>\n      <xsd:enumeration value=\"squareTabs\"/>\n      <xsd:enumeration value=\"plaqueTabs\"/>\n      <xsd:enumeration value=\"chartX\"/>\n      <xsd:enumeration value=\"chartStar\"/>\n      <xsd:enumeration value=\"chartPlus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"textNoShape\"/>\n      <xsd:enumeration value=\"textPlain\"/>\n      <xsd:enumeration value=\"textStop\"/>\n      <xsd:enumeration value=\"textTriangle\"/>\n      <xsd:enumeration value=\"textTriangleInverted\"/>\n      <xsd:enumeration value=\"textChevron\"/>\n      <xsd:enumeration value=\"textChevronInverted\"/>\n      <xsd:enumeration value=\"textRingInside\"/>\n      <xsd:enumeration value=\"textRingOutside\"/>\n      <xsd:enumeration value=\"textArchUp\"/>\n      <xsd:enumeration value=\"textArchDown\"/>\n      <xsd:enumeration value=\"textCircle\"/>\n      <xsd:enumeration value=\"textButton\"/>\n      <xsd:enumeration value=\"textArchUpPour\"/>\n      <xsd:enumeration value=\"textArchDownPour\"/>\n      <xsd:enumeration value=\"textCirclePour\"/>\n      <xsd:enumeration value=\"textButtonPour\"/>\n      <xsd:enumeration value=\"textCurveUp\"/>\n      <xsd:enumeration value=\"textCurveDown\"/>\n      <xsd:enumeration value=\"textCanUp\"/>\n      <xsd:enumeration value=\"textCanDown\"/>\n      <xsd:enumeration value=\"textWave1\"/>\n      <xsd:enumeration value=\"textWave2\"/>\n      <xsd:enumeration value=\"textDoubleWave1\"/>\n      <xsd:enumeration value=\"textWave4\"/>\n      <xsd:enumeration value=\"textInflate\"/>\n      <xsd:enumeration value=\"textDeflate\"/>\n      <xsd:enumeration value=\"textInflateBottom\"/>\n      <xsd:enumeration value=\"textDeflateBottom\"/>\n      <xsd:enumeration value=\"textInflateTop\"/>\n      <xsd:enumeration value=\"textDeflateTop\"/>\n      <xsd:enumeration value=\"textDeflateInflate\"/>\n      <xsd:enumeration value=\"textDeflateInflateDeflate\"/>\n      <xsd:enumeration value=\"textFadeRight\"/>\n      <xsd:enumeration value=\"textFadeLeft\"/>\n      <xsd:enumeration value=\"textFadeUp\"/>\n      <xsd:enumeration value=\"textFadeDown\"/>\n      <xsd:enumeration value=\"textSlantUp\"/>\n      <xsd:enumeration value=\"textSlantDown\"/>\n      <xsd:enumeration value=\"textCascadeUp\"/>\n      <xsd:enumeration value=\"textCascadeDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideName\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideFormula\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GeomGuide\">\n    <xsd:attribute name=\"name\" type=\"ST_GeomGuideName\" use=\"required\"/>\n    <xsd:attribute name=\"fmla\" type=\"ST_GeomGuideFormula\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomGuideList\">\n    <xsd:sequence>\n      <xsd:element name=\"gd\" type=\"CT_GeomGuide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AdjCoordinate\">\n    <xsd:union memberTypes=\"ST_Coordinate ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AdjAngle\">\n    <xsd:union memberTypes=\"ST_Angle ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AdjPoint2D\">\n    <xsd:attribute name=\"x\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomRect\">\n    <xsd:attribute name=\"l\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XYAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefX\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefY\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolarAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefR\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefAng\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"maxAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSite\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ang\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjustHandleList\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"ahXY\" type=\"CT_XYAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahPolar\" type=\"CT_PolarAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSiteList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_ConnectionSite\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DMoveTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DLineTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DArcTo\">\n    <xsd:attribute name=\"wR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"hR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"stAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n    <xsd:attribute name=\"swAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DQuadBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DCubicBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"3\" maxOccurs=\"3\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DClose\"/>\n  <xsd:simpleType name=\"ST_PathFillMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"lighten\"/>\n      <xsd:enumeration value=\"lightenLess\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"darkenLess\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Path2D\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"close\" type=\"CT_Path2DClose\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_Path2DMoveTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTo\" type=\"CT_Path2DLineTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"arcTo\" type=\"CT_Path2DArcTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"quadBezTo\" type=\"CT_Path2DQuadBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cubicBezTo\" type=\"CT_Path2DCubicBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_PathFillMode\" use=\"optional\" default=\"norm\"/>\n    <xsd:attribute name=\"stroke\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"extrusionOk\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DList\">\n    <xsd:sequence>\n      <xsd:element name=\"path\" type=\"CT_Path2D\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_ShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_TextShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gdLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahLst\" type=\"CT_AdjustHandleList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_ConnectionSiteList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rect\" type=\"CT_GeomRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pathLst\" type=\"CT_Path2DList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Geometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstGeom\" type=\"CT_PresetGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextGeometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineEndType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"stealth\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"arrow\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndWidth\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndLength\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineEndProperties\">\n    <xsd:attribute name=\"type\" type=\"ST_LineEndType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"w\" type=\"ST_LineEndWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"len\" type=\"ST_LineEndLength\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineFillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineJoinBevel\"/>\n  <xsd:complexType name=\"CT_LineJoinRound\"/>\n  <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n    <xsd:attribute name=\"lim\" type=\"ST_PositivePercentage\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineJoinProperties\">\n    <xsd:choice>\n      <xsd:element name=\"round\" type=\"CT_LineJoinRound\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevel\" type=\"CT_LineJoinBevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PresetLineDashVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"lgDash\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"lgDashDot\"/>\n      <xsd:enumeration value=\"lgDashDotDot\"/>\n      <xsd:enumeration value=\"sysDash\"/>\n      <xsd:enumeration value=\"sysDot\"/>\n      <xsd:enumeration value=\"sysDashDot\"/>\n      <xsd:enumeration value=\"sysDashDotDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetLineDashProperties\">\n    <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStop\">\n    <xsd:attribute name=\"d\" type=\"ST_PositivePercentage\" use=\"required\"/>\n    <xsd:attribute name=\"sp\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"ds\" type=\"CT_DashStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineDashProperties\">\n    <xsd:choice>\n      <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDash\" type=\"CT_DashStopList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineCap\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rnd\"/>\n      <xsd:enumeration value=\"sq\"/>\n      <xsd:enumeration value=\"flat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineWidth\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"20116800\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PenAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CompoundLine\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"tri\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineFillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tailEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_LineWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_LineCap\" use=\"optional\"/>\n    <xsd:attribute name=\"cmpd\" type=\"ST_CompoundLine\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_PenAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShapeID\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Geometry\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_GroupTransform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrixReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_StyleMatrixColumnIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_FontCollectionIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefaultShapeDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectStyleDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"spDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_ColorMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bg1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"hlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"folHlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMappingOverride\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"masterClrMapping\" type=\"CT_EmptyElement\"/>\n        <xsd:element name=\"overrideClrMapping\" type=\"CT_ColorMapping\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeAndMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeList\">\n    <xsd:sequence>\n      <xsd:element name=\"extraClrScheme\" type=\"CT_ColorSchemeAndMapping\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"objectDefaults\" type=\"CT_ObjectStyleDefaults\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extraClrSchemeLst\" type=\"CT_ColorSchemeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custClrLst\" type=\"CT_CustomColorList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStylesOverride\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipboardStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"theme\" type=\"CT_OfficeStyleSheet\"/>\n  <xsd:element name=\"themeOverride\" type=\"CT_BaseStylesOverride\"/>\n  <xsd:element name=\"themeManager\" type=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_TableCellProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnL\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnR\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnT\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnB\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTlToBr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnBlToTr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marT\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"marB\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\" default=\"t\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\" default=\"clip\"\n    />\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"xsd:string\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCol\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableGrid\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TableCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCell\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TableCellProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rowSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"gridSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"hMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableRow\">\n    <xsd:sequence>\n      <xsd:element name=\"tc\" type=\"CT_TableCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"h\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\"/>\n        <xsd:element name=\"tableStyleId\" type=\"s:ST_Guid\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPr\" type=\"CT_TableProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TableGrid\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr\" type=\"CT_TableRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tbl\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Cell3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevel\" type=\"CT_Bevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\" default=\"plastic\"\n    />\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableFillStyle\">\n    <xsd:choice>\n      <xsd:element name=\"fill\" type=\"CT_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ThemeableLineStyle\">\n    <xsd:choice>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableEffectStyle\">\n    <xsd:choice>\n      <xsd:element name=\"effect\" type=\"CT_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ThemeableFontStyles\">\n    <xsd:choice>\n      <xsd:element name=\"font\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_OnOffStyleType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"def\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleTextStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFontStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"b\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n    <xsd:attribute name=\"i\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCellBorderStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"left\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideH\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideV\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableBackgroundStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableEffectStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleCellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcBdr\" type=\"CT_TableCellBorderStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePartStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcTxStyle\" type=\"CT_TableStyleTextStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcStyle\" type=\"CT_TableStyleCellStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tblBg\" type=\"CT_TableBackgroundStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wholeTbl\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"seCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"swCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"neCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nwCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"styleName\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"def\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"tblStyleLst\" type=\"CT_TableStyleList\"/>\n  <xsd:complexType name=\"CT_TextParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"endParaRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAnchoringType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"dist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVertOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"ellipsis\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextHorzOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVerticalType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"vert270\"/>\n      <xsd:enumeration value=\"wordArtVert\"/>\n      <xsd:enumeration value=\"eaVert\"/>\n      <xsd:enumeration value=\"mongolianVert\"/>\n      <xsd:enumeration value=\"wordArtVertRtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextWrappingType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"square\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextColumnCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"16\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextListStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"defPPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl1pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl2pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl3pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl4pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl5pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl6pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl7pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl8pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl9pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextFontScalePercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextFontScalePercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontScalePercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"1000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextNormalAutofit\">\n    <xsd:attribute name=\"fontScale\" type=\"ST_TextFontScalePercentOrPercentString\" use=\"optional\"\n      default=\"100%\"/>\n    <xsd:attribute name=\"lnSpcReduction\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"optional\"\n      default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextShapeAutofit\"/>\n  <xsd:complexType name=\"CT_TextNoAutofit\"/>\n  <xsd:group name=\"EG_TextAutofit\">\n    <xsd:choice>\n      <xsd:element name=\"noAutofit\" type=\"CT_TextNoAutofit\"/>\n      <xsd:element name=\"normAutofit\" type=\"CT_TextNormalAutofit\"/>\n      <xsd:element name=\"spAutoFit\" type=\"CT_TextShapeAutofit\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBodyProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextAutofit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"spcFirstLastPara\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"vertOverflow\" type=\"ST_TextVertOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_TextWrappingType\" use=\"optional\"/>\n    <xsd:attribute name=\"lIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"tIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"bIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"numCol\" type=\"ST_TextColumnCount\" use=\"optional\"/>\n    <xsd:attribute name=\"spcCol\" type=\"ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtlCol\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fromWordArt\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"forceAA\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"upright\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatLnSpc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBody\">\n    <xsd:sequence>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"p\" type=\"CT_TextParagraph\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextBulletStartAtNum\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"32767\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAutonumberScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"alphaLcParenBoth\"/>\n      <xsd:enumeration value=\"alphaUcParenBoth\"/>\n      <xsd:enumeration value=\"alphaLcParenR\"/>\n      <xsd:enumeration value=\"alphaUcParenR\"/>\n      <xsd:enumeration value=\"alphaLcPeriod\"/>\n      <xsd:enumeration value=\"alphaUcPeriod\"/>\n      <xsd:enumeration value=\"arabicParenBoth\"/>\n      <xsd:enumeration value=\"arabicParenR\"/>\n      <xsd:enumeration value=\"arabicPeriod\"/>\n      <xsd:enumeration value=\"arabicPlain\"/>\n      <xsd:enumeration value=\"romanLcParenBoth\"/>\n      <xsd:enumeration value=\"romanUcParenBoth\"/>\n      <xsd:enumeration value=\"romanLcParenR\"/>\n      <xsd:enumeration value=\"romanUcParenR\"/>\n      <xsd:enumeration value=\"romanLcPeriod\"/>\n      <xsd:enumeration value=\"romanUcPeriod\"/>\n      <xsd:enumeration value=\"circleNumDbPlain\"/>\n      <xsd:enumeration value=\"circleNumWdBlackPlain\"/>\n      <xsd:enumeration value=\"circleNumWdWhitePlain\"/>\n      <xsd:enumeration value=\"arabicDbPeriod\"/>\n      <xsd:enumeration value=\"arabicDbPlain\"/>\n      <xsd:enumeration value=\"ea1ChsPeriod\"/>\n      <xsd:enumeration value=\"ea1ChsPlain\"/>\n      <xsd:enumeration value=\"ea1ChtPeriod\"/>\n      <xsd:enumeration value=\"ea1ChtPlain\"/>\n      <xsd:enumeration value=\"ea1JpnChsDbPeriod\"/>\n      <xsd:enumeration value=\"ea1JpnKorPlain\"/>\n      <xsd:enumeration value=\"ea1JpnKorPeriod\"/>\n      <xsd:enumeration value=\"arabic1Minus\"/>\n      <xsd:enumeration value=\"arabic2Minus\"/>\n      <xsd:enumeration value=\"hebrew2Minus\"/>\n      <xsd:enumeration value=\"thaiAlphaPeriod\"/>\n      <xsd:enumeration value=\"thaiAlphaParenR\"/>\n      <xsd:enumeration value=\"thaiAlphaParenBoth\"/>\n      <xsd:enumeration value=\"thaiNumPeriod\"/>\n      <xsd:enumeration value=\"thaiNumParenR\"/>\n      <xsd:enumeration value=\"thaiNumParenBoth\"/>\n      <xsd:enumeration value=\"hindiAlphaPeriod\"/>\n      <xsd:enumeration value=\"hindiNumPeriod\"/>\n      <xsd:enumeration value=\"hindiNumParenR\"/>\n      <xsd:enumeration value=\"hindiAlpha1Period\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletColorFollowText\"/>\n  <xsd:group name=\"EG_TextBulletColor\">\n    <xsd:choice>\n      <xsd:element name=\"buClrTx\" type=\"CT_TextBulletColorFollowText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"buClr\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextBulletSize\">\n    <xsd:union memberTypes=\"ST_TextBulletSizePercent ST_TextBulletSizeDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*((2[5-9])|([3-9][0-9])|([1-3][0-9][0-9])|400)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizeDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"25000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletSizeFollowText\"/>\n  <xsd:complexType name=\"CT_TextBulletSizePercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextBulletSizePercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBulletSizePoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextFontSize\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextBulletSize\">\n    <xsd:choice>\n      <xsd:element name=\"buSzTx\" type=\"CT_TextBulletSizeFollowText\"/>\n      <xsd:element name=\"buSzPct\" type=\"CT_TextBulletSizePercent\"/>\n      <xsd:element name=\"buSzPts\" type=\"CT_TextBulletSizePoint\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBulletTypefaceFollowText\"/>\n  <xsd:group name=\"EG_TextBulletTypeface\">\n    <xsd:choice>\n      <xsd:element name=\"buFontTx\" type=\"CT_TextBulletTypefaceFollowText\"/>\n      <xsd:element name=\"buFont\" type=\"CT_TextFont\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextAutonumberBullet\">\n    <xsd:attribute name=\"type\" type=\"ST_TextAutonumberScheme\" use=\"required\"/>\n    <xsd:attribute name=\"startAt\" type=\"ST_TextBulletStartAtNum\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextCharBullet\">\n    <xsd:attribute name=\"char\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBlipBullet\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextNoBullet\"/>\n  <xsd:group name=\"EG_TextBullet\">\n    <xsd:choice>\n      <xsd:element name=\"buNone\" type=\"CT_TextNoBullet\"/>\n      <xsd:element name=\"buAutoNum\" type=\"CT_TextAutonumberBullet\"/>\n      <xsd:element name=\"buChar\" type=\"CT_TextCharBullet\"/>\n      <xsd:element name=\"buBlip\" type=\"CT_TextBlipBullet\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextPoint\">\n    <xsd:union memberTypes=\"ST_TextPointUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextPointUnqualified\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-400000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextNonNegativePoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontSize\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"100\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTypeface\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PitchFamily\">\n   <xsd:restriction base=\"xsd:byte\">\n     <xsd:enumeration value=\"00\"/>\n     <xsd:enumeration value=\"01\"/>\n     <xsd:enumeration value=\"02\"/>\n     <xsd:enumeration value=\"16\"/>\n     <xsd:enumeration value=\"17\"/>\n     <xsd:enumeration value=\"18\"/>\n     <xsd:enumeration value=\"32\"/>\n     <xsd:enumeration value=\"33\"/>\n     <xsd:enumeration value=\"34\"/>\n     <xsd:enumeration value=\"48\"/>\n     <xsd:enumeration value=\"49\"/>\n     <xsd:enumeration value=\"50\"/>\n     <xsd:enumeration value=\"64\"/>\n     <xsd:enumeration value=\"65\"/>\n     <xsd:enumeration value=\"66\"/>\n     <xsd:enumeration value=\"80\"/>\n     <xsd:enumeration value=\"81\"/>\n     <xsd:enumeration value=\"82\"/>\n   </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_TextFont\">\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n    <xsd:attribute name=\"panose\" type=\"s:ST_Panose\" use=\"optional\"/>\n    <xsd:attribute name=\"pitchFamily\" type=\"ST_PitchFamily\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"charset\" type=\"xsd:byte\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextUnderlineType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDashHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dotDotDashHeavy\"/>\n      <xsd:enumeration value=\"wavy\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDbl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextUnderlineLineFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillGroupWrapper\">\n    <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextUnderlineLine\">\n    <xsd:choice>\n      <xsd:element name=\"uLnTx\" type=\"CT_TextUnderlineLineFollowText\"/>\n      <xsd:element name=\"uLn\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextUnderlineFill\">\n    <xsd:choice>\n      <xsd:element name=\"uFillTx\" type=\"CT_TextUnderlineFillFollowText\"/>\n      <xsd:element name=\"uFill\" type=\"CT_TextUnderlineFillGroupWrapper\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextStrikeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"noStrike\"/>\n      <xsd:enumeration value=\"sngStrike\"/>\n      <xsd:enumeration value=\"dblStrike\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextCapsType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"small\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextCharacterProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineLine\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sym\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkMouseOver\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rtl\" type=\"CT_Boolean\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"kumimoji\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"altLang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_TextFontSize\" use=\"optional\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"u\" type=\"ST_TextUnderlineType\" use=\"optional\"/>\n    <xsd:attribute name=\"strike\" type=\"ST_TextStrikeType\" use=\"optional\"/>\n    <xsd:attribute name=\"kern\" type=\"ST_TextNonNegativePoint\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_TextCapsType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"spc\" type=\"ST_TextPoint\" use=\"optional\"/>\n    <xsd:attribute name=\"normalizeH\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"baseline\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"noProof\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"dirty\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"err\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"smtClean\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"smtId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bmk\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextSpacingPoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"158400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextSpacingPercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"13200000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextSpacingPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacingPoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPoint\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextMargin\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndent\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"-51206400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTabAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"dec\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextTabStop\">\n    <xsd:attribute name=\"pos\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextTabAlignType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextTabStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TextTabStop\" minOccurs=\"0\" maxOccurs=\"32\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLineBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacing\">\n    <xsd:choice>\n      <xsd:element name=\"spcPct\" type=\"CT_TextSpacingPercent\"/>\n      <xsd:element name=\"spcPts\" type=\"CT_TextSpacingPoint\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"justLow\"/>\n      <xsd:enumeration value=\"dist\"/>\n      <xsd:enumeration value=\"thaiDist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndentLevelType\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"8\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextParagraphProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnSpc\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcBef\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcAft\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletColor\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletTypeface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBullet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tabLst\" type=\"CT_TextTabStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"defRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"lvl\" type=\"ST_TextIndentLevelType\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"ST_TextIndent\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"defTabSz\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"eaLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fontAlgn\" type=\"ST_TextFontAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"latinLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingPunct\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextRun\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_RegularTextRun\"/>\n      <xsd:element name=\"br\" type=\"CT_TextLineBreak\"/>\n      <xsd:element name=\"fld\" type=\"CT_TextField\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RegularTextRun\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"shared-relationshipReference.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>\n  <xsd:element name=\"from\" type=\"CT_Marker\"/>\n  <xsd:element name=\"to\" type=\"CT_Marker\"/>\n  <xsd:complexType name=\"CT_AnchorClientData\">\n    <xsd:attribute name=\"fLocksWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPrintsWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ColID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RowID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"ST_ColID\"/>\n      <xsd:element name=\"colOff\" type=\"a:ST_Coordinate\"/>\n      <xsd:element name=\"row\" type=\"ST_RowID\"/>\n      <xsd:element name=\"rowOff\" type=\"a:ST_Coordinate\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"twoCell\"/>\n      <xsd:enumeration value=\"oneCell\"/>\n      <xsd:enumeration value=\"absolute\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TwoCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"editAs\" type=\"ST_EditAs\" use=\"optional\" default=\"twoCell\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OneCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsoluteAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"twoCellAnchor\" type=\"CT_TwoCellAnchor\"/>\n      <xsd:element name=\"oneCellAnchor\" type=\"CT_OneCellAnchor\"/>\n      <xsd:element name=\"absoluteAnchor\" type=\"CT_AbsoluteAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wsDr\" type=\"CT_Drawing\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:dpct=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"wml.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:complexType name=\"CT_EffectExtent\">\n    <xsd:attribute name=\"l\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapDistance\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Inline\">\n    <xsd:sequence>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapText\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bothSides\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WrapPath\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lineTo\" type=\"a:CT_Point2D\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"edited\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapNone\"/>\n  <xsd:complexType name=\"CT_WrapSquare\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTight\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapThrough\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTopBottom\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_WrapType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"wrapNone\" type=\"CT_WrapNone\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapSquare\" type=\"CT_WrapSquare\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTight\" type=\"CT_WrapTight\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapThrough\" type=\"CT_WrapThrough\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTopAndBottom\" type=\"CT_WrapTopBottom\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PositionOffset\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlignH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"leftMargin\"/>\n      <xsd:enumeration value=\"rightMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosH\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignH\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromH\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlignV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"topMargin\"/>\n      <xsd:enumeration value=\"bottomMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosV\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignV\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromV\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Anchor\">\n    <xsd:sequence>\n      <xsd:element name=\"simplePos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"positionH\" type=\"CT_PosH\"/>\n      <xsd:element name=\"positionV\" type=\"CT_PosV\"/>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_WrapType\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"simplePos\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"relativeHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"behindDoc\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"layoutInCell\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"allowOverlap\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"w:EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextboxInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinkedTextboxInformation\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"seq\" type=\"xsd:unsignedShort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingShape\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"cNvCnPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"txbx\" type=\"CT_TextboxInfo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"linkedTxbx\" type=\"CT_LinkedTextboxInformation\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"bodyPr\" type=\"a:CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"normalEastAsianFlow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvFrPr\" type=\"a:CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPartNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvContentPartPr\" type=\"a:CT_NonVisualContentPartProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPart\">\n    <xsd:sequence>\n      <xsd:element name=\"nvContentPartPr\" type=\"CT_WordprocessingContentPartNonVisual\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingGroup\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_WordprocessingGroup\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingCanvas\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n        <xsd:element ref=\"wgp\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wpc\" type=\"CT_WordprocessingCanvas\"/>\n  <xsd:element name=\"wgp\" type=\"CT_WordprocessingGroup\"/>\n  <xsd:element name=\"wsp\" type=\"CT_WordprocessingShape\"/>\n  <xsd:element name=\"inline\" type=\"CT_Inline\"/>\n  <xsd:element name=\"anchor\" type=\"CT_Anchor\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_TransitionSideDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"d\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionCornerDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"lu\"/>\n      <xsd:enumeration value=\"ru\"/>\n      <xsd:enumeration value=\"ld\"/>\n      <xsd:enumeration value=\"rd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionInOutDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SideDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionSideDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CornerDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionCornerDirectionType\" use=\"optional\" default=\"lu\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionEightDirectionType\">\n    <xsd:union memberTypes=\"ST_TransitionSideDirectionType ST_TransitionCornerDirectionType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EightDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionEightDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OrientationTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InOutTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptionalBlackTransition\">\n    <xsd:attribute name=\"thruBlk\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SplitTransition\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WheelTransition\">\n    <xsd:attribute name=\"spokes\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"4\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionStartSoundAction\">\n    <xsd:sequence>\n      <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"snd\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionSoundAction\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"stSnd\" type=\"CT_TransitionStartSoundAction\"/>\n      <xsd:element name=\"endSnd\" type=\"CT_Empty\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionSpeed\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slow\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"fast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideTransition\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"blinds\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"checker\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"circle\" type=\"CT_Empty\"/>\n        <xsd:element name=\"dissolve\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comb\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"cover\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"cut\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"diamond\" type=\"CT_Empty\"/>\n        <xsd:element name=\"fade\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"newsflash\" type=\"CT_Empty\"/>\n        <xsd:element name=\"plus\" type=\"CT_Empty\"/>\n        <xsd:element name=\"pull\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"push\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"random\" type=\"CT_Empty\"/>\n        <xsd:element name=\"randomBar\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"split\" type=\"CT_SplitTransition\"/>\n        <xsd:element name=\"strips\" type=\"CT_CornerDirectionTransition\"/>\n        <xsd:element name=\"wedge\" type=\"CT_Empty\"/>\n        <xsd:element name=\"wheel\" type=\"CT_WheelTransition\"/>\n        <xsd:element name=\"wipe\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"zoom\" type=\"CT_InOutTransition\"/>\n      </xsd:choice>\n      <xsd:element name=\"sndAc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TransitionSoundAction\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"spd\" type=\"ST_TransitionSpeed\" use=\"optional\" default=\"fast\"/>\n    <xsd:attribute name=\"advClick\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"advTm\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeIndefinite\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"indefinite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTime\">\n    <xsd:union memberTypes=\"xsd:unsignedInt ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeID\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateIntervalTime\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLIterateIntervalPercentage\">\n    <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_IterateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"el\"/>\n      <xsd:enumeration value=\"wd\"/>\n      <xsd:enumeration value=\"lt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateData\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"tmAbs\" type=\"CT_TLIterateIntervalTime\"/>\n      <xsd:element name=\"tmPct\" type=\"CT_TLIterateIntervalPercentage\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_IterateType\" use=\"optional\" default=\"el\"/>\n    <xsd:attribute name=\"backwards\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSubShapeId\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTextTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"charRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"pRg\" type=\"CT_IndexRange\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLChartSubelementType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"gridLegend\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleChartTargetElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TLChartSubelementType\" use=\"required\"/>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLShapeTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"CT_Empty\"/>\n      <xsd:element name=\"subSp\" type=\"CT_TLSubShapeId\"/>\n      <xsd:element name=\"oleChartEl\" type=\"CT_TLOleChartTargetElement\"/>\n      <xsd:element name=\"txEl\" type=\"CT_TLTextTargetElement\"/>\n      <xsd:element name=\"graphicEl\" type=\"a:CT_AnimationElementChoice\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeTargetElement\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"sldTgt\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sndTgt\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"spTgt\" type=\"CT_TLShapeTargetElement\"/>\n      <xsd:element name=\"inkTgt\" type=\"CT_TLSubShapeId\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTriggerTimeNodeID\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTimeNodeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerRuntimeNode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"first\"/>\n      <xsd:enumeration value=\"last\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTriggerRuntimeNode\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTriggerRuntimeNode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerEvent\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"onBegin\"/>\n      <xsd:enumeration value=\"onEnd\"/>\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"onClick\"/>\n      <xsd:enumeration value=\"onDblClick\"/>\n      <xsd:enumeration value=\"onMouseOver\"/>\n      <xsd:enumeration value=\"onMouseOut\"/>\n      <xsd:enumeration value=\"onNext\"/>\n      <xsd:enumeration value=\"onPrev\"/>\n      <xsd:enumeration value=\"onStopAudio\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeCondition\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\"/>\n      <xsd:element name=\"tn\" type=\"CT_TLTriggerTimeNodeID\"/>\n      <xsd:element name=\"rtn\" type=\"CT_TLTriggerRuntimeNode\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"evt\" use=\"optional\" type=\"ST_TLTriggerEvent\"/>\n    <xsd:attribute name=\"delay\" type=\"ST_TLTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeConditionList\">\n    <xsd:sequence>\n      <xsd:element name=\"cond\" type=\"CT_TLTimeCondition\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TimeNodeList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"par\" type=\"CT_TLTimeNodeParallel\"/>\n      <xsd:element name=\"seq\" type=\"CT_TLTimeNodeSequence\"/>\n      <xsd:element name=\"excl\" type=\"CT_TLTimeNodeExclusive\"/>\n      <xsd:element name=\"anim\" type=\"CT_TLAnimateBehavior\"/>\n      <xsd:element name=\"animClr\" type=\"CT_TLAnimateColorBehavior\"/>\n      <xsd:element name=\"animEffect\" type=\"CT_TLAnimateEffectBehavior\"/>\n      <xsd:element name=\"animMotion\" type=\"CT_TLAnimateMotionBehavior\"/>\n      <xsd:element name=\"animRot\" type=\"CT_TLAnimateRotationBehavior\"/>\n      <xsd:element name=\"animScale\" type=\"CT_TLAnimateScaleBehavior\"/>\n      <xsd:element name=\"cmd\" type=\"CT_TLCommandBehavior\"/>\n      <xsd:element name=\"set\" type=\"CT_TLSetBehavior\"/>\n      <xsd:element name=\"audio\" type=\"CT_TLMediaNodeAudio\"/>\n      <xsd:element name=\"video\" type=\"CT_TLMediaNodeVideo\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeNodePresetClassType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"entr\"/>\n      <xsd:enumeration value=\"exit\"/>\n      <xsd:enumeration value=\"emph\"/>\n      <xsd:enumeration value=\"path\"/>\n      <xsd:enumeration value=\"verb\"/>\n      <xsd:enumeration value=\"mediacall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeRestartType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"whenNotActive\"/>\n      <xsd:enumeration value=\"never\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeFillType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"remove\"/>\n      <xsd:enumeration value=\"freeze\"/>\n      <xsd:enumeration value=\"hold\"/>\n      <xsd:enumeration value=\"transition\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeSyncType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"canSlip\"/>\n      <xsd:enumeration value=\"locked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeMasterRelation\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sameClick\"/>\n      <xsd:enumeration value=\"lastClick\"/>\n      <xsd:enumeration value=\"nextClick\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clickEffect\"/>\n      <xsd:enumeration value=\"withEffect\"/>\n      <xsd:enumeration value=\"afterEffect\"/>\n      <xsd:enumeration value=\"mainSeq\"/>\n      <xsd:enumeration value=\"interactiveSeq\"/>\n      <xsd:enumeration value=\"clickPar\"/>\n      <xsd:enumeration value=\"withGroup\"/>\n      <xsd:enumeration value=\"afterGroup\"/>\n      <xsd:enumeration value=\"tmRoot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonTimeNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"stCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endSync\" type=\"CT_TLTimeCondition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iterate\" type=\"CT_TLIterateData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"childTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"subTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_TLTimeNodeID\" use=\"optional\"/>\n    <xsd:attribute name=\"presetID\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presetClass\" type=\"ST_TLTimeNodePresetClassType\" use=\"optional\"/>\n    <xsd:attribute name=\"presetSubtype\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"dur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"repeatCount\" type=\"ST_TLTime\" use=\"optional\" default=\"1000\"/>\n    <xsd:attribute name=\"repeatDur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"spd\" type=\"a:ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"accel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"decel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"autoRev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_TLTimeNodeRestartType\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_TLTimeNodeFillType\" use=\"optional\"/>\n    <xsd:attribute name=\"syncBehavior\" type=\"ST_TLTimeNodeSyncType\" use=\"optional\"/>\n    <xsd:attribute name=\"tmFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"evtFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"masterRel\" type=\"ST_TLTimeNodeMasterRelation\" use=\"optional\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"afterEffect\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nodeType\" type=\"ST_TLTimeNodeType\" use=\"optional\"/>\n    <xsd:attribute name=\"nodePh\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeParallel\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLNextActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"seek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLPreviousActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"skipTimed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeNodeSequence\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prevCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nextCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"concurrent\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"prevAc\" type=\"ST_TLPreviousActionType\" use=\"optional\"/>\n    <xsd:attribute name=\"nextAc\" type=\"ST_TLNextActionType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeExclusive\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLBehaviorAttributeNameList\">\n    <xsd:sequence>\n      <xsd:element name=\"attrName\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLBehaviorAdditiveType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"repl\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorAccumulateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorTransformType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pt\"/>\n      <xsd:enumeration value=\"img\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorOverrideType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"childStyle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonBehaviorData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attrNameLst\" type=\"CT_TLBehaviorAttributeNameList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"additive\" type=\"ST_TLBehaviorAdditiveType\" use=\"optional\"/>\n    <xsd:attribute name=\"accumulate\" type=\"ST_TLBehaviorAccumulateType\" use=\"optional\"/>\n    <xsd:attribute name=\"xfrmType\" type=\"ST_TLBehaviorTransformType\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rctx\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"override\" type=\"ST_TLBehaviorOverrideType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantBooleanVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantIntegerVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantFloatVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:float\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantStringVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"boolVal\" type=\"CT_TLAnimVariantBooleanVal\"/>\n      <xsd:element name=\"intVal\" type=\"CT_TLAnimVariantIntegerVal\"/>\n      <xsd:element name=\"fltVal\" type=\"CT_TLAnimVariantFloatVal\"/>\n      <xsd:element name=\"strVal\" type=\"CT_TLAnimVariantStringVal\"/>\n      <xsd:element name=\"clrVal\" type=\"a:CT_Color\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeAnimateValueTime\">\n    <xsd:union memberTypes=\"a:ST_PositiveFixedPercentage ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tm\" type=\"ST_TLTimeAnimateValueTime\" use=\"optional\" default=\"indefinite\"/>\n    <xsd:attribute name=\"fmla\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValueList\">\n    <xsd:sequence>\n      <xsd:element name=\"tav\" type=\"CT_TLTimeAnimateValue\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorCalcMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"discrete\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"fmla\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorValueType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tavLst\" type=\"CT_TLTimeAnimateValueList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"calcmode\" type=\"ST_TLAnimateBehaviorCalcMode\" use=\"optional\"/>\n    <xsd:attribute name=\"valueType\" type=\"ST_TLAnimateBehaviorValueType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByRgbColorTransform\">\n    <xsd:attribute name=\"r\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByHslColorTransform\">\n    <xsd:attribute name=\"h\" type=\"a:ST_Angle\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"l\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByAnimateColorTransform\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"rgb\" type=\"CT_TLByRgbColorTransform\"/>\n      <xsd:element name=\"hsl\" type=\"CT_TLByHslColorTransform\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateColorSpace\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rgb\"/>\n      <xsd:enumeration value=\"hsl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateColorDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateColorBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLByAnimateColorTransform\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"clrSpc\" type=\"ST_TLAnimateColorSpace\" use=\"optional\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TLAnimateColorDirection\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateEffectTransition\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateEffectBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"progress\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"transition\" type=\"ST_TLAnimateEffectTransition\" default=\"in\" use=\"optional\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"prLst\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionBehaviorOrigin\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parent\"/>\n      <xsd:enumeration value=\"layout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionPathEditMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relative\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLPoint\">\n    <xsd:attribute name=\"x\" type=\"a:ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"a:ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateMotionBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rCtr\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"origin\" type=\"ST_TLAnimateMotionBehaviorOrigin\" use=\"optional\"/>\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"pathEditMode\" type=\"ST_TLAnimateMotionPathEditMode\" use=\"optional\"/>\n    <xsd:attribute name=\"rAng\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"ptsTypes\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateRotationBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"a:ST_Angle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateScaleBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zoomContents\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLCommandType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"evt\"/>\n      <xsd:enumeration value=\"call\"/>\n      <xsd:enumeration value=\"verb\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommandBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute type=\"ST_TLCommandType\" name=\"type\" use=\"optional\"/>\n    <xsd:attribute name=\"cmd\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSetBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLCommonMediaNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"vol\" type=\"a:ST_PositiveFixedPercentage\" default=\"50%\" use=\"optional\"/>\n    <xsd:attribute name=\"mute\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numSld\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showWhenStopped\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeAudio\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeVideo\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullScrn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_TLBuild\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uiExpand\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_TLTemplate\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTemplateList\">\n    <xsd:sequence>\n      <xsd:element name=\"tmpl\" type=\"CT_TLTemplate\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLParaBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"whole\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"tmplLst\" type=\"CT_TLTemplateList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"build\" type=\"ST_TLParaBuildType\" use=\"optional\" default=\"whole\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoUpdateAnimBg\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advAuto\" type=\"ST_TLTime\" use=\"optional\" default=\"indefinite\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLDiagramBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"depthByNode\"/>\n      <xsd:enumeration value=\"depthByBranch\"/>\n      <xsd:enumeration value=\"breadthByNode\"/>\n      <xsd:enumeration value=\"breadthByLvl\"/>\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"cwIn\"/>\n      <xsd:enumeration value=\"cwOut\"/>\n      <xsd:enumeration value=\"ccw\"/>\n      <xsd:enumeration value=\"ccwIn\"/>\n      <xsd:enumeration value=\"ccwOut\"/>\n      <xsd:enumeration value=\"inByRing\"/>\n      <xsd:enumeration value=\"outByRing\"/>\n      <xsd:enumeration value=\"up\"/>\n      <xsd:enumeration value=\"down\"/>\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildDiagram\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLDiagramBuildType\" use=\"optional\" default=\"whole\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLOleChartBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleBuildChart\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLOleChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLGraphicalObjectBuild\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bldAsOne\" type=\"CT_Empty\"/>\n      <xsd:element name=\"bldSub\" type=\"a:CT_AnimationGraphicalObjectBuildProperties\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BuildList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bldP\" type=\"CT_TLBuildParagraph\"/>\n      <xsd:element name=\"bldDgm\" type=\"CT_TLBuildDiagram\"/>\n      <xsd:element name=\"bldOleChart\" type=\"CT_TLOleBuildChart\"/>\n      <xsd:element name=\"bldGraphic\" type=\"CT_TLGraphicalObjectBuild\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideTiming\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bldLst\" type=\"CT_BuildList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:simpleType name=\"ST_Name\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IndexRange\">\n    <xsd:attribute name=\"st\" type=\"ST_Index\" use=\"required\"/>\n    <xsd:attribute name=\"end\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipListEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_SlideRelationshipListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowId\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SlideListChoice\">\n    <xsd:choice>\n      <xsd:element name=\"sldAll\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sldRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShowId\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CustomerData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagsData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomerDataList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"custData\" type=\"CT_CustomerData\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tags\" type=\"CT_TagsData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionListModify\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mod\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthor\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"initials\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"lastIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"clrIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthorList\">\n    <xsd:sequence>\n      <xsd:element name=\"cmAuthor\" type=\"CT_CommentAuthor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmAuthorLst\" type=\"CT_CommentAuthorList\"/>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"text\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"idx\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"cm\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmLst\" type=\"CT_CommentList\"/>\n  <xsd:attributeGroup name=\"AG_Ole\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"showAsIcon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"imgW\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"imgH\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:simpleType name=\"ST_OleObjectFollowColorScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"textAndBackground\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleObjectEmbed\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"followColorScheme\" type=\"ST_OleObjectFollowColorScheme\" use=\"optional\"\n      default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjectLink\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"updateAutomatic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"embed\" type=\"CT_OleObjectEmbed\"/>\n        <xsd:element name=\"link\" type=\"CT_OleObjectLink\"/>\n      </xsd:choice>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"oleObj\" type=\"CT_OleObject\"/>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlList\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"256\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideId\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldId\" type=\"CT_SlideIdListEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideMasterId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideMasterId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterId\" type=\"CT_SlideMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"notesMasterId\" type=\"CT_NotesMasterIdListEntry\" minOccurs=\"0\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"handoutMasterId\" type=\"CT_HandoutMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontDataId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"a:CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"regular\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bold\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"italic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"boldItalic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontList\">\n    <xsd:sequence>\n      <xsd:element name=\"embeddedFont\" type=\"CT_EmbeddedFontListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShow\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLst\" type=\"CT_SlideRelationshipList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowList\">\n    <xsd:sequence>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhotoAlbumLayout\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fitToSlide\"/>\n      <xsd:enumeration value=\"1pic\"/>\n      <xsd:enumeration value=\"2pic\"/>\n      <xsd:enumeration value=\"4pic\"/>\n      <xsd:enumeration value=\"1picTitle\"/>\n      <xsd:enumeration value=\"2picTitle\"/>\n      <xsd:enumeration value=\"4picTitle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhotoAlbumFrameShape\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"frameStyle1\"/>\n      <xsd:enumeration value=\"frameStyle2\"/>\n      <xsd:enumeration value=\"frameStyle3\"/>\n      <xsd:enumeration value=\"frameStyle4\"/>\n      <xsd:enumeration value=\"frameStyle5\"/>\n      <xsd:enumeration value=\"frameStyle6\"/>\n      <xsd:enumeration value=\"frameStyle7\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhotoAlbum\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bw\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showCaptions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"layout\" type=\"ST_PhotoAlbumLayout\" use=\"optional\" default=\"fitToSlide\"/>\n    <xsd:attribute name=\"frame\" type=\"ST_PhotoAlbumFrameShape\" use=\"optional\" default=\"frameStyle1\"\n    />\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideSizeCoordinate\">\n    <xsd:restriction base=\"a:ST_PositiveCoordinate32\">\n      <xsd:minInclusive value=\"914400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SlideSizeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"screen4x3\"/>\n      <xsd:enumeration value=\"letter\"/>\n      <xsd:enumeration value=\"A4\"/>\n      <xsd:enumeration value=\"35mm\"/>\n      <xsd:enumeration value=\"overhead\"/>\n      <xsd:enumeration value=\"banner\"/>\n      <xsd:enumeration value=\"custom\"/>\n      <xsd:enumeration value=\"ledger\"/>\n      <xsd:enumeration value=\"A3\"/>\n      <xsd:enumeration value=\"B4ISO\"/>\n      <xsd:enumeration value=\"B5ISO\"/>\n      <xsd:enumeration value=\"B4JIS\"/>\n      <xsd:enumeration value=\"B5JIS\"/>\n      <xsd:enumeration value=\"hagakiCard\"/>\n      <xsd:enumeration value=\"screen16x9\"/>\n      <xsd:enumeration value=\"screen16x10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideSize\">\n    <xsd:attribute name=\"cx\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideSizeType\" use=\"optional\" default=\"custom\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"invalStChars\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"invalEndChars\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BookmarkIdSeed\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ModifyVerifier\">\n    <xsd:attribute name=\"algorithmName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinValue\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"saltData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"hashData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Presentation\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterIdLst\" type=\"CT_SlideMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesMasterIdLst\" type=\"CT_NotesMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"handoutMasterIdLst\" type=\"CT_HandoutMasterIdList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sldIdLst\" type=\"CT_SlideIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldSz\" type=\"CT_SlideSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesSz\" type=\"a:CT_PositiveSize2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embeddedFontLst\" type=\"CT_EmbeddedFontList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custShowLst\" type=\"CT_CustomShowList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"photoAlbum\" type=\"CT_PhotoAlbum\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTextStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"modifyVerifier\" type=\"CT_ModifyVerifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverZoom\" type=\"a:ST_Percentage\" use=\"optional\" default=\"50%\"/>\n    <xsd:attribute name=\"firstSlideNum\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showSpecialPlsOnTitleSld\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removePersonalInfoOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"strictFirstAndLastChars\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"embedTrueTypeFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveSubsetFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"bookmarkIdSeed\" type=\"ST_BookmarkIdSeed\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:element name=\"presentation\" type=\"CT_Presentation\"/>\n  <xsd:complexType name=\"CT_HtmlPublishProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showSpeakerNotes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebColorType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"browser\"/>\n      <xsd:enumeration value=\"presentationText\"/>\n      <xsd:enumeration value=\"presentationAccent\"/>\n      <xsd:enumeration value=\"whiteTextOnBlack\"/>\n      <xsd:enumeration value=\"blackTextOnWhite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebScreenSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1400\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebEncoding\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"resizeGraphics\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"relyOnVml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"organizeInFolders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useLongFilenames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"imgSz\" type=\"ST_WebScreenSize\" use=\"optional\" default=\"800x600\"/>\n    <xsd:attribute name=\"encoding\" type=\"ST_WebEncoding\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"clr\" type=\"ST_WebColorType\" use=\"optional\" default=\"whiteTextOnBlack\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintWhat\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slides\"/>\n      <xsd:enumeration value=\"handouts1\"/>\n      <xsd:enumeration value=\"handouts2\"/>\n      <xsd:enumeration value=\"handouts3\"/>\n      <xsd:enumeration value=\"handouts4\"/>\n      <xsd:enumeration value=\"handouts6\"/>\n      <xsd:enumeration value=\"handouts9\"/>\n      <xsd:enumeration value=\"notes\"/>\n      <xsd:enumeration value=\"outline\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrintColorMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bw\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PrintProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prnWhat\" type=\"ST_PrintWhat\" use=\"optional\" default=\"slides\"/>\n    <xsd:attribute name=\"clrMode\" type=\"ST_PrintColorMode\" use=\"optional\" default=\"clr\"/>\n    <xsd:attribute name=\"hiddenSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scaleToFitPaper\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"frameSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoBrowse\">\n    <xsd:attribute name=\"showScrollbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoKiosk\">\n    <xsd:attribute name=\"restart\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"300000\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShowType\">\n    <xsd:choice>\n      <xsd:element name=\"present\" type=\"CT_Empty\"/>\n      <xsd:element name=\"browse\" type=\"CT_ShowInfoBrowse\"/>\n      <xsd:element name=\"kiosk\" type=\"CT_ShowInfoKiosk\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ShowProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:group ref=\"EG_ShowType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"penClr\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useTimings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"htmlPubPr\" type=\"CT_HtmlPublishProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPr\" type=\"CT_WebProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prnPr\" type=\"CT_PrintProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPr\" type=\"CT_ShowProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMru\" type=\"a:CT_ColorMRU\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"presentationPr\" type=\"CT_PresentationProperties\"/>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sldNum\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"hdr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"ftr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PlaceholderType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"body\"/>\n      <xsd:enumeration value=\"ctrTitle\"/>\n      <xsd:enumeration value=\"subTitle\"/>\n      <xsd:enumeration value=\"dt\"/>\n      <xsd:enumeration value=\"sldNum\"/>\n      <xsd:enumeration value=\"ftr\"/>\n      <xsd:enumeration value=\"hdr\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"clipArt\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"media\"/>\n      <xsd:enumeration value=\"sldImg\"/>\n      <xsd:enumeration value=\"pic\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PlaceholderSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"half\"/>\n      <xsd:enumeration value=\"quarter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_PlaceholderType\" use=\"optional\" default=\"obj\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_PlaceholderSize\" use=\"optional\" default=\"full\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hasCustomPrompt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ApplicationNonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"ph\" type=\"CT_Placeholder\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_Media\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isPhoto\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useBgFill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TopLevelSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMap\" type=\"a:CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_ChildSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMappingOverride\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_ChildSlide\">\n    <xsd:attribute name=\"showMasterSp\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showMasterPhAnim\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_BackgroundProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shadeToTitle\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Background\">\n    <xsd:choice>\n      <xsd:element name=\"bgPr\" type=\"CT_BackgroundProperties\"/>\n      <xsd:element name=\"bgRef\" type=\"a:CT_StyleMatrixReference\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Background\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\" default=\"white\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideData\">\n    <xsd:sequence>\n      <xsd:element name=\"bg\" type=\"CT_Background\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spTree\" type=\"CT_GroupShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_ControlList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Slide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sld\" type=\"CT_Slide\"/>\n  <xsd:simpleType name=\"ST_SlideLayoutType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"twoColTx\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"txAndChart\"/>\n      <xsd:enumeration value=\"chartAndTx\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"txAndClipArt\"/>\n      <xsd:enumeration value=\"clipArtAndTx\"/>\n      <xsd:enumeration value=\"titleOnly\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"txAndObj\"/>\n      <xsd:enumeration value=\"objAndTx\"/>\n      <xsd:enumeration value=\"objOnly\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"txAndMedia\"/>\n      <xsd:enumeration value=\"mediaAndTx\"/>\n      <xsd:enumeration value=\"objOverTx\"/>\n      <xsd:enumeration value=\"txOverObj\"/>\n      <xsd:enumeration value=\"txAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndTx\"/>\n      <xsd:enumeration value=\"twoObjOverTx\"/>\n      <xsd:enumeration value=\"fourObj\"/>\n      <xsd:enumeration value=\"vertTx\"/>\n      <xsd:enumeration value=\"clipArtAndVertTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTxOverChart\"/>\n      <xsd:enumeration value=\"twoObj\"/>\n      <xsd:enumeration value=\"objAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndObj\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"secHead\"/>\n      <xsd:enumeration value=\"twoTxTwoObj\"/>\n      <xsd:enumeration value=\"objTx\"/>\n      <xsd:enumeration value=\"picTx\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayout\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"matchingName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideLayoutType\" use=\"optional\" default=\"cust\"/>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldLayout\" type=\"CT_SlideLayout\"/>\n  <xsd:complexType name=\"CT_SlideMasterTextStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"titleStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"otherStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideLayoutId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayoutIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideLayoutId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideLayoutIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLayoutId\" type=\"CT_SlideLayoutIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMaster\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLayoutIdLst\" type=\"CT_SlideLayoutIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txStyles\" type=\"CT_SlideMasterTextStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldMaster\" type=\"CT_SlideMaster\"/>\n  <xsd:complexType name=\"CT_HandoutMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"handoutMaster\" type=\"CT_HandoutMaster\"/>\n  <xsd:complexType name=\"CT_NotesMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"notesMaster\" type=\"CT_NotesMaster\"/>\n  <xsd:complexType name=\"CT_NotesSlide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n  </xsd:complexType>\n  <xsd:element name=\"notes\" type=\"CT_NotesSlide\"/>\n  <xsd:complexType name=\"CT_SlideSyncProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverSldId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"serverSldModifiedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"clientInsertedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldSyncPr\" type=\"CT_SlideSyncProperties\"/>\n  <xsd:complexType name=\"CT_StringTag\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagList\">\n    <xsd:sequence>\n      <xsd:element name=\"tag\" type=\"CT_StringTag\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tagLst\" type=\"CT_TagList\"/>\n  <xsd:simpleType name=\"ST_SplitterBarState\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"minimized\"/>\n      <xsd:enumeration value=\"restored\"/>\n      <xsd:enumeration value=\"maximized\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ViewType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sldView\"/>\n      <xsd:enumeration value=\"sldMasterView\"/>\n      <xsd:enumeration value=\"notesView\"/>\n      <xsd:enumeration value=\"handoutView\"/>\n      <xsd:enumeration value=\"notesMasterView\"/>\n      <xsd:enumeration value=\"outlineView\"/>\n      <xsd:enumeration value=\"sldSorterView\"/>\n      <xsd:enumeration value=\"sldThumbnailView\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NormalViewPortion\">\n    <xsd:attribute name=\"sz\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"autoAdjust\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NormalViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"restoredLeft\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"restoredTop\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showOutlineIcons\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapVertSplitter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vertBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"horzBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"preferSingleView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"scale\" type=\"a:CT_Scale2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"origin\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"varScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesTextViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"collapse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_OutlineViewSlideEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLst\" type=\"CT_OutlineViewSlideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideSorterViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guide\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"vert\"/>\n    <xsd:attribute name=\"pos\" type=\"a:ST_Coordinate32\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GuideList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"guide\" type=\"CT_Guide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"guideLst\" type=\"CT_GuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"snapToGrid\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapToObjects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGuides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ViewProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"normalViewPr\" type=\"CT_NormalViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"slideViewPr\" type=\"CT_SlideViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlineViewPr\" type=\"CT_OutlineViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesTextViewPr\" type=\"CT_NotesTextViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sorterViewPr\" type=\"CT_SlideSorterViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"notesViewPr\" type=\"CT_NotesViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpacing\" type=\"a:CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastView\" type=\"ST_ViewType\" use=\"optional\" default=\"sldView\"/>\n    <xsd:attribute name=\"showComments\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"viewPr\" type=\"CT_ViewProperties\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_AdditionalCharacteristics\">\n    <xsd:sequence>\n      <xsd:element name=\"characteristic\" type=\"CT_Characteristic\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Characteristic\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"relation\" type=\"ST_Relation\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"vocabulary\" type=\"xsd:anyURI\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Relation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ge\"/>\n      <xsd:enumeration value=\"le\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"eq\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"additionalCharacteristics\" type=\"CT_AdditionalCharacteristics\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"s:ST_String\">\n      <xsd:enumeration value=\"ArticleInAPeriodical\"/>\n      <xsd:enumeration value=\"Book\"/>\n      <xsd:enumeration value=\"BookSection\"/>\n      <xsd:enumeration value=\"JournalArticle\"/>\n      <xsd:enumeration value=\"ConferenceProceedings\"/>\n      <xsd:enumeration value=\"Report\"/>\n      <xsd:enumeration value=\"SoundRecording\"/>\n      <xsd:enumeration value=\"Performance\"/>\n      <xsd:enumeration value=\"Art\"/>\n      <xsd:enumeration value=\"DocumentFromInternetSite\"/>\n      <xsd:enumeration value=\"InternetSite\"/>\n      <xsd:enumeration value=\"Film\"/>\n      <xsd:enumeration value=\"Interview\"/>\n      <xsd:enumeration value=\"Patent\"/>\n      <xsd:enumeration value=\"ElectronicSource\"/>\n      <xsd:enumeration value=\"Case\"/>\n      <xsd:enumeration value=\"Misc\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NameListType\">\n    <xsd:sequence>\n      <xsd:element name=\"Person\" type=\"CT_PersonType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PersonType\">\n    <xsd:sequence>\n      <xsd:element name=\"Last\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"First\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Middle\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameType\">\n    <xsd:sequence>\n      <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameOrCorporateType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"Corporate\" minOccurs=\"1\" maxOccurs=\"1\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AuthorType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"Artist\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Author\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"BookAuthor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Compiler\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Composer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Conductor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Counsel\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Director\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Editor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewee\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Inventor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Performer\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"ProducerName\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Translator\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Writer\" type=\"CT_NameType\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SourceType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"AbbreviatedCaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"AlbumTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Author\" type=\"CT_AuthorType\"/>\n        <xsd:element name=\"BookTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Broadcaster\" type=\"s:ST_String\"/>\n        <xsd:element name=\"BroadcastTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ChapterNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"City\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Comments\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ConferenceName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CountryRegion\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Court\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Day\" type=\"s:ST_String\"/>\n        <xsd:element name=\"DayAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Department\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Distributor\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Edition\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Guid\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Institution\" type=\"s:ST_String\"/>\n        <xsd:element name=\"InternetSiteTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Issue\" type=\"s:ST_String\"/>\n        <xsd:element name=\"JournalName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"LCID\" type=\"s:ST_Lang\"/>\n        <xsd:element name=\"Medium\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Month\" type=\"s:ST_String\"/>\n        <xsd:element name=\"MonthAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"NumberVolumes\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Pages\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PatentNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PeriodicalTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ProductionCompany\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PublicationTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Publisher\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RecordingNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RefOrder\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Reporter\" type=\"s:ST_String\"/>\n        <xsd:element name=\"SourceType\" type=\"ST_SourceType\"/>\n        <xsd:element name=\"ShortTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StandardNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StateProvince\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Station\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Tag\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Theater\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ThesisType\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Title\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Type\" type=\"s:ST_String\"/>\n        <xsd:element name=\"URL\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Version\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Volume\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Year\" type=\"s:ST_String\"/>\n        <xsd:element name=\"YearAccessed\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"Sources\" type=\"CT_Sources\"/>\n  <xsd:complexType name=\"CT_Sources\">\n    <xsd:sequence>\n      <xsd:element name=\"Source\" type=\"CT_SourceType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectedStyle\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"StyleName\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"URI\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\">\n  <xsd:simpleType name=\"ST_Lang\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColorRGB\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"3\" fixed=\"true\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Panose\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalendarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gregorian\"/>\n      <xsd:enumeration value=\"gregorianUs\"/>\n      <xsd:enumeration value=\"gregorianMeFrench\"/>\n      <xsd:enumeration value=\"gregorianArabic\"/>\n      <xsd:enumeration value=\"hijri\"/>\n      <xsd:enumeration value=\"hebrew\"/>\n      <xsd:enumeration value=\"taiwan\"/>\n      <xsd:enumeration value=\"japan\"/>\n      <xsd:enumeration value=\"thai\"/>\n      <xsd:enumeration value=\"korea\"/>\n      <xsd:enumeration value=\"saka\"/>\n      <xsd:enumeration value=\"gregorianXlitEnglish\"/>\n      <xsd:enumeration value=\"gregorianXlitFrench\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hash\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CryptProv\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rsaAES\"/>\n      <xsd:enumeration value=\"rsaFull\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"typeAny\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Guid\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff\">\n    <xsd:union memberTypes=\"xsd:boolean ST_OnOff1\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff1\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_String\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XmlName\">\n    <xsd:restriction base=\"xsd:NCName\">\n      <xsd:minLength value=\"1\"/>\n      <xsd:maxLength value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalse\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalseBlank\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n      <xsd:enumeration value=\"\"/>\n      <xsd:enumeration value=\"True\"/>\n      <xsd:enumeration value=\"False\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedDecimalNumber\">\n    <xsd:restriction base=\"xsd:decimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TwipsMeasure\">\n    <xsd:union memberTypes=\"ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignRun\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"superscript\"/>\n      <xsd:enumeration value=\"subscript\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Xstring\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_YAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inline\"/>\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConformanceClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"strict\"/>\n      <xsd:enumeration value=\"transitional\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UniversalMeasure\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveUniversalMeasure\">\n    <xsd:restriction base=\"ST_UniversalMeasure\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"-?((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_DatastoreSchemaRef\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreSchemaRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRef\" type=\"CT_DatastoreSchemaRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreItem\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRefs\" type=\"CT_DatastoreSchemaRefs\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"itemID\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"datastoreItem\" type=\"CT_DatastoreItem\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_Schema\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" default=\"\"/>\n    <xsd:attribute name=\"manifestLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLanguage\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SchemaLibrary\">\n    <xsd:sequence>\n      <xsd:element name=\"schema\" type=\"CT_Schema\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"schemaLibrary\" type=\"CT_SchemaLibrary\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:sequence>\n      <xsd:element name=\"property\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Property\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Property\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n      <xsd:element ref=\"vt:array\"/>\n      <xsd:element ref=\"vt:blob\"/>\n      <xsd:element ref=\"vt:oblob\"/>\n      <xsd:element ref=\"vt:empty\"/>\n      <xsd:element ref=\"vt:null\"/>\n      <xsd:element ref=\"vt:i1\"/>\n      <xsd:element ref=\"vt:i2\"/>\n      <xsd:element ref=\"vt:i4\"/>\n      <xsd:element ref=\"vt:i8\"/>\n      <xsd:element ref=\"vt:int\"/>\n      <xsd:element ref=\"vt:ui1\"/>\n      <xsd:element ref=\"vt:ui2\"/>\n      <xsd:element ref=\"vt:ui4\"/>\n      <xsd:element ref=\"vt:ui8\"/>\n      <xsd:element ref=\"vt:uint\"/>\n      <xsd:element ref=\"vt:r4\"/>\n      <xsd:element ref=\"vt:r8\"/>\n      <xsd:element ref=\"vt:decimal\"/>\n      <xsd:element ref=\"vt:lpstr\"/>\n      <xsd:element ref=\"vt:lpwstr\"/>\n      <xsd:element ref=\"vt:bstr\"/>\n      <xsd:element ref=\"vt:date\"/>\n      <xsd:element ref=\"vt:filetime\"/>\n      <xsd:element ref=\"vt:bool\"/>\n      <xsd:element ref=\"vt:cy\"/>\n      <xsd:element ref=\"vt:error\"/>\n      <xsd:element ref=\"vt:stream\"/>\n      <xsd:element ref=\"vt:ostream\"/>\n      <xsd:element ref=\"vt:storage\"/>\n      <xsd:element ref=\"vt:ostorage\"/>\n      <xsd:element ref=\"vt:vstream\"/>\n      <xsd:element ref=\"vt:clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fmtid\" use=\"required\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"pid\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"linkTarget\" use=\"optional\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  elementFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:all>\n      <xsd:element name=\"Template\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Manager\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Company\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Pages\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Words\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Characters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"PresentationFormat\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Lines\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Paragraphs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Slides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Notes\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"TotalTime\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"HiddenSlides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"MMClips\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"ScaleCrop\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HeadingPairs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"TitlesOfParts\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorLpstr\"/>\n      <xsd:element name=\"LinksUpToDate\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"CharactersWithSpaces\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"SharedDoc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HyperlinkBase\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"HLinks\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"HyperlinksChanged\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"DigSig\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DigSigBlob\"/>\n      <xsd:element name=\"Application\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"AppVersion\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"DocSecurity\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorVariant\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorLpstr\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DigSigBlob\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:blob\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_VectorBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"i8\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"ui8\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"lpstr\"/>\n      <xsd:enumeration value=\"lpwstr\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"filetime\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n      <xsd:enumeration value=\"clsid\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrayBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"int\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"uint\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Cy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*[0-9]*\\.[0-9]{4}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Error\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*0x[0-9A-Za-z]{8}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Null\"/>\n  <xsd:complexType name=\"CT_Vector\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"baseType\" type=\"ST_VectorBaseType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Array\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"cy\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"lBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"uBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"baseType\" type=\"ST_ArrayBaseType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Variant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"vector\"/>\n      <xsd:element ref=\"array\"/>\n      <xsd:element ref=\"blob\"/>\n      <xsd:element ref=\"oblob\"/>\n      <xsd:element ref=\"empty\"/>\n      <xsd:element ref=\"null\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"stream\"/>\n      <xsd:element ref=\"ostream\"/>\n      <xsd:element ref=\"storage\"/>\n      <xsd:element ref=\"ostorage\"/>\n      <xsd:element ref=\"vstream\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vstream\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:base64Binary\">\n        <xsd:attribute name=\"version\" type=\"s:ST_Guid\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:element name=\"variant\" type=\"CT_Variant\"/>\n  <xsd:element name=\"vector\" type=\"CT_Vector\"/>\n  <xsd:element name=\"array\" type=\"CT_Array\"/>\n  <xsd:element name=\"blob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"oblob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"empty\" type=\"CT_Empty\"/>\n  <xsd:element name=\"null\" type=\"CT_Null\"/>\n  <xsd:element name=\"i1\" type=\"xsd:byte\"/>\n  <xsd:element name=\"i2\" type=\"xsd:short\"/>\n  <xsd:element name=\"i4\" type=\"xsd:int\"/>\n  <xsd:element name=\"i8\" type=\"xsd:long\"/>\n  <xsd:element name=\"int\" type=\"xsd:int\"/>\n  <xsd:element name=\"ui1\" type=\"xsd:unsignedByte\"/>\n  <xsd:element name=\"ui2\" type=\"xsd:unsignedShort\"/>\n  <xsd:element name=\"ui4\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"ui8\" type=\"xsd:unsignedLong\"/>\n  <xsd:element name=\"uint\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"r4\" type=\"xsd:float\"/>\n  <xsd:element name=\"r8\" type=\"xsd:double\"/>\n  <xsd:element name=\"decimal\" type=\"xsd:decimal\"/>\n  <xsd:element name=\"lpstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"lpwstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"bstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"date\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"filetime\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"bool\" type=\"xsd:boolean\"/>\n  <xsd:element name=\"cy\" type=\"ST_Cy\"/>\n  <xsd:element name=\"error\" type=\"ST_Error\"/>\n  <xsd:element name=\"stream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"storage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostorage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"vstream\" type=\"CT_Vstream\"/>\n  <xsd:element name=\"clsid\" type=\"s:ST_Guid\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n  <xsd:simpleType name=\"ST_Integer255\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer255\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer255\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Integer2\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"-2\"/>\n      <xsd:maxInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer2\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer2\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SpacingRule\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SpacingRule\">\n    <xsd:attribute name=\"val\" type=\"ST_SpacingRule\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnSignedInteger\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnSignedInteger\">\n    <xsd:attribute name=\"val\" type=\"ST_UnSignedInteger\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Char\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Char\">\n    <xsd:attribute name=\"val\" type=\"ST_Char\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_XAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_YAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_YAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"centered\"/>\n      <xsd:enumeration value=\"match\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shp\">\n    <xsd:attribute name=\"val\" type=\"ST_Shp\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"skw\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"noBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FType\">\n    <xsd:attribute name=\"val\" type=\"ST_FType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LimLoc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"undOvr\"/>\n      <xsd:enumeration value=\"subSup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LimLoc\">\n    <xsd:attribute name=\"val\" type=\"ST_LimLoc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TopBot\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TopBot\">\n    <xsd:attribute name=\"val\" type=\"ST_TopBot\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Script\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"fraktur\"/>\n      <xsd:enumeration value=\"double-struck\"/>\n      <xsd:enumeration value=\"sans-serif\"/>\n      <xsd:enumeration value=\"monospace\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Script\">\n    <xsd:attribute name=\"val\" type=\"ST_Script\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"i\"/>\n      <xsd:enumeration value=\"bi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualBreak\">\n    <xsd:attribute name=\"alnAt\" type=\"ST_Integer255\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ScriptStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"scr\" minOccurs=\"0\" type=\"CT_Script\"/>\n      <xsd:element name=\"sty\" minOccurs=\"0\" type=\"CT_Style\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPR\">\n    <xsd:sequence>\n      <xsd:element name=\"lit\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n      <xsd:choice>\n        <xsd:element name=\"nor\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n        <xsd:sequence>\n          <xsd:group ref=\"EG_ScriptStyle\"/>\n        </xsd:sequence>\n      </xsd:choice>\n      <xsd:element name=\"brk\" minOccurs=\"0\" type=\"CT_ManualBreak\"/>\n      <xsd:element name=\"aln\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPR\" minOccurs=\"0\"/>\n      <xsd:group ref=\"w:EG_RPr\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:group ref=\"w:EG_RunInnerContent\"/>\n        <xsd:element name=\"t\" type=\"CT_Text\" minOccurs=\"0\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CtrlPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"w:EG_RPrMath\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AccPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Acc\">\n    <xsd:sequence>\n      <xsd:element name=\"accPr\" type=\"CT_AccPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarPr\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar\">\n    <xsd:sequence>\n      <xsd:element name=\"barPr\" type=\"CT_BarPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"opEmu\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBreak\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"diff\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"brk\" type=\"CT_ManualBreak\" minOccurs=\"0\"/>\n      <xsd:element name=\"aln\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Box\">\n    <xsd:sequence>\n      <xsd:element name=\"boxPr\" type=\"CT_BoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"hideTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideBot\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideLeft\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideRight\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeH\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeV\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeBLTR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeTLBR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBox\">\n    <xsd:sequence>\n      <xsd:element name=\"borderBoxPr\" type=\"CT_BorderBoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPr\">\n    <xsd:sequence>\n      <xsd:element name=\"begChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"sepChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"endChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shp\" type=\"CT_Shp\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_D\">\n    <xsd:sequence>\n      <xsd:element name=\"dPr\" type=\"CT_DPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"objDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArr\">\n    <xsd:sequence>\n      <xsd:element name=\"eqArrPr\" type=\"CT_EqArrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FPr\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FType\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:sequence>\n      <xsd:element name=\"fPr\" type=\"CT_FPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"num\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"den\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FuncPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Func\">\n    <xsd:sequence>\n      <xsd:element name=\"funcPr\" type=\"CT_FuncPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"fName\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"vertJc\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChr\">\n    <xsd:sequence>\n      <xsd:element name=\"groupChrPr\" type=\"CT_GroupChrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLowPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLow\">\n    <xsd:sequence>\n      <xsd:element name=\"limLowPr\" type=\"CT_LimLowPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUppPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUpp\">\n    <xsd:sequence>\n      <xsd:element name=\"limUppPr\" type=\"CT_LimUppPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCPr\">\n    <xsd:sequence>\n      <xsd:element name=\"count\" type=\"CT_Integer255\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcJc\" type=\"CT_XAlign\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MC\">\n    <xsd:sequence>\n      <xsd:element name=\"mcPr\" type=\"CT_MCPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCS\">\n    <xsd:sequence>\n      <xsd:element name=\"mc\" type=\"CT_MC\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"plcHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcs\" type=\"CT_MCS\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MR\">\n    <xsd:sequence>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_M\">\n    <xsd:sequence>\n      <xsd:element name=\"mPr\" type=\"CT_MPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"mr\" type=\"CT_MR\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NaryPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"limLoc\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"supHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Nary\">\n    <xsd:sequence>\n      <xsd:element name=\"naryPr\" type=\"CT_NaryPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhantPr\">\n    <xsd:sequence>\n      <xsd:element name=\"show\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroWid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroAsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroDesc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"transp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Phant\">\n    <xsd:sequence>\n      <xsd:element name=\"phantPr\" type=\"CT_PhantPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadPr\">\n    <xsd:sequence>\n      <xsd:element name=\"degHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rad\">\n    <xsd:sequence>\n      <xsd:element name=\"radPr\" type=\"CT_RadPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"deg\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPrePr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPre\">\n    <xsd:sequence>\n      <xsd:element name=\"sPrePr\" type=\"CT_SPrePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSub\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubPr\" type=\"CT_SSubPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"alnScr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubSupPr\" type=\"CT_SSubSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSupPr\" type=\"CT_SSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OMathMathElements\">\n    <xsd:choice>\n      <xsd:element name=\"acc\" type=\"CT_Acc\"/>\n      <xsd:element name=\"bar\" type=\"CT_Bar\"/>\n      <xsd:element name=\"box\" type=\"CT_Box\"/>\n      <xsd:element name=\"borderBox\" type=\"CT_BorderBox\"/>\n      <xsd:element name=\"d\" type=\"CT_D\"/>\n      <xsd:element name=\"eqArr\" type=\"CT_EqArr\"/>\n      <xsd:element name=\"f\" type=\"CT_F\"/>\n      <xsd:element name=\"func\" type=\"CT_Func\"/>\n      <xsd:element name=\"groupChr\" type=\"CT_GroupChr\"/>\n      <xsd:element name=\"limLow\" type=\"CT_LimLow\"/>\n      <xsd:element name=\"limUpp\" type=\"CT_LimUpp\"/>\n      <xsd:element name=\"m\" type=\"CT_M\"/>\n      <xsd:element name=\"nary\" type=\"CT_Nary\"/>\n      <xsd:element name=\"phant\" type=\"CT_Phant\"/>\n      <xsd:element name=\"rad\" type=\"CT_Rad\"/>\n      <xsd:element name=\"sPre\" type=\"CT_SPre\"/>\n      <xsd:element name=\"sSub\" type=\"CT_SSub\"/>\n      <xsd:element name=\"sSubSup\" type=\"CT_SSubSup\"/>\n      <xsd:element name=\"sSup\" type=\"CT_SSup\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_OMathElements\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_OMathMathElements\"/>\n      <xsd:group ref=\"w:EG_PContentMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OMathArgPr\">\n    <xsd:sequence>\n      <xsd:element name=\"argSz\" type=\"CT_Integer2\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathArg\">\n    <xsd:sequence>\n      <xsd:element name=\"argPr\" type=\"CT_OMathArgPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"centerGroup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OMathJc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathParaPr\">\n    <xsd:sequence>\n      <xsd:element name=\"jc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBin\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"before\"/>\n      <xsd:enumeration value=\"after\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBin\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBin\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBinSub\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"--\"/>\n      <xsd:enumeration value=\"-+\"/>\n      <xsd:enumeration value=\"+-\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBinSub\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBinSub\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathPr\">\n    <xsd:sequence>\n      <xsd:element name=\"mathFont\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBin\" type=\"CT_BreakBin\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBinSub\" type=\"CT_BreakBinSub\" minOccurs=\"0\"/>\n      <xsd:element name=\"smallFrac\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dispDef\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"rMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"defJc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"preSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"postSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"interSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"intraSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"wrapIndent\" type=\"CT_TwipsMeasure\"/>\n        <xsd:element name=\"wrapRight\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"intLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"naryLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"mathPr\" type=\"CT_MathPr\"/>\n  <xsd:complexType name=\"CT_OMathPara\">\n    <xsd:sequence>\n      <xsd:element name=\"oMathParaPr\" type=\"CT_OMathParaPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OMath\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMath\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"oMathPara\" type=\"CT_OMathPara\"/>\n  <xsd:element name=\"oMath\" type=\"CT_OMath\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  blockDefault=\"#all\">\n  <xsd:simpleType name=\"ST_RelationshipId\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:attribute name=\"id\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"embed\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"link\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"dm\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"lo\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"qs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"cs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"blip\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"pict\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"href\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topRight\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomRight\" type=\"ST_RelationshipId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import \n    namespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n    schemaLocation=\"dml-spreadsheetDrawing.xsd\"/>\n  <xsd:complexType name=\"CT_AutoFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"filterColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FilterColumn\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FilterColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"filters\" type=\"CT_Filters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top10\" type=\"CT_Top10\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customFilters\" type=\"CT_CustomFilters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dynamicFilter\" type=\"CT_DynamicFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colorFilter\" type=\"CT_ColorFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconFilter\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_IconFilter\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"colId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"hiddenButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showButton\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" type=\"CT_Filter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dateGroupItem\" type=\"CT_DateGroupItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n    <xsd:attribute name=\"blank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calendarType\" type=\"s:ST_CalendarType\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filter\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"customFilter\" type=\"CT_CustomFilter\" minOccurs=\"1\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"and\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilter\">\n    <xsd:attribute name=\"operator\" type=\"ST_FilterOperator\" default=\"equal\" use=\"optional\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Top10\">\n    <xsd:attribute name=\"top\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"filterVal\" type=\"xsd:double\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorFilter\">\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"cellColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconFilter\">\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"required\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FilterOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DynamicFilter\">\n    <xsd:attribute name=\"type\" type=\"ST_DynamicFilterType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"valIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxVal\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DynamicFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n      <xsd:enumeration value=\"belowAverage\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_IconSetType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"3Arrows\"/>\n      <xsd:enumeration value=\"3ArrowsGray\"/>\n      <xsd:enumeration value=\"3Flags\"/>\n      <xsd:enumeration value=\"3TrafficLights1\"/>\n      <xsd:enumeration value=\"3TrafficLights2\"/>\n      <xsd:enumeration value=\"3Signs\"/>\n      <xsd:enumeration value=\"3Symbols\"/>\n      <xsd:enumeration value=\"3Symbols2\"/>\n      <xsd:enumeration value=\"4Arrows\"/>\n      <xsd:enumeration value=\"4ArrowsGray\"/>\n      <xsd:enumeration value=\"4RedToBlack\"/>\n      <xsd:enumeration value=\"4Rating\"/>\n      <xsd:enumeration value=\"4TrafficLights\"/>\n      <xsd:enumeration value=\"5Arrows\"/>\n      <xsd:enumeration value=\"5ArrowsGray\"/>\n      <xsd:enumeration value=\"5Rating\"/>\n      <xsd:enumeration value=\"5Quarters\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SortState\">\n    <xsd:sequence>\n      <xsd:element name=\"sortCondition\" minOccurs=\"0\" maxOccurs=\"64\" type=\"CT_SortCondition\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"columnSort\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"caseSensitive\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortMethod\" type=\"ST_SortMethod\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SortCondition\">\n    <xsd:attribute name=\"descending\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortBy\" type=\"ST_SortBy\" use=\"optional\" default=\"value\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"customList\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3Arrows\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cellColor\"/>\n      <xsd:enumeration value=\"fontColor\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SortMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stroke\"/>\n      <xsd:enumeration value=\"pinYin\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DateGroupItem\">\n    <xsd:attribute name=\"year\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"month\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"day\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"hour\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"minute\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"second\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"dateTimeGrouping\" type=\"ST_DateTimeGrouping\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTimeGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"year\"/>\n      <xsd:enumeration value=\"month\"/>\n      <xsd:enumeration value=\"day\"/>\n      <xsd:enumeration value=\"hour\"/>\n      <xsd:enumeration value=\"minute\"/>\n      <xsd:enumeration value=\"second\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellRef\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ref\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefA\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Sqref\">\n    <xsd:list itemType=\"ST_Ref\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Formula\">\n    <xsd:restriction base=\"s:ST_Xstring\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedIntHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedShortHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XStringElement\">\n    <xsd:attribute name=\"v\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectAnchor\">\n    <xsd:sequence>\n      <xsd:element ref=\"xdr:from\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"xdr:to\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"moveWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sizeWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"calcChain\" type=\"CT_CalcChain\"/>\n  <xsd:complexType name=\"CT_CalcChain\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_CalcCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcCell\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"l\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"a\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"authors\" type=\"CT_Authors\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentList\" type=\"CT_CommentList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Authors\">\n    <xsd:sequence>\n      <xsd:element name=\"author\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"text\" type=\"CT_Rst\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentPr\" type=\"CT_CommentPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"textHAlign\" type=\"ST_TextHAlign\" use=\"optional\" default=\"left\"/>\n    <xsd:attribute name=\"textVAlign\" type=\"ST_TextVAlign\" use=\"optional\" default=\"top\"/>\n    <xsd:attribute name=\"lockText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"justLastX\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextHAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"MapInfo\" type=\"CT_MapInfo\"/>\n  <xsd:complexType name=\"CT_MapInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"Schema\" type=\"CT_Schema\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Map\" type=\"CT_Map\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectionNamespaces\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Schema\" mixed=\"true\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaRef\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"Namespace\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"SchemaLanguage\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Map\">\n    <xsd:sequence>\n      <xsd:element name=\"DataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"Name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"RootElement\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"ShowImportExportValidationErrors\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"AutoFit\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"Append\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveSortAFLayout\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveFormat\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"DataBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBinding\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"ConnectionID\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DataBindingLoadMode\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"connections\" type=\"CT_Connections\"/>\n  <xsd:complexType name=\"CT_Connections\">\n    <xsd:sequence>\n      <xsd:element name=\"connection\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Connection\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:sequence>\n      <xsd:element name=\"dbPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DbPr\"/>\n      <xsd:element name=\"olapPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_OlapPr\"/>\n      <xsd:element name=\"webPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_WebPr\"/>\n      <xsd:element name=\"textPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextPr\"/>\n      <xsd:element name=\"parameters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Parameters\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"odcFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"keepAlive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"interval\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"reconnectionMethod\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"refreshedVersion\" use=\"required\" type=\"xsd:unsignedByte\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" use=\"optional\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"savePassword\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"new\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"deleted\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"onlyUseConnectionFile\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"background\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"credentials\" use=\"optional\" type=\"ST_CredMethod\" default=\"integrated\"/>\n    <xsd:attribute name=\"singleSignOnId\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CredMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"integrated\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"stored\"/>\n      <xsd:enumeration value=\"prompt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DbPr\">\n    <xsd:attribute name=\"connection\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"command\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"serverCommand\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"commandType\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OlapPr\">\n    <xsd:attribute name=\"local\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"localConnection\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"localRefresh\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sendLocale\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowDrillCount\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"serverFill\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverNumberFormat\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFont\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFontColor\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tables\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Tables\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"xml\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sourceData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parsePre\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl97\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"textDates\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl2000\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"url\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"post\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"htmlTables\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"htmlFormat\" use=\"optional\" type=\"ST_HtmlFmt\" default=\"none\"/>\n    <xsd:attribute name=\"editPage\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HtmlFmt\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rtf\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Parameters\">\n    <xsd:sequence>\n      <xsd:element name=\"parameter\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Parameter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sqlType\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"parameterType\" use=\"optional\" type=\"ST_ParameterType\" default=\"prompt\"/>\n    <xsd:attribute name=\"refreshOnChange\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"boolean\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"double\" use=\"optional\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"integer\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"string\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cell\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ParameterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"prompt\"/>\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Tables\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_TableMissing\"/>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableMissing\"/>\n  <xsd:complexType name=\"CT_TextPr\">\n    <xsd:sequence>\n      <xsd:element name=\"textFields\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextFields\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fileType\" use=\"optional\" type=\"ST_FileType\" default=\"win\"/>\n    <xsd:attribute name=\"codePage\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1252\"/>\n    <xsd:attribute name=\"characterSet\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\" default=\"\"/>\n    <xsd:attribute name=\"delimited\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"decimal\" use=\"optional\" type=\"s:ST_Xstring\" default=\".\"/>\n    <xsd:attribute name=\"thousands\" use=\"optional\" type=\"s:ST_Xstring\" default=\",\"/>\n    <xsd:attribute name=\"tab\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"space\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"comma\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"semicolon\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"qualifier\" use=\"optional\" type=\"ST_Qualifier\" default=\"doubleQuote\"/>\n    <xsd:attribute name=\"delimiter\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FileType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"mac\"/>\n      <xsd:enumeration value=\"win\"/>\n      <xsd:enumeration value=\"dos\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"other\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Qualifier\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doubleQuote\"/>\n      <xsd:enumeration value=\"singleQuote\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextFields\">\n    <xsd:sequence>\n      <xsd:element name=\"textField\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_TextField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"ST_ExternalConnectionType\" default=\"general\"/>\n    <xsd:attribute name=\"position\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ExternalConnectionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"MDY\"/>\n      <xsd:enumeration value=\"DMY\"/>\n      <xsd:enumeration value=\"YMD\"/>\n      <xsd:enumeration value=\"MYD\"/>\n      <xsd:enumeration value=\"DYM\"/>\n      <xsd:enumeration value=\"YDM\"/>\n      <xsd:enumeration value=\"skip\"/>\n      <xsd:enumeration value=\"EMD\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"pivotCacheDefinition\" type=\"CT_PivotCacheDefinition\"/>\n  <xsd:element name=\"pivotCacheRecords\" type=\"CT_PivotCacheRecords\"/>\n  <xsd:element name=\"pivotTableDefinition\" type=\"CT_pivotTableDefinition\"/>\n  <xsd:complexType name=\"CT_PivotCacheDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheSource\" type=\"CT_CacheSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheFields\" type=\"CT_CacheFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheHierarchies\" minOccurs=\"0\" type=\"CT_CacheHierarchies\"/>\n      <xsd:element name=\"kpis\" minOccurs=\"0\" type=\"CT_PCDKPIs\"/>\n      <xsd:element name=\"tupleCache\" minOccurs=\"0\" type=\"CT_TupleCache\"/>\n      <xsd:element name=\"calculatedItems\" minOccurs=\"0\" type=\"CT_CalculatedItems\"/>\n      <xsd:element name=\"calculatedMembers\" type=\"CT_CalculatedMembers\" minOccurs=\"0\"/>\n      <xsd:element name=\"dimensions\" type=\"CT_Dimensions\" minOccurs=\"0\"/>\n      <xsd:element name=\"measureGroups\" type=\"CT_MeasureGroups\" minOccurs=\"0\"/>\n      <xsd:element name=\"maps\" type=\"CT_MeasureDimensionMaps\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalid\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"optimizeMemory\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshedBy\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDate\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDateIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"backgroundQuery\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingItemsLimit\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"refreshedVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"recordCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"upgradeOnRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tupleCache\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportSubquery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportAdvancedDrill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheFields\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheField\" type=\"CT_CacheField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheField\">\n    <xsd:sequence>\n      <xsd:element name=\"sharedItems\" type=\"CT_SharedItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fieldGroup\" minOccurs=\"0\" type=\"CT_FieldGroup\"/>\n      <xsd:element name=\"mpMap\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"propertyName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueList\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqlType\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"databaseField\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"mappingCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"memberPropertyField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheSource\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"worksheetSource\" type=\"CT_WorksheetSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"consolidation\" type=\"CT_Consolidation\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_SourceType\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" default=\"0\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"external\"/>\n      <xsd:enumeration value=\"consolidation\"/>\n      <xsd:enumeration value=\"scenario\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorksheetSource\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Consolidation\">\n    <xsd:sequence>\n      <xsd:element name=\"pages\" type=\"CT_Pages\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rangeSets\" type=\"CT_RangeSets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"autoPage\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pages\">\n    <xsd:sequence>\n      <xsd:element name=\"page\" type=\"CT_PCDSCPage\" minOccurs=\"1\" maxOccurs=\"4\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSCPage\">\n    <xsd:sequence>\n      <xsd:element name=\"pageItem\" type=\"CT_PageItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSets\">\n    <xsd:sequence>\n      <xsd:element name=\"rangeSet\" type=\"CT_RangeSet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSet\">\n    <xsd:attribute name=\"i1\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i2\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i3\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i4\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedItems\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"s\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"containsSemiMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsNonDate\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsDate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsString\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsInteger\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"minDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"longText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Missing\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Number\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Error\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateTime\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"rangePr\" minOccurs=\"0\" type=\"CT_RangePr\"/>\n      <xsd:element name=\"discretePr\" minOccurs=\"0\" type=\"CT_DiscretePr\"/>\n      <xsd:element name=\"groupItems\" minOccurs=\"0\" type=\"CT_GroupItems\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"par\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"base\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangePr\">\n    <xsd:attribute name=\"autoStart\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"autoEnd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"groupBy\" type=\"ST_GroupBy\" default=\"range\"/>\n    <xsd:attribute name=\"startNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"endNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"startDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"endDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"groupInterval\" type=\"xsd:double\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GroupBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"seconds\"/>\n      <xsd:enumeration value=\"minutes\"/>\n      <xsd:enumeration value=\"hours\"/>\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"quarters\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DiscretePr\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupItems\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCacheRecords\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Record\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Record\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPIs\">\n    <xsd:sequence>\n      <xsd:element name=\"kpi\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PCDKPI\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPI\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"value\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"goal\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"status\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"trend\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"weight\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"time\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheHierarchy\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CacheHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldsUsage\" minOccurs=\"0\" type=\"CT_FieldsUsage\"/>\n      <xsd:element name=\"groupLevels\" minOccurs=\"0\" type=\"CT_GroupLevels\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parentSet\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"attribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"keyAttribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultMemberUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"dimensionUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measures\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"oneField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"memberValueDatatype\" use=\"optional\" type=\"xsd:unsignedShort\"/>\n    <xsd:attribute name=\"unbalanced\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"unbalancedGroup\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldsUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldUsage\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FieldUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldUsage\">\n    <xsd:attribute name=\"x\" use=\"required\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevels\">\n    <xsd:sequence>\n      <xsd:element name=\"groupLevel\" maxOccurs=\"unbounded\" type=\"CT_GroupLevel\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevel\">\n    <xsd:sequence>\n      <xsd:element name=\"groups\" minOccurs=\"0\" type=\"CT_Groups\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"user\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customRollUp\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Groups\">\n    <xsd:sequence>\n      <xsd:element name=\"group\" maxOccurs=\"unbounded\" type=\"CT_LevelGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMembers\" type=\"CT_GroupMembers\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueParent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMember\" maxOccurs=\"unbounded\" type=\"CT_GroupMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMember\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"group\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TupleCache\">\n    <xsd:sequence>\n      <xsd:element name=\"entries\" minOccurs=\"0\" type=\"CT_PCDSDTCEntries\"/>\n      <xsd:element name=\"sets\" minOccurs=\"0\" type=\"CT_Sets\"/>\n      <xsd:element name=\"queryCache\" minOccurs=\"0\" type=\"CT_QueryCache\"/>\n      <xsd:element name=\"serverFormats\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ServerFormats\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormat\">\n    <xsd:attribute name=\"culture\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"format\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"serverFormat\" type=\"CT_ServerFormat\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSDTCEntries\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuples\">\n    <xsd:sequence>\n      <xsd:element name=\"tpl\" type=\"CT_Tuple\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuple\">\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"item\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sets\">\n    <xsd:sequence>\n      <xsd:element name=\"set\" maxOccurs=\"unbounded\" type=\"CT_Set\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Set\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"sortByTuple\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"maxRank\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"setDefinition\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_SortType\" default=\"none\"/>\n    <xsd:attribute name=\"queryFailed\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n      <xsd:enumeration value=\"ascendingAlpha\"/>\n      <xsd:enumeration value=\"descendingAlpha\"/>\n      <xsd:enumeration value=\"ascendingNatural\"/>\n      <xsd:enumeration value=\"descendingNatural\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_QueryCache\">\n    <xsd:sequence>\n      <xsd:element name=\"query\" maxOccurs=\"unbounded\" type=\"CT_Query\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Query\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItems\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedItem\" maxOccurs=\"unbounded\" type=\"CT_CalculatedItem\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItem\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedMember\" maxOccurs=\"unbounded\" type=\"CT_CalculatedMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMember\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"memberName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"solveOrder\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_pivotTableDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"location\" type=\"CT_Location\"/>\n      <xsd:element name=\"pivotFields\" type=\"CT_PivotFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowFields\" type=\"CT_RowFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowItems\" type=\"CT_rowItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"colFields\" type=\"CT_ColFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"colItems\" type=\"CT_colItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageFields\" type=\"CT_PageFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataFields\" type=\"CT_DataFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"formats\" type=\"CT_Formats\" minOccurs=\"0\"/>\n      <xsd:element name=\"conditionalFormats\" type=\"CT_ConditionalFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"chartFormats\" type=\"CT_ChartFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotHierarchies\" type=\"CT_PivotHierarchies\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotTableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotTableStyle\"/>\n      <xsd:element name=\"filters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotFilters\"/>\n      <xsd:element name=\"rowHierarchiesUsage\" type=\"CT_RowHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"colHierarchiesUsage\" type=\"CT_ColHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cacheId\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dataOnRows\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dataPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"dataCaption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"grandTotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"errorCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showError\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showMissing\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"pageStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"pivotTableStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"vacatedStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"tag\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"updatedVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"asteriskTotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showItems\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"editData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"disableFieldList\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showCalcMbrs\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"visualTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showMultipleLabel\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataDropDown\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"printDrill\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showMemberPropertyTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableWizard\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableFieldProperties\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"useAutoFormatting\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"pageWrap\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"pageOverThenDown\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalHiddenItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"colGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fieldPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mergeItem\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showDropZones\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"showEmptyRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showEmptyCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showHeaders\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outlineData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"compactData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"gridDropZones\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"immersive\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleFieldFilters\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"chartFormat\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"rowHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"colHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fieldListSortAscending\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mdxSubqueries\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customListSort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Location\">\n    <xsd:attribute name=\"ref\" use=\"required\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"firstHeaderRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataCol\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"rowPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"colPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotField\" maxOccurs=\"unbounded\" type=\"CT_PivotField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotField\">\n    <xsd:sequence>\n      <xsd:element name=\"items\" minOccurs=\"0\" type=\"CT_Items\"/>\n      <xsd:element name=\"autoSortScope\" minOccurs=\"0\" type=\"CT_AutoSortScope\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"axis\" use=\"optional\" type=\"ST_Axis\"/>\n    <xsd:attribute name=\"dataField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showDropDowns\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hiddenLevel\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueMemberProperty\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"allDrilled\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showAll\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"insertBlankRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"insertPageBreak\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"autoShow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"topAutoShow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hideNewItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"measureFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPageCount\" type=\"xsd:unsignedInt\" default=\"10\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_FieldSortType\" default=\"manual\"/>\n    <xsd:attribute name=\"dataSourceSort\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nonAutoSortDefault\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rankBy\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showPropCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultAttributeDrillState\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoSortScope\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Items\">\n    <xsd:sequence>\n      <xsd:element name=\"item\" maxOccurs=\"unbounded\" type=\"CT_Item\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Item\">\n    <xsd:attribute name=\"n\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"h\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"m\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"e\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pageField\" maxOccurs=\"unbounded\" type=\"CT_PageField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"item\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cap\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataFields\">\n    <xsd:sequence>\n      <xsd:element name=\"dataField\" maxOccurs=\"unbounded\" type=\"CT_DataField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataField\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"subtotal\" type=\"ST_DataConsolidateFunction\" default=\"sum\"/>\n    <xsd:attribute name=\"showDataAs\" type=\"ST_ShowDataAs\" default=\"normal\"/>\n    <xsd:attribute name=\"baseField\" type=\"xsd:int\" default=\"-1\"/>\n    <xsd:attribute name=\"baseItem\" type=\"xsd:unsignedInt\" default=\"1048832\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_rowItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_colItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_I\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_X\">\n    <xsd:attribute name=\"v\" type=\"xsd:int\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Field\">\n    <xsd:attribute name=\"x\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formats\">\n    <xsd:sequence>\n      <xsd:element name=\"format\" maxOccurs=\"unbounded\" type=\"CT_Format\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Format\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"action\" type=\"ST_FormatAction\" default=\"formatting\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"conditionalFormat\" maxOccurs=\"unbounded\" type=\"CT_ConditionalFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotAreas\" type=\"CT_PivotAreas\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"scope\" type=\"ST_Scope\" default=\"selection\"/>\n    <xsd:attribute name=\"type\" type=\"ST_Type\" default=\"none\"/>\n    <xsd:attribute name=\"priority\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreas\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Scope\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"selection\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"field\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Type\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"column\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChartFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"chartFormat\" maxOccurs=\"unbounded\" type=\"CT_ChartFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"chart\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"format\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"series\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotHierarchy\" maxOccurs=\"unbounded\" type=\"CT_PivotHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"mps\" minOccurs=\"0\" type=\"CT_MemberProperties\"/>\n      <xsd:element name=\"members\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Members\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showInFieldList\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"rowHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"colHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierarchyUsage\">\n    <xsd:attribute name=\"hierarchyUsage\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"mp\" maxOccurs=\"unbounded\" type=\"CT_MemberProperty\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nameLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pPos\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"field\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Members\">\n    <xsd:sequence>\n      <xsd:element name=\"member\" maxOccurs=\"unbounded\" type=\"CT_Member\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"level\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Member\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dimensions\">\n    <xsd:sequence>\n      <xsd:element name=\"dimension\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotDimension\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotDimension\">\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroups\">\n    <xsd:sequence>\n      <xsd:element name=\"measureGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMaps\">\n    <xsd:sequence>\n      <xsd:element name=\"map\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureDimensionMap\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroup\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMap\">\n    <xsd:attribute name=\"measureGroup\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dimension\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotTableStyle\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"showRowHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotFilter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_AutoFilter\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"mpFld\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" use=\"required\" type=\"ST_PivotFilterType\"/>\n    <xsd:attribute name=\"evalOrder\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureHier\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureFld\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue1\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue2\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShowDataAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"difference\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"percentDiff\"/>\n      <xsd:enumeration value=\"runTotal\"/>\n      <xsd:enumeration value=\"percentOfRow\"/>\n      <xsd:enumeration value=\"percentOfCol\"/>\n      <xsd:enumeration value=\"percentOfTotal\"/>\n      <xsd:enumeration value=\"index\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ItemType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"countA\"/>\n      <xsd:enumeration value=\"avg\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevP\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varP\"/>\n      <xsd:enumeration value=\"grand\"/>\n      <xsd:enumeration value=\"blank\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormatAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"formatting\"/>\n      <xsd:enumeration value=\"drill\"/>\n      <xsd:enumeration value=\"formula\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FieldSortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PivotFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"unknown\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"captionEqual\"/>\n      <xsd:enumeration value=\"captionNotEqual\"/>\n      <xsd:enumeration value=\"captionBeginsWith\"/>\n      <xsd:enumeration value=\"captionNotBeginsWith\"/>\n      <xsd:enumeration value=\"captionEndsWith\"/>\n      <xsd:enumeration value=\"captionNotEndsWith\"/>\n      <xsd:enumeration value=\"captionContains\"/>\n      <xsd:enumeration value=\"captionNotContains\"/>\n      <xsd:enumeration value=\"captionGreaterThan\"/>\n      <xsd:enumeration value=\"captionGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"captionLessThan\"/>\n      <xsd:enumeration value=\"captionLessThanOrEqual\"/>\n      <xsd:enumeration value=\"captionBetween\"/>\n      <xsd:enumeration value=\"captionNotBetween\"/>\n      <xsd:enumeration value=\"valueEqual\"/>\n      <xsd:enumeration value=\"valueNotEqual\"/>\n      <xsd:enumeration value=\"valueGreaterThan\"/>\n      <xsd:enumeration value=\"valueGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"valueLessThan\"/>\n      <xsd:enumeration value=\"valueLessThanOrEqual\"/>\n      <xsd:enumeration value=\"valueBetween\"/>\n      <xsd:enumeration value=\"valueNotBetween\"/>\n      <xsd:enumeration value=\"dateEqual\"/>\n      <xsd:enumeration value=\"dateNotEqual\"/>\n      <xsd:enumeration value=\"dateOlderThan\"/>\n      <xsd:enumeration value=\"dateOlderThanOrEqual\"/>\n      <xsd:enumeration value=\"dateNewerThan\"/>\n      <xsd:enumeration value=\"dateNewerThanOrEqual\"/>\n      <xsd:enumeration value=\"dateBetween\"/>\n      <xsd:enumeration value=\"dateNotBetween\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"references\" minOccurs=\"0\" type=\"CT_PivotAreaReferences\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PivotAreaType\" default=\"normal\"/>\n    <xsd:attribute name=\"dataOnly\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"labelOnly\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"cacheIndex\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"offset\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"collapsedLevelsAreSubtotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PivotAreaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"origin\"/>\n      <xsd:enumeration value=\"button\"/>\n      <xsd:enumeration value=\"topEnd\"/>\n      <xsd:enumeration value=\"topRight\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotAreaReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"reference\" maxOccurs=\"unbounded\" type=\"CT_PivotAreaReference\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreaReference\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"selected\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"byPosition\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"relative\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Index\">\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Axis\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"axisRow\"/>\n      <xsd:enumeration value=\"axisCol\"/>\n      <xsd:enumeration value=\"axisPage\"/>\n      <xsd:enumeration value=\"axisValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"queryTable\" type=\"CT_QueryTable\"/>\n  <xsd:complexType name=\"CT_QueryTable\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableRefresh\" type=\"CT_QueryTableRefresh\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"headers\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"backgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"firstBackgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"growShrinkType\" type=\"ST_GrowShrinkType\" use=\"optional\"\n      default=\"insertDelete\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removeDataOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"adjustColumnWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"intermediate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableRefresh\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableFields\" type=\"CT_QueryTableFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"queryTableDeletedFields\" type=\"CT_QueryTableDeletedFields\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserveSortFilterLayout\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fieldIdWrapped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headersInLastRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"minimumVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"nextId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"unboundColumnsLeft\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"unboundColumnsRight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableDeletedFields\">\n    <xsd:sequence>\n      <xsd:element name=\"deletedField\" type=\"CT_DeletedField\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DeletedField\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableFields\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableField\" type=\"CT_QueryTableField\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataBound\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clipped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tableColumnId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GrowShrinkType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertDelete\"/>\n      <xsd:enumeration value=\"insertClear\"/>\n      <xsd:enumeration value=\"overwriteClear\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"sst\" type=\"CT_Sst\"/>\n  <xsd:complexType name=\"CT_Sst\">\n    <xsd:sequence>\n      <xsd:element name=\"si\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"uniqueCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhoneticType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"halfwidthKatakana\"/>\n      <xsd:enumeration value=\"fullwidthKatakana\"/>\n      <xsd:enumeration value=\"Hiragana\"/>\n      <xsd:enumeration value=\"noConversion\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhoneticAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhoneticRun\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RElt\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPrElt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrElt\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rFont\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rst\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"r\" type=\"CT_RElt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPh\" type=\"CT_PhoneticRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"phoneticPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PhoneticPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhoneticPr\">\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PhoneticType\" use=\"optional\" default=\"fullwidthKatakana\"/>\n    <xsd:attribute name=\"alignment\" type=\"ST_PhoneticAlignment\" use=\"optional\" default=\"left\"/>\n  </xsd:complexType>\n  <xsd:element name=\"headers\" type=\"CT_RevisionHeaders\"/>\n  <xsd:element name=\"revisions\" type=\"CT_Revisions\"/>\n  <xsd:complexType name=\"CT_RevisionHeaders\">\n    <xsd:sequence>\n      <xsd:element name=\"header\" type=\"CT_RevisionHeader\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"lastGuid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shared\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"diskRevisions\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"trackRevisions\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"exclusive\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"revisionId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"version\" type=\"xsd:int\" default=\"1\"/>\n    <xsd:attribute name=\"keepChangeHistory\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"protected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveHistory\" type=\"xsd:unsignedInt\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Revisions\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rrc\" type=\"CT_RevisionRowColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rm\" type=\"CT_RevisionMove\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcv\" type=\"CT_RevisionCustomView\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rsnm\" type=\"CT_RevisionSheetRename\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ris\" type=\"CT_RevisionInsertSheet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"raf\" type=\"CT_RevisionAutoFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rdn\" type=\"CT_RevisionDefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcmt\" type=\"CT_RevisionComment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rqt\" type=\"CT_RevisionQueryTableField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcft\" type=\"CT_RevisionConflict\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_RevData\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ua\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ra\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_RevisionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetIdMap\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_SheetIdMap\"/>\n      <xsd:element name=\"reviewedList\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ReviewedRevisions\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"maxSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"minRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"maxRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetIdMap\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetId\" type=\"CT_SheetId\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetId\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReviewedRevisions\">\n    <xsd:sequence>\n      <xsd:element name=\"reviewed\" type=\"CT_Reviewed\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Reviewed\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UndoInfo\">\n    <xsd:attribute name=\"index\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"exp\" type=\"ST_FormulaExpression\" use=\"required\"/>\n    <xsd:attribute name=\"ref3D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"array\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cs\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dr\" type=\"ST_RefA\" use=\"required\"/>\n    <xsd:attribute name=\"dn\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionRowColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_rwColActionType\" use=\"required\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionMove\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"source\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"destination\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"sourceSheetId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCustomView\">\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionSheetRename\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"oldName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"newName\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionInsertSheet\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetPosition\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCellChange\">\n    <xsd:sequence>\n      <xsd:element name=\"oc\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nc\" type=\"CT_Cell\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"odxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ndxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"odxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldQuotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"oldPh\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"endOfListFormulaUpdate\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionAutoFormatting\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionComment\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"cell\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" default=\"add\"/>\n    <xsd:attribute name=\"alwaysShow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"author\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"oldLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"newLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionDefinedName\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oldFormula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"customView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldFunction\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldFunctionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"shortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldShortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldHidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldCustomMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldDescription\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldHelp\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldStatusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldComment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionConflict\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionQueryTableField\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"fieldId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_rwColActionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertRow\"/>\n      <xsd:enumeration value=\"deleteRow\"/>\n      <xsd:enumeration value=\"insertCol\"/>\n      <xsd:enumeration value=\"deleteCol\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RevisionAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"add\"/>\n      <xsd:enumeration value=\"delete\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormulaExpression\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ref\"/>\n      <xsd:enumeration value=\"refError\"/>\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"areaError\"/>\n      <xsd:enumeration value=\"computedArea\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"users\" type=\"CT_Users\"/>\n  <xsd:complexType name=\"CT_Users\">\n    <xsd:sequence>\n      <xsd:element name=\"userInfo\" minOccurs=\"0\" maxOccurs=\"256\" type=\"CT_SharedUser\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedUser\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"worksheet\" type=\"CT_Worksheet\"/>\n  <xsd:element name=\"chartsheet\" type=\"CT_Chartsheet\"/>\n  <xsd:element name=\"dialogsheet\" type=\"CT_Dialogsheet\"/>\n  <xsd:complexType name=\"CT_Macrosheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dialogsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" minOccurs=\"0\" type=\"CT_SheetPr\"/>\n      <xsd:element name=\"sheetViews\" minOccurs=\"0\" type=\"CT_SheetViews\"/>\n      <xsd:element name=\"sheetFormatPr\" minOccurs=\"0\" type=\"CT_SheetFormatPr\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" minOccurs=\"0\" type=\"CT_CustomSheetViews\"/>\n      <xsd:element name=\"printOptions\" minOccurs=\"0\" type=\"CT_PrintOptions\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" minOccurs=\"0\" type=\"CT_PageSetup\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" minOccurs=\"0\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"legacyDrawing\" minOccurs=\"0\" type=\"CT_LegacyDrawing\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Worksheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetCalcPr\" type=\"CT_SheetCalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protectedRanges\" type=\"CT_ProtectedRanges\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scenarios\" type=\"CT_Scenarios\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mergeCells\" type=\"CT_MergeCells\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dataValidations\" type=\"CT_DataValidations\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hyperlinks\" type=\"CT_Hyperlinks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellWatches\" type=\"CT_CellWatches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ignoredErrors\" type=\"CT_IgnoredErrors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableParts\" type=\"CT_TableParts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetCalcPr\">\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetFormatPr\">\n    <xsd:attribute name=\"baseColWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"8\"/>\n    <xsd:attribute name=\"defaultColWidth\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultRowHeight\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zeroHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevelRow\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"outlineLevelCol\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cols\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"CT_Col\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Col\">\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bestFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"phonetic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellSpan\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellSpans\">\n    <xsd:list itemType=\"ST_CellSpan\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spans\" type=\"ST_CellSpans\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"customFormat\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ht\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cell\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_CellFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"is\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"cm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"inlineStr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellFormulaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"array\"/>\n      <xsd:enumeration value=\"dataTable\"/>\n      <xsd:enumeration value=\"shared\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlinePr\" type=\"CT_OutlinePr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetUpPr\" type=\"CT_PageSetUpPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"syncHorizontal\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncVertical\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"transitionEvaluation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"transitionEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filterMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableFormatConditionsCalculation\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetDimension\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_SheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"pivotSelection\" type=\"CT_PivotSelection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"windowProtection\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowColHeaders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showZeros\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rightToLeft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultGridColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showWhiteSpace\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" use=\"optional\" default=\"normal\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"64\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"zoomScaleNormal\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScaleSheetLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScalePageLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pane\">\n    <xsd:attribute name=\"xSplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ySplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activePane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"state\" type=\"ST_PaneState\" use=\"optional\" default=\"split\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSelection\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"showHeader\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"label\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"extendable\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"dimension\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"click\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Selection\">\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"activeCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activeCellId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\" default=\"A1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bottomRight\"/>\n      <xsd:enumeration value=\"topRight\"/>\n      <xsd:enumeration value=\"bottomLeft\"/>\n      <xsd:enumeration value=\"topLeft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"brk\" type=\"CT_Break\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"manualBreakCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Break\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"man\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetViewType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"pageBreakPreview\"/>\n      <xsd:enumeration value=\"pageLayout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OutlinePr\">\n    <xsd:attribute name=\"applyStyles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"summaryBelow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"summaryRight\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetUpPr\">\n    <xsd:attribute name=\"autoPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataConsolidate\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRefs\" type=\"CT_DataRefs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"function\" type=\"ST_DataConsolidateFunction\" use=\"optional\" default=\"sum\"/>\n    <xsd:attribute name=\"startLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"leftLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"topLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"link\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataConsolidateFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevp\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varp\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DataRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRef\" type=\"CT_DataRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataRef\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCells\">\n    <xsd:sequence>\n      <xsd:element name=\"mergeCell\" type=\"CT_MergeCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCell\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTags\" type=\"CT_CellSmartTags\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTag\" type=\"CT_CellSmartTag\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTag\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTagPr\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CellSmartTagPr\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlBased\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTagPr\">\n    <xsd:attribute name=\"key\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LegacyDrawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DrawingHF\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"lho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"che\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"chf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomSheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" default=\"64\"/>\n    <xsd:attribute name=\"showPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"outlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"zeroValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"printArea\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAutoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"filterUnique\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" default=\"normal\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidations\">\n    <xsd:sequence>\n      <xsd:element name=\"dataValidation\" type=\"CT_DataValidation\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"disablePrompts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidation\">\n    <xsd:sequence>\n      <xsd:element name=\"formula1\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formula2\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_DataValidationType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"errorStyle\" type=\"ST_DataValidationErrorStyle\" use=\"optional\"\n      default=\"stop\"/>\n    <xsd:attribute name=\"imeMode\" type=\"ST_DataValidationImeMode\" use=\"optional\" default=\"noControl\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_DataValidationOperator\" use=\"optional\" default=\"between\"/>\n    <xsd:attribute name=\"allowBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showDropDown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInputMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showErrorMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errorTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"error\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"promptTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"prompt\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataValidationType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"list\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"time\"/>\n      <xsd:enumeration value=\"textLength\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationErrorStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stop\"/>\n      <xsd:enumeration value=\"warning\"/>\n      <xsd:enumeration value=\"information\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationImeMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"disabled\"/>\n      <xsd:enumeration value=\"hiragana\"/>\n      <xsd:enumeration value=\"fullKatakana\"/>\n      <xsd:enumeration value=\"halfKatakana\"/>\n      <xsd:enumeration value=\"fullAlpha\"/>\n      <xsd:enumeration value=\"halfAlpha\"/>\n      <xsd:enumeration value=\"fullHangul\"/>\n      <xsd:enumeration value=\"halfHangul\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"expression\"/>\n      <xsd:enumeration value=\"cellIs\"/>\n      <xsd:enumeration value=\"colorScale\"/>\n      <xsd:enumeration value=\"dataBar\"/>\n      <xsd:enumeration value=\"iconSet\"/>\n      <xsd:enumeration value=\"top10\"/>\n      <xsd:enumeration value=\"uniqueValues\"/>\n      <xsd:enumeration value=\"duplicateValues\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContainsText\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n      <xsd:enumeration value=\"containsBlanks\"/>\n      <xsd:enumeration value=\"notContainsBlanks\"/>\n      <xsd:enumeration value=\"containsErrors\"/>\n      <xsd:enumeration value=\"notContainsErrors\"/>\n      <xsd:enumeration value=\"timePeriod\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TimePeriod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"last7Days\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConditionalFormattingOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContains\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfvoType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"formula\"/>\n      <xsd:enumeration value=\"percentile\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ConditionalFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"cfRule\" type=\"CT_CfRule\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CfRule\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"3\"/>\n      <xsd:element name=\"colorScale\" type=\"CT_ColorScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataBar\" type=\"CT_DataBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconSet\" type=\"CT_IconSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfType\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"priority\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"stopIfTrue\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"aboveAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_ConditionalFormattingOperator\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"timePeriod\" type=\"ST_TimePeriod\" use=\"optional\"/>\n    <xsd:attribute name=\"rank\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"stdDev\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"equalAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlinks\">\n    <xsd:sequence>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"location\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"t\" type=\"ST_CellFormulaType\" use=\"optional\" default=\"normal\"/>\n        <xsd:attribute name=\"aca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n        <xsd:attribute name=\"dt2D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"dtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del1\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del2\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"r1\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"r2\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"ca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"bx\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorScale\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBar\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"minLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"10\"/>\n    <xsd:attribute name=\"maxLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"90\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconSet\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3TrafficLights1\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"reverse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cfvo\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfvoType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"gte\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintOptions\">\n    <xsd:attribute name=\"horizontalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"verticalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headings\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLinesSet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToHeight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"pageOrder\" type=\"ST_PageOrder\" use=\"optional\" default=\"downThenOver\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellComments\" type=\"ST_CellComments\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errors\" type=\"ST_PrintError\" use=\"optional\" default=\"displayed\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"downThenOver\"/>\n      <xsd:enumeration value=\"overThenDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellComments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"asDisplayed\"/>\n      <xsd:enumeration value=\"atEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"scaleWithDoc\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintError\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"displayed\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"NA\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Scenarios\">\n    <xsd:sequence>\n      <xsd:element name=\"scenario\" type=\"CT_Scenario\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"current\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scenarios\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formatCells\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertHyperlinks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectLockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"pivotTables\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectUnlockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRanges\">\n    <xsd:sequence>\n      <xsd:element name=\"protectedRange\" type=\"CT_ProtectedRange\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRange\">\n    <xsd:sequence>\n      <xsd:element name=\"securityDescriptor\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"securityDescriptor\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scenario\">\n    <xsd:sequence>\n      <xsd:element name=\"inputCells\" type=\"CT_InputCells\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"user\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InputCells\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"undone\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatches\">\n    <xsd:sequence>\n      <xsd:element name=\"cellWatch\" type=\"CT_CellWatch\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatch\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chartsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_ChartsheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_ChartsheetViews\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_ChartsheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomChartsheetViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_ChartsheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" default=\"100\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"content\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CsPageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomChartsheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"customPr\" type=\"CT_CustomProperty\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"oleObject\" type=\"CT_OleObject\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:element name=\"objectPr\" type=\"CT_ObjectPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dvAspect\" type=\"ST_DvAspect\" use=\"optional\" default=\"DVASPECT_CONTENT\"/>\n    <xsd:attribute name=\"link\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oleUpdate\" type=\"ST_OleUpdate\" use=\"optional\"/>\n    <xsd:attribute name=\"autoLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dde\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DvAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"DVASPECT_CONTENT\"/>\n      <xsd:enumeration value=\"DVASPECT_ICON\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OleUpdate\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"OLEUPDATE_ALWAYS\"/>\n      <xsd:enumeration value=\"OLEUPDATE_ONCALL\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebPublishItems\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishItem\" type=\"CT_WebPublishItem\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishItem\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceType\" type=\"ST_WebSourceType\" use=\"required\"/>\n    <xsd:attribute name=\"sourceRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Controls\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"controlPr\" type=\"CT_ControlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"recalcAlways\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"linkedCell\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"listFillRange\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"cf\" type=\"s:ST_Xstring\" use=\"optional\" default=\"pict\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sheet\"/>\n      <xsd:enumeration value=\"printArea\"/>\n      <xsd:enumeration value=\"autoFilter\"/>\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"pivotTable\"/>\n      <xsd:enumeration value=\"query\"/>\n      <xsd:enumeration value=\"label\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IgnoredErrors\">\n    <xsd:sequence>\n      <xsd:element name=\"ignoredError\" type=\"CT_IgnoredError\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IgnoredError\">\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"evalError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"twoDigitTextYear\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numberStoredAsText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formulaRange\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"unlockedFormula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"emptyCellReference\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"listDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calculatedColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PaneState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"split\"/>\n      <xsd:enumeration value=\"frozen\"/>\n      <xsd:enumeration value=\"frozenSplit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableParts\">\n    <xsd:sequence>\n      <xsd:element name=\"tablePart\" type=\"CT_TablePart\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePart\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"metadata\" type=\"CT_Metadata\"/>\n  <xsd:complexType name=\"CT_Metadata\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataTypes\" type=\"CT_MetadataTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"metadataStrings\" type=\"CT_MetadataStrings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mdxMetadata\" type=\"CT_MdxMetadata\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"futureMetadata\" type=\"CT_FutureMetadata\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"cellMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"valueMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataType\" type=\"CT_MetadataType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataType\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"minSupportedVersion\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ghostRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ghostCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"edit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"delete\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"copy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteValues\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteBorders\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteColWidths\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteNumberFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"merge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitFirst\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"rowColShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearAll\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"clearFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearContents\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"assign\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"coerce\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"adjust\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellMeta\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlocks\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_MetadataBlock\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"rc\" type=\"CT_MetadataRecord\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataRecord\">\n    <xsd:attribute name=\"t\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_FutureMetadataBlock\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"mdx\" type=\"CT_Mdx\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Mdx\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"t\" type=\"CT_MdxTuple\"/>\n      <xsd:element name=\"ms\" type=\"CT_MdxSet\"/>\n      <xsd:element name=\"p\" type=\"CT_MdxMemeberProp\"/>\n      <xsd:element name=\"k\" type=\"CT_MdxKPI\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"f\" type=\"ST_MdxFunctionType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxFunctionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"m\"/>\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"c\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"k\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxTuple\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ct\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"fi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxSet\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ns\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"o\" type=\"ST_MdxSetOrder\" use=\"optional\" default=\"u\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxSetOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"a\"/>\n      <xsd:enumeration value=\"d\"/>\n      <xsd:enumeration value=\"aa\"/>\n      <xsd:enumeration value=\"ad\"/>\n      <xsd:enumeration value=\"na\"/>\n      <xsd:enumeration value=\"nd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxMemeberProp\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxKPI\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"p\" type=\"ST_MdxKPIProperty\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxKPIProperty\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"g\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"m\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MetadataStringIndex\">\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataStrings\">\n    <xsd:sequence>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"singleXmlCells\" type=\"CT_SingleXmlCells\"/>\n  <xsd:complexType name=\"CT_SingleXmlCells\">\n    <xsd:sequence>\n      <xsd:element name=\"singleXmlCell\" type=\"CT_SingleXmlCell\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SingleXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlCellPr\" type=\"CT_XmlCellPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlCellPr\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlPr\" type=\"CT_XmlPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleSheet\" type=\"CT_Stylesheet\"/>\n  <xsd:complexType name=\"CT_Stylesheet\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmts\" type=\"CT_NumFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fonts\" type=\"CT_Fonts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fills\" type=\"CT_Fills\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"borders\" type=\"CT_Borders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyleXfs\" type=\"CT_CellStyleXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellXfs\" type=\"CT_CellXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyles\" type=\"CT_CellStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dxfs\" type=\"CT_Dxfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyles\" type=\"CT_TableStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colors\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellAlignment\">\n    <xsd:attribute name=\"horizontal\" type=\"ST_HorizontalAlignment\" use=\"optional\"/>\n    <xsd:attribute name=\"vertical\" type=\"ST_VerticalAlignment\" default=\"bottom\" use=\"optional\"/>\n    <xsd:attribute name=\"textRotation\" type=\"ST_TextRotation\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapText\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"relativeIndent\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"justifyLastLine\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"shrinkToFit\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"readingOrder\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextRotation\">\n    <xsd:union>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:maxInclusive value=\"180\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:enumeration value=\"255\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:union>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"thin\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hair\"/>\n      <xsd:enumeration value=\"mediumDashed\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"mediumDashDot\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"mediumDashDotDot\"/>\n      <xsd:enumeration value=\"slantDashDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Borders\">\n    <xsd:sequence>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"top\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"diagonal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertical\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"horizontal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"diagonalUp\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"diagonalDown\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderPr\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"style\" type=\"ST_BorderStyle\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellProtection\">\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fills\">\n    <xsd:sequence>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"patternFill\" type=\"CT_PatternFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradientFill\" type=\"CT_GradientFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PatternFill\">\n    <xsd:sequence>\n      <xsd:element name=\"fgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"patternType\" type=\"ST_PatternType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"auto\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indexed\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"theme\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tint\" type=\"xsd:double\" use=\"optional\" default=\"0.0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PatternType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"mediumGray\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"darkHorizontal\"/>\n      <xsd:enumeration value=\"darkVertical\"/>\n      <xsd:enumeration value=\"darkDown\"/>\n      <xsd:enumeration value=\"darkUp\"/>\n      <xsd:enumeration value=\"darkGrid\"/>\n      <xsd:enumeration value=\"darkTrellis\"/>\n      <xsd:enumeration value=\"lightHorizontal\"/>\n      <xsd:enumeration value=\"lightVertical\"/>\n      <xsd:enumeration value=\"lightDown\"/>\n      <xsd:enumeration value=\"lightUp\"/>\n      <xsd:enumeration value=\"lightGrid\"/>\n      <xsd:enumeration value=\"lightTrellis\"/>\n      <xsd:enumeration value=\"gray125\"/>\n      <xsd:enumeration value=\"gray0625\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientFill\">\n    <xsd:sequence>\n      <xsd:element name=\"stop\" type=\"CT_GradientStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_GradientType\" use=\"optional\" default=\"linear\"/>\n    <xsd:attribute name=\"degree\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"position\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GradientType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"path\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"fill\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"centerContinuous\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyleXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Xf\">\n    <xsd:sequence>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"optional\"/>\n    <xsd:attribute name=\"fillId\" type=\"ST_FillId\" use=\"optional\"/>\n    <xsd:attribute name=\"borderId\" type=\"ST_BorderId\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pivotButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"applyNumberFormat\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFont\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFill\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyBorder\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyAlignment\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyProtection\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"cellStyle\" type=\"CT_CellStyle\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"required\"/>\n    <xsd:attribute name=\"builtinId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iLevel\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"customBuiltin\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxfs\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxf\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumFmtId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellStyleXfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DxfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:element name=\"indexedColors\" type=\"CT_IndexedColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mruColors\" type=\"CT_MRUColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IndexedColors\">\n    <xsd:sequence>\n      <xsd:element name=\"rgbColor\" type=\"CT_RgbColor\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MRUColors\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RgbColor\">\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultTableStyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultPivotStyle\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyleElement\" type=\"CT_TableStyleElement\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"table\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TableStyleType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableStyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"headerRow\"/>\n      <xsd:enumeration value=\"totalRow\"/>\n      <xsd:enumeration value=\"firstColumn\"/>\n      <xsd:enumeration value=\"lastColumn\"/>\n      <xsd:enumeration value=\"firstRowStripe\"/>\n      <xsd:enumeration value=\"secondRowStripe\"/>\n      <xsd:enumeration value=\"firstColumnStripe\"/>\n      <xsd:enumeration value=\"secondColumnStripe\"/>\n      <xsd:enumeration value=\"firstHeaderCell\"/>\n      <xsd:enumeration value=\"lastHeaderCell\"/>\n      <xsd:enumeration value=\"firstTotalCell\"/>\n      <xsd:enumeration value=\"lastTotalCell\"/>\n      <xsd:enumeration value=\"firstSubtotalColumn\"/>\n      <xsd:enumeration value=\"secondSubtotalColumn\"/>\n      <xsd:enumeration value=\"thirdSubtotalColumn\"/>\n      <xsd:enumeration value=\"firstSubtotalRow\"/>\n      <xsd:enumeration value=\"secondSubtotalRow\"/>\n      <xsd:enumeration value=\"thirdSubtotalRow\"/>\n      <xsd:enumeration value=\"blankRow\"/>\n      <xsd:enumeration value=\"firstColumnSubheading\"/>\n      <xsd:enumeration value=\"secondColumnSubheading\"/>\n      <xsd:enumeration value=\"thirdColumnSubheading\"/>\n      <xsd:enumeration value=\"firstRowSubheading\"/>\n      <xsd:enumeration value=\"secondRowSubheading\"/>\n      <xsd:enumeration value=\"thirdRowSubheading\"/>\n      <xsd:enumeration value=\"pageFieldLabels\"/>\n      <xsd:enumeration value=\"pageFieldValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BooleanProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSize\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IntProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignFontProperty\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:attribute name=\"val\" type=\"ST_FontScheme\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontScheme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnderlineProperty\">\n    <xsd:attribute name=\"val\" type=\"ST_UnderlineValues\" use=\"optional\" default=\"single\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnderlineValues\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"singleAccounting\"/>\n      <xsd:enumeration value=\"doubleAccounting\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"14\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_AutoFormat\">\n    <xsd:attribute name=\"autoFormatId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"applyNumberFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyBorderFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyFontFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyPatternFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyAlignmentFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyWidthHeightFormats\" type=\"xsd:boolean\"/>\n  </xsd:attributeGroup>\n  <xsd:element name=\"externalLink\" type=\"CT_ExternalLink\"/>\n  <xsd:complexType name=\"CT_ExternalLink\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"externalBook\" type=\"CT_ExternalBook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ddeLink\" type=\"CT_DdeLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"oleLink\" type=\"CT_OleLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalBook\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetNames\" type=\"CT_ExternalSheetNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_ExternalDefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetDataSet\" type=\"CT_ExternalSheetDataSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetNames\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetName\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_ExternalSheetName\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_ExternalDefinedName\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedName\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"refersTo\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetDataSet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetData\" type=\"CT_ExternalSheetData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_ExternalRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"refreshError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalRow\">\n    <xsd:sequence>\n      <xsd:element name=\"cell\" type=\"CT_ExternalCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalCell\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeLink\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItems\" type=\"CT_DdeItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ddeService\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"ddeTopic\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItems\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItem\" type=\"CT_DdeItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItem\">\n    <xsd:sequence>\n      <xsd:element name=\"values\" type=\"CT_DdeValues\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" default=\"0\"/>\n    <xsd:attribute name=\"ole\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValues\">\n    <xsd:sequence>\n      <xsd:element name=\"value\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_DdeValue\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rows\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cols\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_DdeValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DdeValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"str\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleLink\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItems\" type=\"CT_OleItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItems\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItem\" type=\"CT_OleItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"icon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"table\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableColumns\" type=\"CT_TableColumns\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyleInfo\" type=\"CT_TableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"displayName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"tableType\" type=\"ST_TableType\" use=\"optional\" default=\"worksheet\"/>\n    <xsd:attribute name=\"headerRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"insertRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"insertRowShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"totalsRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"totalsRowShown\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"tableBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"xml\"/>\n      <xsd:enumeration value=\"queryTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleInfo\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showFirstColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showColumnStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumns\">\n    <xsd:sequence>\n      <xsd:element name=\"tableColumn\" type=\"CT_TableColumn\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumn\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedColumnFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"totalsRowFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xmlColumnPr\" type=\"CT_XmlColumnPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"totalsRowFunction\" type=\"ST_TotalsRowFunction\" use=\"optional\"\n      default=\"none\"/>\n    <xsd:attribute name=\"totalsRowLabel\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"queryTableFieldId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"array\" type=\"xsd:boolean\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TotalsRowFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XmlColumnPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"denormalized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_XmlDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:element name=\"volTypes\" type=\"CT_VolTypes\"/>\n  <xsd:complexType name=\"CT_VolTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"volType\" type=\"CT_VolType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolType\">\n    <xsd:sequence>\n      <xsd:element name=\"main\" type=\"CT_VolMain\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_VolDepType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolMain\">\n    <xsd:sequence>\n      <xsd:element name=\"tp\" type=\"CT_VolTopic\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"first\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopic\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stp\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tr\" type=\"CT_VolTopicRef\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_VolValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopicRef\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VolDepType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"realTimeData\"/>\n      <xsd:enumeration value=\"olapFunctions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VolValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"workbook\" type=\"CT_Workbook\"/>\n  <xsd:complexType name=\"CT_Workbook\">\n    <xsd:sequence>\n      <xsd:element name=\"fileVersion\" type=\"CT_FileVersion\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileSharing\" type=\"CT_FileSharing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookPr\" type=\"CT_WorkbookPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookProtection\" type=\"CT_WorkbookProtection\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"bookViews\" type=\"CT_BookViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheets\" type=\"CT_Sheets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"functionGroups\" type=\"CT_FunctionGroups\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalReferences\" type=\"CT_ExternalReferences\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_DefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"calcPr\" type=\"CT_CalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleSize\" type=\"CT_OleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customWorkbookViews\" type=\"CT_CustomWorkbookViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotCaches\" type=\"CT_PivotCaches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagTypes\" type=\"CT_SmartTagTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishing\" type=\"CT_WebPublishing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileRecoveryPr\" type=\"CT_FileRecoveryPr\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"webPublishObjects\" type=\"CT_WebPublishObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileVersion\">\n    <xsd:attribute name=\"appName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lastEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lowestEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rupBuild\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"codeName\" type=\"s:ST_Guid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"workbookView\" type=\"CT_BookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"visibility\" type=\"ST_Visibility\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"firstSheet\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"activeTab\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"autoFilterDateGrouping\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Visibility\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CustomWorkbookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customWorkbookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomWorkbookView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomWorkbookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"autoUpdate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"mergeInterval\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"changesSavedWin\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"onlySync\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"personalView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"includePrintSettings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"includeHiddenRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"maximized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"activeSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"showFormulaBar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showStatusbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showComments\" type=\"ST_Comments\" use=\"optional\" default=\"commIndicator\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Comments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"commNone\"/>\n      <xsd:enumeration value=\"commIndicator\"/>\n      <xsd:enumeration value=\"commIndAndComment\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Objects\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"placeholders\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Sheets\">\n    <xsd:sequence>\n      <xsd:element name=\"sheet\" type=\"CT_Sheet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sheet\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorkbookPr\">\n    <xsd:attribute name=\"date1904\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"showBorderUnselectedTables\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n    <xsd:attribute name=\"filterPrivacy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"promptedSolutions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInkAnnotation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"backupFile\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveExternalLinkValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"updateLinks\" type=\"ST_UpdateLinks\" use=\"optional\" default=\"userSet\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hidePivotFieldList\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPivotChartFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"allowRefreshQuery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"publishItems\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"checkCompatibility\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshAllConnections\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultThemeVersion\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UpdateLinks\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"userSet\"/>\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:attribute name=\"embed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"show\" type=\"ST_SmartTagShow\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SmartTagShow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"noIndicator\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceUri\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileRecoveryPr\">\n    <xsd:attribute name=\"autoRecover\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"crashSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dataExtractLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"repairLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcPr\">\n    <xsd:attribute name=\"calcId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"calcMode\" type=\"ST_CalcMode\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refMode\" type=\"ST_RefMode\" use=\"optional\" default=\"A1\"/>\n    <xsd:attribute name=\"iterate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"iterateCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"iterateDelta\" type=\"xsd:double\" use=\"optional\" default=\"0.001\"/>\n    <xsd:attribute name=\"fullPrecision\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcCompleted\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentCalc\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentManualCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"forceFullCalc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CalcMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"autoNoTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"A1\"/>\n      <xsd:enumeration value=\"R1C1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_DefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefinedName\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n        <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"vbProcedure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"xlm\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"shortcutKey\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"publishToServer\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"workbookParameter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"externalReference\" type=\"CT_ExternalReference\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReference\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetBackgroundPicture\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCaches\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotCache\" type=\"CT_PivotCache\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCache\">\n    <xsd:attribute name=\"cacheId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileSharing\">\n    <xsd:attribute name=\"readOnlyRecommended\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"reservationPassword\" type=\"ST_UnsignedShortHex\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleSize\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WorkbookProtection\">\n    <xsd:attribute name=\"workbookPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lockStructure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockWindows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockRevision\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"revisionsAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishing\">\n    <xsd:attribute name=\"css\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"thicket\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"longFileNames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"vml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"targetScreenSize\" type=\"ST_TargetScreenSize\" use=\"optional\"\n      default=\"800x600\"/>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"96\"/>\n    <xsd:attribute name=\"codePage\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FunctionGroups\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"functionGroup\" type=\"CT_FunctionGroup\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"builtInGroupCount\" type=\"xsd:unsignedInt\" default=\"16\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FunctionGroup\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishObject\" type=\"CT_WebPublishObject\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObject\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:schemas-microsoft-com:vml\"\n  xmlns:pvml=\"urn:schemas-microsoft-com:office:powerpoint\"\n  xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:w10=\"urn:schemas-microsoft-com:office:word\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:vml\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:office\"\n    schemaLocation=\"vml-officeDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:word\"\n    schemaLocation=\"vml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:excel\"\n    schemaLocation=\"vml-spreadsheetDrawing.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:powerpoint\"\n    schemaLocation=\"vml-presentationDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attributeGroup name=\"AG_Id\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Style\">\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Type\">\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Adj\">\n    <xsd:attribute name=\"adj\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Path\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Fill\">\n    <xsd:attribute name=\"filled\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Chromakey\">\n    <xsd:attribute name=\"chromakey\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Ext\">\n    <xsd:attribute name=\"ext\" form=\"qualified\" type=\"ST_Ext\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_CoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"href\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"class\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"alt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordsize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"print\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"stroked\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeweight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeCoreAttributes\">\n    <xsd:attribute ref=\"o:spid\"/>\n    <xsd:attribute ref=\"o:oned\"/>\n    <xsd:attribute ref=\"o:regroupid\"/>\n    <xsd:attribute ref=\"o:doubleclicknotify\"/>\n    <xsd:attribute ref=\"o:button\"/>\n    <xsd:attribute ref=\"o:userhidden\"/>\n    <xsd:attribute ref=\"o:bullet\"/>\n    <xsd:attribute ref=\"o:hr\"/>\n    <xsd:attribute ref=\"o:hrstd\"/>\n    <xsd:attribute ref=\"o:hrnoshade\"/>\n    <xsd:attribute ref=\"o:hrpct\"/>\n    <xsd:attribute ref=\"o:hralign\"/>\n    <xsd:attribute ref=\"o:allowincell\"/>\n    <xsd:attribute ref=\"o:allowoverlap\"/>\n    <xsd:attribute ref=\"o:userdrawn\"/>\n    <xsd:attribute ref=\"o:bordertopcolor\"/>\n    <xsd:attribute ref=\"o:borderleftcolor\"/>\n    <xsd:attribute ref=\"o:borderbottomcolor\"/>\n    <xsd:attribute ref=\"o:borderrightcolor\"/>\n    <xsd:attribute ref=\"o:dgmlayout\"/>\n    <xsd:attribute ref=\"o:dgmnodekind\"/>\n    <xsd:attribute ref=\"o:dgmlayoutmru\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeShapeAttributes\">\n    <xsd:attribute ref=\"o:spt\"/>\n    <xsd:attribute ref=\"o:connectortype\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"o:oleicon\"/>\n    <xsd:attribute ref=\"o:ole\"/>\n    <xsd:attribute ref=\"o:preferrelative\"/>\n    <xsd:attribute ref=\"o:cliptowrap\"/>\n    <xsd:attribute ref=\"o:clip\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllCoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_CoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeCoreAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_ShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeShapeAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ImageAttributes\">\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropleft\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"croptop\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropright\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropbottom\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gain\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"blacklevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gamma\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"grayscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"bilevel\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_StrokeAttributes\">\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n  </xsd:attributeGroup>\n  <xsd:group name=\"EG_ShapeElements\">\n    <xsd:choice>\n      <xsd:element ref=\"path\"/>\n      <xsd:element ref=\"formulas\"/>\n      <xsd:element ref=\"handles\"/>\n      <xsd:element ref=\"fill\"/>\n      <xsd:element ref=\"stroke\"/>\n      <xsd:element ref=\"shadow\"/>\n      <xsd:element ref=\"textbox\"/>\n      <xsd:element ref=\"textpath\"/>\n      <xsd:element ref=\"imagedata\"/>\n      <xsd:element ref=\"o:skew\"/>\n      <xsd:element ref=\"o:extrusion\"/>\n      <xsd:element ref=\"o:callout\"/>\n      <xsd:element ref=\"o:lock\"/>\n      <xsd:element ref=\"o:clippath\"/>\n      <xsd:element ref=\"o:signatureline\"/>\n      <xsd:element ref=\"w10:wrap\"/>\n      <xsd:element ref=\"w10:anchorlock\"/>\n      <xsd:element ref=\"w10:bordertop\"/>\n      <xsd:element ref=\"w10:borderbottom\"/>\n      <xsd:element ref=\"w10:borderleft\"/>\n      <xsd:element ref=\"w10:borderright\"/>\n      <xsd:element ref=\"x:ClientData\" minOccurs=\"0\"/>\n      <xsd:element ref=\"pvml:textdata\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"shape\" type=\"CT_Shape\"/>\n  <xsd:element name=\"shapetype\" type=\"CT_Shapetype\"/>\n  <xsd:element name=\"group\" type=\"CT_Group\"/>\n  <xsd:element name=\"background\" type=\"CT_Background\"/>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n      <xsd:element ref=\"pvml:iscomment\"/>\n      <xsd:element ref=\"o:equationxml\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Type\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:gfxdata\"/>\n    <xsd:attribute name=\"equationxml\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shapetype\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"o:complex\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:master\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Group\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"group\"/>\n      <xsd:element ref=\"shape\"/>\n      <xsd:element ref=\"shapetype\"/>\n      <xsd:element ref=\"arc\"/>\n      <xsd:element ref=\"curve\"/>\n      <xsd:element ref=\"image\"/>\n      <xsd:element ref=\"line\"/>\n      <xsd:element ref=\"oval\"/>\n      <xsd:element ref=\"polyline\"/>\n      <xsd:element ref=\"rect\"/>\n      <xsd:element ref=\"roundrect\"/>\n      <xsd:element ref=\"o:diagram\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"editas\" type=\"ST_EditAs\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:tableproperties\"/>\n    <xsd:attribute ref=\"o:tablelimits\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:element ref=\"fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:targetscreensize\"/>\n  </xsd:complexType>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:element name=\"formulas\" type=\"CT_Formulas\"/>\n  <xsd:element name=\"handles\" type=\"CT_Handles\"/>\n  <xsd:element name=\"imagedata\" type=\"CT_ImageData\"/>\n  <xsd:element name=\"path\" type=\"CT_Path\"/>\n  <xsd:element name=\"textbox\" type=\"CT_Textbox\"/>\n  <xsd:element name=\"shadow\" type=\"CT_Shadow\"/>\n  <xsd:element name=\"stroke\" type=\"CT_Stroke\"/>\n  <xsd:element name=\"textpath\" type=\"CT_TextPath\"/>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"position\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"aspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"alignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"focus\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focussize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focusposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"method\" type=\"ST_FillMethod\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:opacity2\"/>\n    <xsd:attribute name=\"recolor\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotate\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formulas\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_F\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:attribute name=\"eqn\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Handles\">\n    <xsd:sequence>\n      <xsd:element name=\"h\" type=\"CT_H\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_H\">\n    <xsd:attribute name=\"position\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"polar\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"map\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"invx\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"invy\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"switch\" type=\"s:ST_TrueFalseBlank\"/>\n    <xsd:attribute name=\"xrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"yrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"radiusrange\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ImageData\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attribute name=\"embosscolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"recolortarget\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:oleid\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:movie\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n    <xsd:attribute ref=\"r:id\"/>\n    <xsd:attribute ref=\"r:pict\"/>\n    <xsd:attribute ref=\"r:href\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"limo\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textboxrect\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fillok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shadowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"arrowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"gradientshapeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textpathok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpenok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:connecttype\"/>\n    <xsd:attribute ref=\"o:connectlocs\"/>\n    <xsd:attribute ref=\"o:connectangles\"/>\n    <xsd:attribute ref=\"o:extrusionok\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shadow\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ShadowType\" use=\"optional\"/>\n    <xsd:attribute name=\"obscured\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"offset2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Stroke\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:left\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:top\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:right\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:bottom\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:column\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_StrokeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Textbox\">\n    <xsd:choice>\n      <xsd:element ref=\"w:txbxContent\" minOccurs=\"0\"/>\n      <xsd:any namespace=\"##local\" processContents=\"skip\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"inset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:singleclick\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextPath\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitpath\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"trim\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"xscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"string\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"arc\" type=\"CT_Arc\"/>\n  <xsd:element name=\"curve\" type=\"CT_Curve\"/>\n  <xsd:element name=\"image\" type=\"CT_Image\"/>\n  <xsd:element name=\"line\" type=\"CT_Line\"/>\n  <xsd:element name=\"oval\" type=\"CT_Oval\"/>\n  <xsd:element name=\"polyline\" type=\"CT_PolyLine\"/>\n  <xsd:element name=\"rect\" type=\"CT_Rect\"/>\n  <xsd:element name=\"roundrect\" type=\"CT_RoundRect\"/>\n  <xsd:complexType name=\"CT_Arc\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"startAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"endAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Curve\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control1\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Image\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Oval\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolyLine\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"points\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RoundRect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"arcsize\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Ext\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"view\"/>\n      <xsd:enumeration value=\"edit\"/>\n      <xsd:enumeration value=\"backwardCompatible\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"frame\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"sigma\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"linear sigma\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ShadowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"emboss\"/>\n      <xsd:enumeration value=\"perspective\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeLineStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thinThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeJoinStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"miter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeEndCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"round\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowLength\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"short\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"long\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"narrow\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"wide\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"block\"/>\n      <xsd:enumeration value=\"classic\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"open\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ImageAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ignore\"/>\n      <xsd:enumeration value=\"atMost\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"canvas\"/>\n      <xsd:enumeration value=\"orgchart\"/>\n      <xsd:enumeration value=\"radial\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"stacked\"/>\n      <xsd:enumeration value=\"venn\"/>\n      <xsd:enumeration value=\"bullseye\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:office\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:vml\" schemaLocation=\"vml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attribute name=\"bwmode\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwpure\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwnormal\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"targetscreensize\" type=\"ST_ScreenSize\"/>\n  <xsd:attribute name=\"insetmode\" type=\"ST_InsetMode\" default=\"custom\"/>\n  <xsd:attribute name=\"spt\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"oned\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"regroupid\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"doubleclicknotify\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"connectortype\" type=\"ST_ConnectorType\" default=\"straight\"/>\n  <xsd:attribute name=\"button\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userhidden\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"forcedash\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleicon\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"ole\" type=\"s:ST_TrueFalseBlank\"/>\n  <xsd:attribute name=\"preferrelative\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"cliptowrap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"clip\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bullet\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hr\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrstd\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrnoshade\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrpct\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"hralign\" type=\"ST_HrAlign\" default=\"left\"/>\n  <xsd:attribute name=\"allowincell\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"allowoverlap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userdrawn\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bordertopcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderleftcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderbottomcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderrightcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connecttype\" type=\"ST_ConnectType\"/>\n  <xsd:attribute name=\"connectlocs\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connectangles\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"master\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"extrusionok\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"href\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"althref\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"title\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"singleclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleid\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"detectmouseclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"movie\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"spid\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"opacity2\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"relid\" type=\"r:ST_RelationshipId\"/>\n  <xsd:attribute name=\"dgmlayout\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"dgmnodekind\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"dgmlayoutmru\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"gfxdata\" type=\"xsd:base64Binary\"/>\n  <xsd:attribute name=\"tableproperties\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"tablelimits\" type=\"xsd:string\"/>\n  <xsd:element name=\"shapedefaults\" type=\"CT_ShapeDefaults\"/>\n  <xsd:element name=\"shapelayout\" type=\"CT_ShapeLayout\"/>\n  <xsd:element name=\"signatureline\" type=\"CT_SignatureLine\"/>\n  <xsd:element name=\"ink\" type=\"CT_Ink\"/>\n  <xsd:element name=\"diagram\" type=\"CT_Diagram\"/>\n  <xsd:element name=\"equationxml\" type=\"CT_EquationXml\"/>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:all minOccurs=\"0\">\n      <xsd:element ref=\"v:fill\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:stroke\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:textbox\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:shadow\" minOccurs=\"0\"/>\n      <xsd:element ref=\"skew\" minOccurs=\"0\"/>\n      <xsd:element ref=\"extrusion\" minOccurs=\"0\"/>\n      <xsd:element ref=\"callout\" minOccurs=\"0\"/>\n      <xsd:element ref=\"lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"colormru\" minOccurs=\"0\" type=\"CT_ColorMru\"/>\n      <xsd:element name=\"colormenu\" minOccurs=\"0\" type=\"CT_ColorMenu\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"spidmax\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"stroke\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"allowincell\" form=\"qualified\" type=\"s:ST_TrueFalse\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ink\">\n    <xsd:sequence/>\n    <xsd:attribute name=\"i\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"annotation\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"contentType\" type=\"ST_ContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SignatureLine\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"issignatureline\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"provid\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"signinginstructionsset\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"allowcomments\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"showsigndate\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"suggestedsigner\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigner2\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigneremail\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"signinginstructions\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"addlxml\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"sigprovurl\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLayout\">\n    <xsd:all>\n      <xsd:element name=\"idmap\" type=\"CT_IdMap\" minOccurs=\"0\"/>\n      <xsd:element name=\"regrouptable\" type=\"CT_RegroupTable\" minOccurs=\"0\"/>\n      <xsd:element name=\"rules\" type=\"CT_Rules\" minOccurs=\"0\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IdMap\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RegroupTable\">\n    <xsd:sequence>\n      <xsd:element name=\"entry\" type=\"CT_Entry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Entry\">\n    <xsd:attribute name=\"new\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" type=\"CT_R\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"proxy\" type=\"CT_Proxy\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_RType\" use=\"optional\"/>\n    <xsd:attribute name=\"how\" type=\"ST_How\" use=\"optional\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Proxy\">\n    <xsd:attribute name=\"start\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"end\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"connectloc\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Diagram\">\n    <xsd:sequence>\n      <xsd:element name=\"relationtable\" type=\"CT_RelationTable\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"dgmstyle\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"autoformat\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"reverse\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autolayout\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscalex\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscaley\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmfontsize\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"constrainbounds\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmbasetextscale\" type=\"xsd:integer\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EquationXml\">\n    <xsd:sequence>\n      <xsd:any namespace=\"##any\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"contentType\" type=\"ST_AlternateMathContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlternateMathContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RelationTable\">\n    <xsd:sequence>\n      <xsd:element name=\"rel\" type=\"CT_Relation\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Relation\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"idsrc\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"iddest\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"idcntr\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMru\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMenu\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"shadowcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"extrusioncolor\" type=\"s:ST_ColorType\"/>\n  </xsd:complexType>\n  <xsd:element name=\"skew\" type=\"CT_Skew\"/>\n  <xsd:element name=\"extrusion\" type=\"CT_Extrusion\"/>\n  <xsd:element name=\"callout\" type=\"CT_Callout\"/>\n  <xsd:element name=\"lock\" type=\"CT_Lock\"/>\n  <xsd:element name=\"OLEObject\" type=\"CT_OLEObject\"/>\n  <xsd:element name=\"complex\" type=\"CT_Complex\"/>\n  <xsd:element name=\"left\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"top\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"right\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"bottom\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"column\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"clippath\" type=\"CT_ClipPath\"/>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:complexType name=\"CT_Skew\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extrusion\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ExtrusionType\" default=\"parallel\" use=\"optional\"/>\n    <xsd:attribute name=\"render\" type=\"ST_ExtrusionRender\" default=\"solid\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpointorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpoint\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"plane\" type=\"ST_ExtrusionPlane\" default=\"XY\" use=\"optional\"/>\n    <xsd:attribute name=\"skewangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"skewamt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"foredepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"backdepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientation\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientationangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"lockrotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autorotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationcenter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationangle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"colormode\" type=\"ST_ColorMode\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"shininess\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"specularity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"diffusity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"metal\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"facet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightface\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"brightness\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh2\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Callout\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gap\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"dropauto\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"drop\" type=\"ST_CalloutDrop\" use=\"optional\"/>\n    <xsd:attribute name=\"distance\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lengthspecified\" type=\"s:ST_TrueFalse\" default=\"f\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"accentbar\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textborder\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusx\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusy\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"position\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"selection\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"grouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"ungrouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotation\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"cropping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"verticies\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"adjusthandles\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"aspectratio\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shapetype\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OLEObject\">\n    <xsd:sequence>\n      <xsd:element name=\"LinkType\" type=\"ST_OLELinkType\" minOccurs=\"0\"/>\n      <xsd:element name=\"LockedField\" type=\"s:ST_TrueFalseBlank\" minOccurs=\"0\"/>\n      <xsd:element name=\"FieldCodes\" type=\"xsd:string\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"Type\" type=\"ST_OLEType\" use=\"optional\"/>\n    <xsd:attribute name=\"ProgID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"ShapeID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DrawAspect\" type=\"ST_OLEDrawAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"ObjectID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"UpdateMode\" type=\"ST_OLEUpdateMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Complex\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrokeChild\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"v:ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"v:ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"v:ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"v:ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"v:ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"href\"/>\n    <xsd:attribute ref=\"althref\"/>\n    <xsd:attribute ref=\"title\"/>\n    <xsd:attribute ref=\"forcedash\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipPath\">\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"required\" form=\"qualified\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"callout\"/>\n      <xsd:enumeration value=\"connector\"/>\n      <xsd:enumeration value=\"align\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_How\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"middle\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BWMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"color\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"grayScale\"/>\n      <xsd:enumeration value=\"lightGrayscale\"/>\n      <xsd:enumeration value=\"inverseGray\"/>\n      <xsd:enumeration value=\"grayOutline\"/>\n      <xsd:enumeration value=\"highContrast\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hide\"/>\n      <xsd:enumeration value=\"undrawn\"/>\n      <xsd:enumeration value=\"blackTextAndLines\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544,376\"/>\n      <xsd:enumeration value=\"640,480\"/>\n      <xsd:enumeration value=\"720,512\"/>\n      <xsd:enumeration value=\"800,600\"/>\n      <xsd:enumeration value=\"1024,768\"/>\n      <xsd:enumeration value=\"1152,862\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InsetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramLayout\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:enumeration value=\"0\"/>\n      <xsd:enumeration value=\"1\"/>\n      <xsd:enumeration value=\"2\"/>\n      <xsd:enumeration value=\"3\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"perspective\"/>\n      <xsd:enumeration value=\"parallel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionRender\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"wireFrame\"/>\n      <xsd:enumeration value=\"boundingCube\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionPlane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"XY\"/>\n      <xsd:enumeration value=\"ZX\"/>\n      <xsd:enumeration value=\"YZ\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"30\"/>\n      <xsd:enumeration value=\"45\"/>\n      <xsd:enumeration value=\"60\"/>\n      <xsd:enumeration value=\"90\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutDrop\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutPlacement\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"user\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"straight\"/>\n      <xsd:enumeration value=\"elbow\"/>\n      <xsd:enumeration value=\"curved\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HrAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"segments\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLELinkType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Embed\"/>\n      <xsd:enumeration value=\"Link\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Content\"/>\n      <xsd:enumeration value=\"Icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Always\"/>\n      <xsd:enumeration value=\"OnCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gradientCenter\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"gradientUnscaled\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"background\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:powerpoint\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:powerpoint\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"iscomment\" type=\"CT_Empty\"/>\n  <xsd:element name=\"textdata\" type=\"CT_Rel\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:excel\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"ClientData\" type=\"CT_ClientData\"/>\n  <xsd:complexType name=\"CT_ClientData\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"MoveWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SizeWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Anchor\" type=\"xsd:string\"/>\n      <xsd:element name=\"Locked\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DefaultSize\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"PrintObject\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Disabled\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoFill\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoPict\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaMacro\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextHAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextVAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"LockText\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"JustLastX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SecretEdit\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Default\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Help\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Cancel\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dismiss\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Accel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Accel2\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Row\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Column\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Visible\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RowHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ColHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VTEdit\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MultiLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VScroll\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ValidIds\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaRange\" type=\"xsd:string\"/>\n      <xsd:element name=\"WidthMin\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Sel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"NoThreeD2\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SelType\" type=\"xsd:string\"/>\n      <xsd:element name=\"MultiSel\" type=\"xsd:string\"/>\n      <xsd:element name=\"LCT\" type=\"xsd:string\"/>\n      <xsd:element name=\"ListItem\" type=\"xsd:string\"/>\n      <xsd:element name=\"DropStyle\" type=\"xsd:string\"/>\n      <xsd:element name=\"Colored\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DropLines\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Checked\" type=\"xsd:integer\"/>\n      <xsd:element name=\"FmlaLink\" type=\"xsd:string\"/>\n      <xsd:element name=\"FmlaPict\" type=\"xsd:string\"/>\n      <xsd:element name=\"NoThreeD\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FirstButton\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaGroup\" type=\"xsd:string\"/>\n      <xsd:element name=\"Val\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Min\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Max\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Inc\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Page\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Horiz\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dx\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MapOCX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"CF\" type=\"ST_CF\"/>\n      <xsd:element name=\"Camera\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RecalcAlways\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoScale\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DDE\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"UIObj\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ScriptText\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptExtended\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptLanguage\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"ScriptLocation\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"FmlaTxbx\" type=\"xsd:string\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"ObjectType\" type=\"ST_ObjectType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CF\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ObjectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Button\"/>\n      <xsd:enumeration value=\"Checkbox\"/>\n      <xsd:enumeration value=\"Dialog\"/>\n      <xsd:enumeration value=\"Drop\"/>\n      <xsd:enumeration value=\"Edit\"/>\n      <xsd:enumeration value=\"GBox\"/>\n      <xsd:enumeration value=\"Label\"/>\n      <xsd:enumeration value=\"LineA\"/>\n      <xsd:enumeration value=\"List\"/>\n      <xsd:enumeration value=\"Movie\"/>\n      <xsd:enumeration value=\"Note\"/>\n      <xsd:enumeration value=\"Pict\"/>\n      <xsd:enumeration value=\"Radio\"/>\n      <xsd:enumeration value=\"RectA\"/>\n      <xsd:enumeration value=\"Scroll\"/>\n      <xsd:enumeration value=\"Spin\"/>\n      <xsd:enumeration value=\"Shape\"/>\n      <xsd:enumeration value=\"Group\"/>\n      <xsd:enumeration value=\"Rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:word\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:word\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"bordertop\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderleft\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderright\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderbottom\" type=\"CT_Border\"/>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"type\" type=\"ST_BorderType\" use=\"optional\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:positiveInteger\" use=\"optional\"/>\n    <xsd:attribute name=\"shadow\" type=\"ST_BorderShadow\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"wrap\" type=\"CT_Wrap\"/>\n  <xsd:complexType name=\"CT_Wrap\">\n    <xsd:attribute name=\"type\" type=\"ST_WrapType\" use=\"optional\"/>\n    <xsd:attribute name=\"side\" type=\"ST_WrapSide\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorx\" type=\"ST_HorizontalAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"anchory\" type=\"ST_VerticalAnchor\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"anchorlock\" type=\"CT_AnchorLock\"/>\n  <xsd:complexType name=\"CT_AnchorLock\"/>\n  <xsd:simpleType name=\"ST_BorderType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hairline\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmall\"/>\n      <xsd:enumeration value=\"thickThinSmall\"/>\n      <xsd:enumeration value=\"thickBetweenThinSmall\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n      <xsd:enumeration value=\"thinThickLarge\"/>\n      <xsd:enumeration value=\"thickThinLarge\"/>\n      <xsd:enumeration value=\"thickBetweenThinLarge\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashedSmall\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"HTMLOutset\"/>\n      <xsd:enumeration value=\"HTMLInset\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderShadow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"topAndBottom\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapSide\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"char\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"line\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:sl=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" schemaLocation=\"../mce/mc.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n    schemaLocation=\"dml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n    schemaLocation=\"shared-math.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n    schemaLocation=\"shared-customXmlSchemaProperties.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LongHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LongHexNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_LongHexNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShortHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UcharHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Charset\">\n    <xsd:attribute name=\"val\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"s:ST_String\" use=\"optional\" default=\"ISO-8859-1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DecimalNumberOrPercent\">\n    <xsd:union memberTypes=\"ST_UnqualifiedPercentage s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnqualifiedPercentage\">\n    <xsd:restriction base=\"xsd:decimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DecimalNumber\">\n    <xsd:restriction base=\"xsd:integer\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedDecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DecimalNumberOrPrecent\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedTwipsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedTwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PixelsMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PixelsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HpsMeasure\">\n    <xsd:union memberTypes=\"s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_HpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedHpsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedHpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedHpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTime\">\n    <xsd:restriction base=\"xsd:dateTime\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_MacroName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"33\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MacroName\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MacroName\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EighthPointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextScale\">\n    <xsd:union memberTypes=\"ST_TextScalePercent ST_TextScaleDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(600|([0-5]?[0-9]?[0-9]))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScaleDecimal\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"600\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextScale\">\n    <xsd:attribute name=\"val\" type=\"ST_TextScale\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HighlightColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkYellow\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Highlight\">\n    <xsd:attribute name=\"val\" type=\"ST_HighlightColor\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HexColorAuto\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColor\">\n    <xsd:union memberTypes=\"ST_HexColorAuto s:ST_HexColorRGB\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"val\" type=\"ST_HexColor\" use=\"required\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lang\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guid\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Guid\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Underline\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashedHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dashDotDotHeavy\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDouble\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Underline\">\n    <xsd:attribute name=\"val\" type=\"ST_Underline\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextEffect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blinkBackground\"/>\n      <xsd:enumeration value=\"lights\"/>\n      <xsd:enumeration value=\"antsBlack\"/>\n      <xsd:enumeration value=\"antsRed\"/>\n      <xsd:enumeration value=\"shimmer\"/>\n      <xsd:enumeration value=\"sparkle\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextEffect\">\n    <xsd:attribute name=\"val\" type=\"ST_TextEffect\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Border\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmallGap\"/>\n      <xsd:enumeration value=\"thickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickMediumGap\"/>\n      <xsd:enumeration value=\"thickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickLargeGap\"/>\n      <xsd:enumeration value=\"thickThinLargeGap\"/>\n      <xsd:enumeration value=\"thinThickThinLargeGap\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashSmallGap\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"outset\"/>\n      <xsd:enumeration value=\"inset\"/>\n      <xsd:enumeration value=\"apples\"/>\n      <xsd:enumeration value=\"archedScallops\"/>\n      <xsd:enumeration value=\"babyPacifier\"/>\n      <xsd:enumeration value=\"babyRattle\"/>\n      <xsd:enumeration value=\"balloons3Colors\"/>\n      <xsd:enumeration value=\"balloonsHotAir\"/>\n      <xsd:enumeration value=\"basicBlackDashes\"/>\n      <xsd:enumeration value=\"basicBlackDots\"/>\n      <xsd:enumeration value=\"basicBlackSquares\"/>\n      <xsd:enumeration value=\"basicThinLines\"/>\n      <xsd:enumeration value=\"basicWhiteDashes\"/>\n      <xsd:enumeration value=\"basicWhiteDots\"/>\n      <xsd:enumeration value=\"basicWhiteSquares\"/>\n      <xsd:enumeration value=\"basicWideInline\"/>\n      <xsd:enumeration value=\"basicWideMidline\"/>\n      <xsd:enumeration value=\"basicWideOutline\"/>\n      <xsd:enumeration value=\"bats\"/>\n      <xsd:enumeration value=\"birds\"/>\n      <xsd:enumeration value=\"birdsFlight\"/>\n      <xsd:enumeration value=\"cabins\"/>\n      <xsd:enumeration value=\"cakeSlice\"/>\n      <xsd:enumeration value=\"candyCorn\"/>\n      <xsd:enumeration value=\"celticKnotwork\"/>\n      <xsd:enumeration value=\"certificateBanner\"/>\n      <xsd:enumeration value=\"chainLink\"/>\n      <xsd:enumeration value=\"champagneBottle\"/>\n      <xsd:enumeration value=\"checkedBarBlack\"/>\n      <xsd:enumeration value=\"checkedBarColor\"/>\n      <xsd:enumeration value=\"checkered\"/>\n      <xsd:enumeration value=\"christmasTree\"/>\n      <xsd:enumeration value=\"circlesLines\"/>\n      <xsd:enumeration value=\"circlesRectangles\"/>\n      <xsd:enumeration value=\"classicalWave\"/>\n      <xsd:enumeration value=\"clocks\"/>\n      <xsd:enumeration value=\"compass\"/>\n      <xsd:enumeration value=\"confetti\"/>\n      <xsd:enumeration value=\"confettiGrays\"/>\n      <xsd:enumeration value=\"confettiOutline\"/>\n      <xsd:enumeration value=\"confettiStreamers\"/>\n      <xsd:enumeration value=\"confettiWhite\"/>\n      <xsd:enumeration value=\"cornerTriangles\"/>\n      <xsd:enumeration value=\"couponCutoutDashes\"/>\n      <xsd:enumeration value=\"couponCutoutDots\"/>\n      <xsd:enumeration value=\"crazyMaze\"/>\n      <xsd:enumeration value=\"creaturesButterfly\"/>\n      <xsd:enumeration value=\"creaturesFish\"/>\n      <xsd:enumeration value=\"creaturesInsects\"/>\n      <xsd:enumeration value=\"creaturesLadyBug\"/>\n      <xsd:enumeration value=\"crossStitch\"/>\n      <xsd:enumeration value=\"cup\"/>\n      <xsd:enumeration value=\"decoArch\"/>\n      <xsd:enumeration value=\"decoArchColor\"/>\n      <xsd:enumeration value=\"decoBlocks\"/>\n      <xsd:enumeration value=\"diamondsGray\"/>\n      <xsd:enumeration value=\"doubleD\"/>\n      <xsd:enumeration value=\"doubleDiamonds\"/>\n      <xsd:enumeration value=\"earth1\"/>\n      <xsd:enumeration value=\"earth2\"/>\n      <xsd:enumeration value=\"earth3\"/>\n      <xsd:enumeration value=\"eclipsingSquares1\"/>\n      <xsd:enumeration value=\"eclipsingSquares2\"/>\n      <xsd:enumeration value=\"eggsBlack\"/>\n      <xsd:enumeration value=\"fans\"/>\n      <xsd:enumeration value=\"film\"/>\n      <xsd:enumeration value=\"firecrackers\"/>\n      <xsd:enumeration value=\"flowersBlockPrint\"/>\n      <xsd:enumeration value=\"flowersDaisies\"/>\n      <xsd:enumeration value=\"flowersModern1\"/>\n      <xsd:enumeration value=\"flowersModern2\"/>\n      <xsd:enumeration value=\"flowersPansy\"/>\n      <xsd:enumeration value=\"flowersRedRose\"/>\n      <xsd:enumeration value=\"flowersRoses\"/>\n      <xsd:enumeration value=\"flowersTeacup\"/>\n      <xsd:enumeration value=\"flowersTiny\"/>\n      <xsd:enumeration value=\"gems\"/>\n      <xsd:enumeration value=\"gingerbreadMan\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"handmade1\"/>\n      <xsd:enumeration value=\"handmade2\"/>\n      <xsd:enumeration value=\"heartBalloon\"/>\n      <xsd:enumeration value=\"heartGray\"/>\n      <xsd:enumeration value=\"hearts\"/>\n      <xsd:enumeration value=\"heebieJeebies\"/>\n      <xsd:enumeration value=\"holly\"/>\n      <xsd:enumeration value=\"houseFunky\"/>\n      <xsd:enumeration value=\"hypnotic\"/>\n      <xsd:enumeration value=\"iceCreamCones\"/>\n      <xsd:enumeration value=\"lightBulb\"/>\n      <xsd:enumeration value=\"lightning1\"/>\n      <xsd:enumeration value=\"lightning2\"/>\n      <xsd:enumeration value=\"mapPins\"/>\n      <xsd:enumeration value=\"mapleLeaf\"/>\n      <xsd:enumeration value=\"mapleMuffins\"/>\n      <xsd:enumeration value=\"marquee\"/>\n      <xsd:enumeration value=\"marqueeToothed\"/>\n      <xsd:enumeration value=\"moons\"/>\n      <xsd:enumeration value=\"mosaic\"/>\n      <xsd:enumeration value=\"musicNotes\"/>\n      <xsd:enumeration value=\"northwest\"/>\n      <xsd:enumeration value=\"ovals\"/>\n      <xsd:enumeration value=\"packages\"/>\n      <xsd:enumeration value=\"palmsBlack\"/>\n      <xsd:enumeration value=\"palmsColor\"/>\n      <xsd:enumeration value=\"paperClips\"/>\n      <xsd:enumeration value=\"papyrus\"/>\n      <xsd:enumeration value=\"partyFavor\"/>\n      <xsd:enumeration value=\"partyGlass\"/>\n      <xsd:enumeration value=\"pencils\"/>\n      <xsd:enumeration value=\"people\"/>\n      <xsd:enumeration value=\"peopleWaving\"/>\n      <xsd:enumeration value=\"peopleHats\"/>\n      <xsd:enumeration value=\"poinsettias\"/>\n      <xsd:enumeration value=\"postageStamp\"/>\n      <xsd:enumeration value=\"pumpkin1\"/>\n      <xsd:enumeration value=\"pushPinNote2\"/>\n      <xsd:enumeration value=\"pushPinNote1\"/>\n      <xsd:enumeration value=\"pyramids\"/>\n      <xsd:enumeration value=\"pyramidsAbove\"/>\n      <xsd:enumeration value=\"quadrants\"/>\n      <xsd:enumeration value=\"rings\"/>\n      <xsd:enumeration value=\"safari\"/>\n      <xsd:enumeration value=\"sawtooth\"/>\n      <xsd:enumeration value=\"sawtoothGray\"/>\n      <xsd:enumeration value=\"scaredCat\"/>\n      <xsd:enumeration value=\"seattle\"/>\n      <xsd:enumeration value=\"shadowedSquares\"/>\n      <xsd:enumeration value=\"sharksTeeth\"/>\n      <xsd:enumeration value=\"shorebirdTracks\"/>\n      <xsd:enumeration value=\"skyrocket\"/>\n      <xsd:enumeration value=\"snowflakeFancy\"/>\n      <xsd:enumeration value=\"snowflakes\"/>\n      <xsd:enumeration value=\"sombrero\"/>\n      <xsd:enumeration value=\"southwest\"/>\n      <xsd:enumeration value=\"stars\"/>\n      <xsd:enumeration value=\"starsTop\"/>\n      <xsd:enumeration value=\"stars3d\"/>\n      <xsd:enumeration value=\"starsBlack\"/>\n      <xsd:enumeration value=\"starsShadowed\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"swirligig\"/>\n      <xsd:enumeration value=\"tornPaper\"/>\n      <xsd:enumeration value=\"tornPaperBlack\"/>\n      <xsd:enumeration value=\"trees\"/>\n      <xsd:enumeration value=\"triangleParty\"/>\n      <xsd:enumeration value=\"triangles\"/>\n      <xsd:enumeration value=\"triangle1\"/>\n      <xsd:enumeration value=\"triangle2\"/>\n      <xsd:enumeration value=\"triangleCircle1\"/>\n      <xsd:enumeration value=\"triangleCircle2\"/>\n      <xsd:enumeration value=\"shapes1\"/>\n      <xsd:enumeration value=\"shapes2\"/>\n      <xsd:enumeration value=\"twistedLines1\"/>\n      <xsd:enumeration value=\"twistedLines2\"/>\n      <xsd:enumeration value=\"vine\"/>\n      <xsd:enumeration value=\"waveline\"/>\n      <xsd:enumeration value=\"weavingAngles\"/>\n      <xsd:enumeration value=\"weavingBraid\"/>\n      <xsd:enumeration value=\"weavingRibbon\"/>\n      <xsd:enumeration value=\"weavingStrips\"/>\n      <xsd:enumeration value=\"whiteFlowers\"/>\n      <xsd:enumeration value=\"woodwork\"/>\n      <xsd:enumeration value=\"xIllusions\"/>\n      <xsd:enumeration value=\"zanyTriangles\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n      <xsd:enumeration value=\"zigZagStitch\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"val\" type=\"ST_Border\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_EighthPointMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"ST_PointMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"shadow\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"frame\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shd\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"horzStripe\"/>\n      <xsd:enumeration value=\"vertStripe\"/>\n      <xsd:enumeration value=\"reverseDiagStripe\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"horzCross\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"thinHorzStripe\"/>\n      <xsd:enumeration value=\"thinVertStripe\"/>\n      <xsd:enumeration value=\"thinReverseDiagStripe\"/>\n      <xsd:enumeration value=\"thinDiagStripe\"/>\n      <xsd:enumeration value=\"thinHorzCross\"/>\n      <xsd:enumeration value=\"thinDiagCross\"/>\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct12\"/>\n      <xsd:enumeration value=\"pct15\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct35\"/>\n      <xsd:enumeration value=\"pct37\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct45\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct55\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct62\"/>\n      <xsd:enumeration value=\"pct65\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct85\"/>\n      <xsd:enumeration value=\"pct87\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"pct95\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shd\">\n    <xsd:attribute name=\"val\" type=\"ST_Shd\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFill\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignRun\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FitText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Em\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"comma\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"underDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Em\">\n    <xsd:attribute name=\"val\" type=\"ST_Em\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Language\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"bidi\" type=\"s:ST_Lang\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CombineBrackets\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"curly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EastAsianLayout\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"combine\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"combineBrackets\" type=\"ST_CombineBrackets\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"vertCompress\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HeightRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Wrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"notBeside\"/>\n      <xsd:enumeration value=\"around\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DropCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"drop\"/>\n      <xsd:enumeration value=\"margin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FramePr\">\n    <xsd:attribute name=\"dropCap\" type=\"ST_DropCap\" use=\"optional\"/>\n    <xsd:attribute name=\"lines\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"vSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_Wrap\" use=\"optional\"/>\n    <xsd:attribute name=\"hAnchor\" type=\"ST_HAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"vAnchor\" type=\"ST_VAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"x\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"xAlign\" type=\"s:ST_XAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"y\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"yAlign\" type=\"s:ST_YAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorLock\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TabJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TabTlc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TabStop\">\n    <xsd:attribute name=\"val\" type=\"ST_TabJc\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_TabTlc\" use=\"optional\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LineSpacingRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Spacing\">\n    <xsd:attribute name=\"before\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"after\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"line\" type=\"ST_SignedTwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"lineRule\" type=\"ST_LineSpacingRule\" use=\"optional\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ind\">\n    <xsd:attribute name=\"start\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"startChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"end\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"endChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"left\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"leftChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"right\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"rightChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"hanging\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLine\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLineChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"mediumKashida\"/>\n      <xsd:enumeration value=\"distribute\"/>\n      <xsd:enumeration value=\"numTab\"/>\n      <xsd:enumeration value=\"highKashida\"/>\n      <xsd:enumeration value=\"lowKashida\"/>\n      <xsd:enumeration value=\"thaiDistribute\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_JcTable\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"start\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Jc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_JcTable\">\n    <xsd:attribute name=\"val\" type=\"ST_JcTable\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_View\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"outline\"/>\n      <xsd:enumeration value=\"masterPages\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"web\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_View\">\n    <xsd:attribute name=\"val\" type=\"ST_View\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Zoom\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fullPage\"/>\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"textFit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Zoom\">\n    <xsd:attribute name=\"val\" type=\"ST_Zoom\" use=\"optional\"/>\n    <xsd:attribute name=\"percent\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WritingStyle\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"vendorID\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"dllVersion\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"nlCheck\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"checkStyle\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"appName\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Proof\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clean\"/>\n      <xsd:enumeration value=\"dirty\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Proof\">\n    <xsd:attribute name=\"spelling\" type=\"ST_Proof\" use=\"optional\"/>\n    <xsd:attribute name=\"grammar\" type=\"ST_Proof\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocType\">\n    <xsd:attribute name=\"val\" type=\"ST_DocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocProtect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"readOnly\"/>\n      <xsd:enumeration value=\"comments\"/>\n      <xsd:enumeration value=\"trackedChanges\"/>\n      <xsd:enumeration value=\"forms\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Password\">\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_TransitionalPassword\">\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptSpinCount\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hash\" type=\"xsd:base64Binary\"/>\n    <xsd:attribute name=\"salt\" type=\"xsd:base64Binary\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_DocProtect\">\n    <xsd:attribute name=\"edit\" type=\"ST_DocProtect\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"enforcement\" type=\"s:ST_OnOff\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDocType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"catalog\"/>\n      <xsd:enumeration value=\"envelopes\"/>\n      <xsd:enumeration value=\"mailingLabels\"/>\n      <xsd:enumeration value=\"formLetters\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDocType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDataType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDest\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newDocument\"/>\n      <xsd:enumeration value=\"printer\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDest\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDest\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeOdsoFMDFieldType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"dbColumn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeOdsoFMDFieldType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeOdsoFMDFieldType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangesView\">\n    <xsd:attribute name=\"markup\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"comments\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"insDel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"inkAnnotations\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextDirection\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tb\"/>\n      <xsd:enumeration value=\"rl\"/>\n      <xsd:enumeration value=\"lr\"/>\n      <xsd:enumeration value=\"tbV\"/>\n      <xsd:enumeration value=\"rlV\"/>\n      <xsd:enumeration value=\"lrV\"/>\n      <xsd:enumeration value=\"btLr\"/>\n      <xsd:enumeration value=\"lrTb\"/>\n      <xsd:enumeration value=\"lrTbV\"/>\n      <xsd:enumeration value=\"tbLrV\"/>\n      <xsd:enumeration value=\"tbRl\"/>\n      <xsd:enumeration value=\"tbRlV\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextDirection\">\n    <xsd:attribute name=\"val\" type=\"ST_TextDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextAlignment\">\n    <xsd:attribute name=\"val\" type=\"ST_TextAlignment\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DisplacedByCustomXml\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"next\"/>\n      <xsd:enumeration value=\"prev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnnotationVMerge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cont\"/>\n      <xsd:enumeration value=\"rest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Markup\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellMergeTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"vMerge\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n        <xsd:attribute name=\"vMergeOrig\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MarkupRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookmarkRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_MarkupRange\">\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_BookmarkRange\">\n        <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MoveBookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Bookmark\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"initials\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeNumbering\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"original\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrEx\" type=\"CT_TblPrExBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPr\" type=\"CT_TcPrInner\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"trPr\" type=\"CT_TrPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGrid\" type=\"CT_TblGridBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPrBase\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"pPr\" type=\"CT_PPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_RPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RunTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:group ref=\"EG_ContentRunContent\"/>\n          <xsd:group ref=\"m:EG_OMathMathElements\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContentMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_PContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_ContentRunContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_PContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ContentRunContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_CellMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"cellIns\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellDel\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellMerge\" type=\"CT_CellMergeTrackChange\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RangeMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"bookmarkStart\" type=\"CT_Bookmark\"/>\n      <xsd:element name=\"bookmarkEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveFromRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveFromRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveToRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveToRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeStart\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"customXmlInsRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlInsRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlDelRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlDelRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveFromRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveFromRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveToRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveToRangeEnd\" type=\"CT_Markup\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_NumPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ilvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"between\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bar\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tabs\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TabStop\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextboxTightWrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"allLines\"/>\n      <xsd:enumeration value=\"firstAndLastLine\"/>\n      <xsd:enumeration value=\"firstLineOnly\"/>\n      <xsd:enumeration value=\"lastLineOnly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextboxTightWrap\">\n    <xsd:attribute name=\"val\" type=\"ST_TextboxTightWrap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepNext\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageBreakBefore\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"framePr\" type=\"CT_FramePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"widowControl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"numPr\" type=\"CT_NumPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressLineNumbers\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pBdr\" type=\"CT_PBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabs\" type=\"CT_Tabs\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressAutoHyphens\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wordWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"overflowPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"topLinePunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDE\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDN\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustRightInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacing\" type=\"CT_Spacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"ind\" type=\"CT_Ind\" minOccurs=\"0\"/>\n      <xsd:element name=\"contextualSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorIndents\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressOverlap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"jc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"textAlignment\" type=\"CT_TextAlignment\" minOccurs=\"0\"/>\n      <xsd:element name=\"textboxTightWrap\" type=\"CT_TextboxTightWrap\" minOccurs=\"0\"/>\n      <xsd:element name=\"outlineLvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrGeneral\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeid\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Object\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"control\" type=\"CT_Control\"/>\n        <xsd:element name=\"objectLink\" type=\"CT_ObjectLink\"/>\n        <xsd:element name=\"objectEmbed\" type=\"CT_ObjectEmbed\"/>\n        <xsd:element name=\"movie\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"dxaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"dyaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"movie\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectEmbed\">\n    <xsd:attribute name=\"drawAspect\" type=\"ST_ObjectDrawAspect\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldCodes\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ObjectLink\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_ObjectEmbed\">\n        <xsd:attribute name=\"updateMode\" type=\"ST_ObjectUpdateMode\" use=\"required\"/>\n        <xsd:attribute name=\"lockedField\" type=\"s:ST_OnOff\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"onCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"wp:anchor\" minOccurs=\"0\"/>\n      <xsd:element ref=\"wp:inline\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SimpleField\">\n    <xsd:sequence>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"instr\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FldCharType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"separate\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InfoTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"autoText\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFHelpTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"256\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFStatusTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"140\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"65\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"regular\"/>\n      <xsd:enumeration value=\"number\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"currentTime\"/>\n      <xsd:enumeration value=\"currentDate\"/>\n      <xsd:enumeration value=\"calculated\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FFTextType\">\n    <xsd:attribute name=\"val\" type=\"ST_FFTextType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFName\">\n    <xsd:attribute name=\"val\" type=\"ST_FFName\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FldChar\">\n    <xsd:choice>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ffData\" type=\"CT_FFData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fldCharType\" type=\"ST_FldCharType\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"docLocation\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"history\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFData\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FFName\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"enabled\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"calcOnExit\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"entryMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"exitMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"helpText\" type=\"CT_FFHelpText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"statusText\" type=\"CT_FFStatusText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"checkBox\" type=\"CT_FFCheckBox\"/>\n        <xsd:element name=\"ddList\" type=\"CT_FFDDList\"/>\n        <xsd:element name=\"textInput\" type=\"CT_FFTextInput\"/>\n      </xsd:choice>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFHelpText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFHelpTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFStatusText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFStatusTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFCheckBox\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"size\" type=\"CT_HpsMeasure\"/>\n        <xsd:element name=\"sizeAuto\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"default\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFDDList\">\n    <xsd:sequence>\n      <xsd:element name=\"result\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"listEntry\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFTextInput\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FFTextType\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxLength\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"format\" type=\"CT_String\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SectionMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nextPage\"/>\n      <xsd:enumeration value=\"nextColumn\"/>\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"evenPage\"/>\n      <xsd:enumeration value=\"oddPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SectType\">\n    <xsd:attribute name=\"val\" type=\"ST_SectionMark\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PaperSource\">\n    <xsd:attribute name=\"first\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"other\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumberFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"upperRoman\"/>\n      <xsd:enumeration value=\"lowerRoman\"/>\n      <xsd:enumeration value=\"upperLetter\"/>\n      <xsd:enumeration value=\"lowerLetter\"/>\n      <xsd:enumeration value=\"ordinal\"/>\n      <xsd:enumeration value=\"cardinalText\"/>\n      <xsd:enumeration value=\"ordinalText\"/>\n      <xsd:enumeration value=\"hex\"/>\n      <xsd:enumeration value=\"chicago\"/>\n      <xsd:enumeration value=\"ideographDigital\"/>\n      <xsd:enumeration value=\"japaneseCounting\"/>\n      <xsd:enumeration value=\"aiueo\"/>\n      <xsd:enumeration value=\"iroha\"/>\n      <xsd:enumeration value=\"decimalFullWidth\"/>\n      <xsd:enumeration value=\"decimalHalfWidth\"/>\n      <xsd:enumeration value=\"japaneseLegal\"/>\n      <xsd:enumeration value=\"japaneseDigitalTenThousand\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircle\"/>\n      <xsd:enumeration value=\"decimalFullWidth2\"/>\n      <xsd:enumeration value=\"aiueoFullWidth\"/>\n      <xsd:enumeration value=\"irohaFullWidth\"/>\n      <xsd:enumeration value=\"decimalZero\"/>\n      <xsd:enumeration value=\"bullet\"/>\n      <xsd:enumeration value=\"ganada\"/>\n      <xsd:enumeration value=\"chosung\"/>\n      <xsd:enumeration value=\"decimalEnclosedFullstop\"/>\n      <xsd:enumeration value=\"decimalEnclosedParen\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircleChinese\"/>\n      <xsd:enumeration value=\"ideographEnclosedCircle\"/>\n      <xsd:enumeration value=\"ideographTraditional\"/>\n      <xsd:enumeration value=\"ideographZodiac\"/>\n      <xsd:enumeration value=\"ideographZodiacTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCounting\"/>\n      <xsd:enumeration value=\"ideographLegalTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCountingThousand\"/>\n      <xsd:enumeration value=\"taiwaneseDigital\"/>\n      <xsd:enumeration value=\"chineseCounting\"/>\n      <xsd:enumeration value=\"chineseLegalSimplified\"/>\n      <xsd:enumeration value=\"chineseCountingThousand\"/>\n      <xsd:enumeration value=\"koreanDigital\"/>\n      <xsd:enumeration value=\"koreanCounting\"/>\n      <xsd:enumeration value=\"koreanLegal\"/>\n      <xsd:enumeration value=\"koreanDigital2\"/>\n      <xsd:enumeration value=\"vietnameseCounting\"/>\n      <xsd:enumeration value=\"russianLower\"/>\n      <xsd:enumeration value=\"russianUpper\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"numberInDash\"/>\n      <xsd:enumeration value=\"hebrew1\"/>\n      <xsd:enumeration value=\"hebrew2\"/>\n      <xsd:enumeration value=\"arabicAlpha\"/>\n      <xsd:enumeration value=\"arabicAbjad\"/>\n      <xsd:enumeration value=\"hindiVowels\"/>\n      <xsd:enumeration value=\"hindiConsonants\"/>\n      <xsd:enumeration value=\"hindiNumbers\"/>\n      <xsd:enumeration value=\"hindiCounting\"/>\n      <xsd:enumeration value=\"thaiLetters\"/>\n      <xsd:enumeration value=\"thaiNumbers\"/>\n      <xsd:enumeration value=\"thaiCounting\"/>\n      <xsd:enumeration value=\"bahtText\"/>\n      <xsd:enumeration value=\"dollarText\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageSz\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_PageOrientation\" use=\"optional\"/>\n    <xsd:attribute name=\"code\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMar\">\n    <xsd:attribute name=\"top\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"left\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"gutter\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageBorderZOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"front\"/>\n      <xsd:enumeration value=\"back\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderDisplay\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"allPages\"/>\n      <xsd:enumeration value=\"firstPage\"/>\n      <xsd:enumeration value=\"notFirstPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderOffset\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TopPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BottomPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zOrder\" type=\"ST_PageBorderZOrder\" use=\"optional\" default=\"front\"/>\n    <xsd:attribute name=\"display\" type=\"ST_PageBorderDisplay\" use=\"optional\"/>\n    <xsd:attribute name=\"offsetFrom\" type=\"ST_PageBorderOffset\" use=\"optional\" default=\"text\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Border\">\n        <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BottomPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:bottomLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:bottomRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TopPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:topLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:topRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ChapterSep\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"period\"/>\n      <xsd:enumeration value=\"colon\"/>\n      <xsd:enumeration value=\"emDash\"/>\n      <xsd:enumeration value=\"enDash\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineNumberRestart\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newPage\"/>\n      <xsd:enumeration value=\"newSection\"/>\n      <xsd:enumeration value=\"continuous\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineNumber\">\n    <xsd:attribute name=\"countBy\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"distance\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_LineNumberRestart\" use=\"optional\" default=\"newPage\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageNumber\">\n    <xsd:attribute name=\"fmt\" type=\"ST_NumberFormat\" use=\"optional\" default=\"decimal\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapStyle\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapSep\" type=\"ST_ChapterSep\" use=\"optional\" default=\"hyphen\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Column\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Columns\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"col\" type=\"CT_Column\" maxOccurs=\"45\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"equalWidth\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"720\"/>\n    <xsd:attribute name=\"num\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"sep\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VerticalJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"bottom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VerticalJc\">\n    <xsd:attribute name=\"val\" type=\"ST_VerticalJc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocGrid\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"lines\"/>\n      <xsd:enumeration value=\"linesAndChars\"/>\n      <xsd:enumeration value=\"snapToChars\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocGrid\">\n    <xsd:attribute name=\"type\" type=\"ST_DocGrid\"/>\n    <xsd:attribute name=\"linePitch\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"charSpace\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HdrFtr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"even\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"first\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FtnEdn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"separator\"/>\n      <xsd:enumeration value=\"continuationSeparator\"/>\n      <xsd:enumeration value=\"continuationNotice\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HdrFtrRef\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"type\" type=\"ST_HdrFtr\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_HdrFtrReferences\">\n    <xsd:choice>\n      <xsd:element name=\"headerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n      <xsd:element name=\"footerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_HdrFtr\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SectPrContents\">\n    <xsd:sequence>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_SectType\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgSz\" type=\"CT_PageSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgMar\" type=\"CT_PageMar\" minOccurs=\"0\"/>\n      <xsd:element name=\"paperSrc\" type=\"CT_PaperSource\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgBorders\" type=\"CT_PageBorders\" minOccurs=\"0\"/>\n      <xsd:element name=\"lnNumType\" type=\"CT_LineNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNumType\" type=\"CT_PageNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cols\" type=\"CT_Columns\" minOccurs=\"0\"/>\n      <xsd:element name=\"formProt\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"noEndnote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"titlePg\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rtlGutter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"docGrid\" type=\"CT_DocGrid\" minOccurs=\"0\"/>\n      <xsd:element name=\"printerSettings\" type=\"CT_Rel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_SectPrAttributes\">\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidSect\" type=\"ST_LongHexNumber\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_SectPrBase\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_HdrFtrReferences\" minOccurs=\"0\" maxOccurs=\"6\"/>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n      <xsd:element name=\"sectPrChange\" type=\"CT_SectPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BrType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"textWrapping\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BrClear\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Br\">\n    <xsd:attribute name=\"type\" type=\"ST_BrType\" use=\"optional\"/>\n    <xsd:attribute name=\"clear\" type=\"ST_BrClear\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PTabAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabRelativeTo\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"indent\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabLeader\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PTab\">\n    <xsd:attribute name=\"alignment\" type=\"ST_PTabAlignment\" use=\"required\"/>\n    <xsd:attribute name=\"relativeTo\" type=\"ST_PTabRelativeTo\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_PTabLeader\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sym\">\n    <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"char\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ProofErr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"spellStart\"/>\n      <xsd:enumeration value=\"spellEnd\"/>\n      <xsd:enumeration value=\"gramStart\"/>\n      <xsd:enumeration value=\"gramEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ProofErr\">\n    <xsd:attribute name=\"type\" type=\"ST_ProofErr\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdGrp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"everyone\"/>\n      <xsd:enumeration value=\"administrators\"/>\n      <xsd:enumeration value=\"contributors\"/>\n      <xsd:enumeration value=\"editors\"/>\n      <xsd:enumeration value=\"owners\"/>\n      <xsd:enumeration value=\"current\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perm\">\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PermStart\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Perm\">\n        <xsd:attribute name=\"edGrp\" type=\"ST_EdGrp\" use=\"optional\"/>\n        <xsd:attribute name=\"ed\" type=\"s:ST_String\" use=\"optional\"/>\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RunInnerContent\">\n    <xsd:choice>\n      <xsd:element name=\"br\" type=\"CT_Br\"/>\n      <xsd:element name=\"t\" type=\"CT_Text\"/>\n      <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      <xsd:element name=\"delText\" type=\"CT_Text\"/>\n      <xsd:element name=\"instrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"delInstrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"noBreakHyphen\" type=\"CT_Empty\"/>\n      <xsd:element name=\"softHyphen\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"annotationRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"separator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"continuationSeparator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"sym\" type=\"CT_Sym\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNum\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"cr\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"tab\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"object\" type=\"CT_Object\"/>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"fldChar\" type=\"CT_FldChar\"/>\n      <xsd:element name=\"ruby\" type=\"CT_Ruby\"/>\n      <xsd:element name=\"footnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"endnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"commentReference\" type=\"CT_Markup\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"ptab\" type=\"CT_PTab\" minOccurs=\"0\"/>\n      <xsd:element name=\"lastRenderedPageBreak\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RunInnerContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Hint\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"eastAsia\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Theme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"majorEastAsia\"/>\n      <xsd:enumeration value=\"majorBidi\"/>\n      <xsd:enumeration value=\"majorAscii\"/>\n      <xsd:enumeration value=\"majorHAnsi\"/>\n      <xsd:enumeration value=\"minorEastAsia\"/>\n      <xsd:enumeration value=\"minorBidi\"/>\n      <xsd:enumeration value=\"minorAscii\"/>\n      <xsd:enumeration value=\"minorHAnsi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:attribute name=\"hint\" type=\"ST_Hint\"/>\n    <xsd:attribute name=\"ascii\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hAnsi\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cs\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"asciiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"hAnsiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"eastAsiaTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"cstheme\" type=\"ST_Theme\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPrBase\">\n    <xsd:choice>\n      <xsd:element name=\"rStyle\" type=\"CT_String\"/>\n      <xsd:element name=\"rFonts\" type=\"CT_Fonts\"/>\n      <xsd:element name=\"b\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"bCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"i\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"iCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"caps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"smallCaps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"strike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"dstrike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"outline\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"shadow\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"emboss\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"imprint\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"noProof\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"vanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"webHidden\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\"/>\n      <xsd:element name=\"spacing\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"w\" type=\"CT_TextScale\"/>\n      <xsd:element name=\"kern\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"position\" type=\"CT_SignedHpsMeasure\"/>\n      <xsd:element name=\"sz\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"szCs\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Highlight\"/>\n      <xsd:element name=\"u\" type=\"CT_Underline\"/>\n      <xsd:element name=\"effect\" type=\"CT_TextEffect\"/>\n      <xsd:element name=\"bdr\" type=\"CT_Border\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\"/>\n      <xsd:element name=\"fitText\" type=\"CT_FitText\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignRun\"/>\n      <xsd:element name=\"rtl\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"cs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"em\" type=\"CT_Em\"/>\n      <xsd:element name=\"lang\" type=\"CT_Language\"/>\n      <xsd:element name=\"eastAsianLayout\" type=\"CT_EastAsianLayout\"/>\n      <xsd:element name=\"specVanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OnOff\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrContent\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_RPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrContent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_RPr\"/>\n      <xsd:element name=\"ins\" type=\"CT_MathCtrlIns\"/>\n      <xsd:element name=\"del\" type=\"CT_MathCtrlDel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_MathCtrlIns\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"del\" type=\"CT_RPrChange\" minOccurs=\"1\"/>\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathCtrlDel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_ParaRPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ParaRPrTrackChanges\">\n    <xsd:sequence>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AltChunk\">\n    <xsd:sequence>\n      <xsd:element name=\"altChunkPr\" type=\"CT_AltChunkPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AltChunkPr\">\n    <xsd:sequence>\n      <xsd:element name=\"matchSrc\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RubyAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributeLetter\"/>\n      <xsd:enumeration value=\"distributeSpace\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"rightVertical\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RubyAlign\">\n    <xsd:attribute name=\"val\" type=\"ST_RubyAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RubyPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyAlign\" type=\"CT_RubyAlign\"/>\n      <xsd:element name=\"hps\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsRaise\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsBaseText\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\"/>\n      <xsd:element name=\"dirty\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RubyContent\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RubyContent\">\n    <xsd:group ref=\"EG_RubyContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ruby\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyPr\" type=\"CT_RubyPr\"/>\n      <xsd:element name=\"rt\" type=\"CT_RubyContent\"/>\n      <xsd:element name=\"rubyBase\" type=\"CT_RubyContent\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Lock\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sdtLocked\"/>\n      <xsd:enumeration value=\"contentLocked\"/>\n      <xsd:enumeration value=\"unlocked\"/>\n      <xsd:enumeration value=\"sdtContentLocked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attribute name=\"val\" type=\"ST_Lock\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtListItem\">\n    <xsd:attribute name=\"displayText\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"value\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SdtDateMappingType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"dateTime\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtDateMappingType\">\n    <xsd:attribute name=\"val\" type=\"ST_SdtDateMappingType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalendarType\">\n    <xsd:attribute name=\"val\" type=\"s:ST_CalendarType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDate\">\n    <xsd:sequence>\n      <xsd:element name=\"dateFormat\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"storeMappedDataAs\" type=\"CT_SdtDateMappingType\" minOccurs=\"0\"/>\n      <xsd:element name=\"calendar\" type=\"CT_CalendarType\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullDate\" type=\"ST_DateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtComboBox\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartGallery\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartCategory\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartUnique\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDropDownList\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"docPart\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtText\">\n    <xsd:attribute name=\"multiLine\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:attribute name=\"prefixMappings\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"storeItemID\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"alias\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tag\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"id\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lock\" type=\"CT_Lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"placeholder\" type=\"CT_Placeholder\" minOccurs=\"0\"/>\n      <xsd:element name=\"temporary\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showingPlcHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"equation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comboBox\" type=\"CT_SdtComboBox\"/>\n        <xsd:element name=\"date\" type=\"CT_SdtDate\"/>\n        <xsd:element name=\"docPartObj\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"docPartList\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"dropDownList\" type=\"CT_SdtDropDownList\"/>\n        <xsd:element name=\"picture\" type=\"CT_Empty\"/>\n        <xsd:element name=\"richText\" type=\"CT_Empty\"/>\n        <xsd:element name=\"text\" type=\"CT_SdtText\"/>\n        <xsd:element name=\"citation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"group\" type=\"CT_Empty\"/>\n        <xsd:element name=\"bibliography\" type=\"CT_Empty\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtEndPr\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRunContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:element name=\"dir\" type=\"CT_DirContentRun\"/>\n      <xsd:element name=\"bdo\" type=\"CT_BdoContentRun\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DirContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BdoContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ltr\"/>\n      <xsd:enumeration value=\"rtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentBlockContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlBlock\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtBlock\"/>\n      <xsd:element name=\"p\" type=\"CT_P\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tbl\" type=\"CT_Tbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentBlock\">\n    <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRowContent\">\n    <xsd:choice>\n      <xsd:element name=\"tr\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRow\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRow\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentRow\">\n    <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentCellContent\">\n    <xsd:choice>\n      <xsd:element name=\"tc\" type=\"CT_Tc\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlCell\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtCell\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentCell\">\n    <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentBlock\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRun\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRun\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtCell\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentCell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRow\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRow\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Attr\">\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRun\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagRun\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"placeholder\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRow\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:sequence>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContent\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentRunContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n      <xsd:element name=\"subDoc\" type=\"CT_Rel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_P\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidP\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidRDefault\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"pct\"/>\n      <xsd:enumeration value=\"dxa\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Height\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MeasurementOrPercent\">\n    <xsd:union memberTypes=\"ST_DecimalNumberOrPercent s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblWidth\">\n    <xsd:attribute name=\"w\" type=\"ST_MeasurementOrPercent\"/>\n    <xsd:attribute name=\"type\" type=\"ST_TblWidth\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridCol\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridBase\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TblGridCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGrid\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblGridBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGridChange\" type=\"CT_TblGridChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Merge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continue\"/>\n      <xsd:enumeration value=\"restart\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpan\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hMerge\" type=\"CT_HMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"vMerge\" type=\"CT_VMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcBorders\" type=\"CT_TcBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"noWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcMar\" type=\"CT_TcMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcFitText\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrInner\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPrChange\" type=\"CT_TcPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrInner\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrBase\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_CellMarkupElements\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tc\">\n    <xsd:sequence>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Cnf\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:length value=\"12\"/>\n      <xsd:pattern value=\"[01]*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cnf\">\n    <xsd:attribute name=\"val\" type=\"ST_Cnf\"/>\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowLastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowLastColumn\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrBase\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridBefore\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridAfter\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"wBefore\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wAfter\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cantSplit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"trHeight\" type=\"CT_Height\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"trPrChange\" type=\"CT_TrPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPrEx\" type=\"CT_TblPrEx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidTr\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblLayoutType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"autofit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblLayoutType\">\n    <xsd:attribute name=\"type\" type=\"ST_TblLayoutType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblOverlap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"overlap\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblOverlap\">\n    <xsd:attribute name=\"val\" type=\"ST_TblOverlap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPPr\">\n    <xsd:attribute name=\"leftFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"rightFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"topFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"bottomFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"vertAnchor\" type=\"ST_VAnchor\"/>\n    <xsd:attribute name=\"horzAnchor\" type=\"ST_HAnchor\"/>\n    <xsd:attribute name=\"tblpXSpec\" type=\"s:ST_XAlign\"/>\n    <xsd:attribute name=\"tblpX\" type=\"ST_SignedTwipsMeasure\"/>\n    <xsd:attribute name=\"tblpYSpec\" type=\"s:ST_YAlign\"/>\n    <xsd:attribute name=\"tblpY\" type=\"ST_SignedTwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblCellMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblpPr\" type=\"CT_TblPPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblOverlap\" type=\"CT_TblOverlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bidiVisual\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleRowBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleColBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCaption\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblDescription\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrChange\" type=\"CT_TblPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrEx\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrExBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrExChange\" type=\"CT_TblPrExChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tbl\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPr\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TblGrid\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblLook\">\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FtnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pageBottom\"/>\n      <xsd:enumeration value=\"beneathText\"/>\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FtnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_FtnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EdnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_EdnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"val\" type=\"ST_NumberFormat\" use=\"required\"/>\n    <xsd:attribute name=\"format\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RestartNumber\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"eachSect\"/>\n      <xsd:enumeration value=\"eachPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumRestart\">\n    <xsd:attribute name=\"val\" type=\"ST_RestartNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnRef\">\n    <xsd:attribute name=\"customMarkFollows\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnSepRef\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdn\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_FtnEdn\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FtnEdnNumProps\">\n    <xsd:sequence>\n      <xsd:element name=\"numStart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numRestart\" type=\"CT_NumRestart\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FtnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_FtnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_EdnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_FtnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"footnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_EdnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"endnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RecipientData\">\n    <xsd:sequence>\n      <xsd:element name=\"active\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"uniqueTag\" type=\"CT_Base64Binary\" minOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Base64Binary\">\n    <xsd:attribute name=\"val\" type=\"xsd:base64Binary\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Recipients\">\n    <xsd:sequence>\n      <xsd:element name=\"recipientData\" type=\"CT_RecipientData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"recipients\" type=\"CT_Recipients\"/>\n  <xsd:complexType name=\"CT_OdsoFieldMapData\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_MailMergeOdsoFMDFieldType\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mappedName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"dynamicAddress\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"database\"/>\n      <xsd:enumeration value=\"addressBook\"/>\n      <xsd:enumeration value=\"document1\"/>\n      <xsd:enumeration value=\"document2\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"native\"/>\n      <xsd:enumeration value=\"legacy\"/>\n      <xsd:enumeration value=\"master\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeSourceType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MailMergeSourceType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Odso\">\n    <xsd:sequence>\n      <xsd:element name=\"udl\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"table\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"src\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"colDelim\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_MailMergeSourceType\" minOccurs=\"0\"/>\n      <xsd:element name=\"fHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"fieldMapData\" type=\"CT_OdsoFieldMapData\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"recipientData\" type=\"CT_Rel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MailMerge\">\n    <xsd:sequence>\n      <xsd:element name=\"mainDocumentType\" type=\"CT_MailMergeDocType\" minOccurs=\"1\"/>\n      <xsd:element name=\"linkToQuery\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataType\" type=\"CT_MailMergeDataType\" minOccurs=\"1\"/>\n      <xsd:element name=\"connectString\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"query\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"headerSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressBlankLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"destination\" type=\"CT_MailMergeDest\" minOccurs=\"0\"/>\n      <xsd:element name=\"addressFieldName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailSubject\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailAsAttachment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"viewMergedData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeRecord\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"checkErrors\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"odso\" type=\"CT_Odso\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSz\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TargetScreenSz\">\n    <xsd:attribute name=\"val\" type=\"ST_TargetScreenSz\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Compat\">\n    <xsd:sequence>\n      <xsd:element name=\"useSingleBorderforContiguousCells\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpJustification\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noTabHangInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLeading\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spaceForUL\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noColumnBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"balanceSingleByteDoubleByteWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noExtraLineSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotLeaveBackslashAlone\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ulTrailSpace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotExpandShiftReturn\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacingInWholePoints\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lineWrapLikeWord6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printBodyTextBeforeHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printColBlack\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpSpaceWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showBreaksInFrames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subFontBySize\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressBottomSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpacingAtTopOfPage\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacingWP\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpBfAfterPgBrk\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"swapBordersFacingPages\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"convMailMergeEsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"truncateFontHeightsLikeWP6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mwSmallCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"usePrinterMetrics\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressParagraphBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wrapTrailSpaces\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shapeLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignTablesRowByRow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forgetLastTabAlignment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustLineHeightInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceLikeWord95\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noSpaceRaiseLower\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseHTMLParagraphAutoSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutRawTableWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutTableRowsApart\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord97LineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakWrappedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSnapToGridInCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"selectFldWithFirstOrLastChar\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"applyBreakingRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotWrapTextWithPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseEastAsianBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord2002TableStyleRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"growAutofit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useFELayout\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useNormalStyleForList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseIndentAsNumberingTabStop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAltKinsokuLineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowSpaceOfSameStyleInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressIndentation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutofitConstrainedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autofitToFirstFixedWidthCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"underlineTabInNumList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHangulFixedWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"splitPgBreakAndParaMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignCellWithSp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakConstrainedForcedTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignInTxbx\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAnsiKerningPairs\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"cachedColBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"compatSetting\" type=\"CT_CompatSetting\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CompatSetting\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVar\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVars\">\n    <xsd:sequence>\n      <xsd:element name=\"docVar\" type=\"CT_DocVar\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocRsids\">\n    <xsd:sequence>\n      <xsd:element name=\"rsidRoot\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CharacterSpacing\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doNotCompress\"/>\n      <xsd:enumeration value=\"compressPunctuation\"/>\n      <xsd:enumeration value=\"compressPunctuationAndJapaneseKana\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CharacterSpacing\">\n    <xsd:attribute name=\"val\" type=\"ST_CharacterSpacing\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SaveThroughXslt\">\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"solutionID\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"rPrDefault\" type=\"CT_RPrDefault\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPrDefault\" type=\"CT_PPrDefault\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WmlColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorSchemeMapping\">\n    <xsd:attribute name=\"bg1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"hyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"followedHyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReadingModeInkLockDown\">\n    <xsd:attribute name=\"actualPg\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"w\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"fontSz\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WriteProtection\">\n    <xsd:attribute name=\"recommended\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Settings\">\n    <xsd:sequence>\n      <xsd:element name=\"writeProtection\" type=\"CT_WriteProtection\" minOccurs=\"0\"/>\n      <xsd:element name=\"view\" type=\"CT_View\" minOccurs=\"0\"/>\n      <xsd:element name=\"zoom\" type=\"CT_Zoom\" minOccurs=\"0\"/>\n      <xsd:element name=\"removePersonalInformation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"removeDateAndTime\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDisplayPageBoundaries\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayBackgroundShape\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printPostScriptOverText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFractionalCharacterWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedTrueTypeFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedSystemFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSubsetFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorMargins\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignBordersAndEdges\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundFooter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"gutterAtTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideSpellingErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideGrammaticalErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeWritingStyle\" type=\"CT_WritingStyle\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"proofState\" type=\"CT_Proof\" minOccurs=\"0\"/>\n      <xsd:element name=\"formsDesign\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"attachedTemplate\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkStyles\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneFormatFilter\" type=\"CT_StylePaneFilter\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneSortMethod\" type=\"CT_StyleSort\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentType\" type=\"CT_DocType\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailMerge\" type=\"CT_MailMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"revisionView\" type=\"CT_TrackChangesView\" minOccurs=\"0\"/>\n      <xsd:element name=\"trackRevisions\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackMoves\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackFormatting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentProtection\" type=\"CT_DocProtect\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoFormatOverride\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockTheme\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockQFSet\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTabStop\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoHyphenation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"consecutiveHyphenLimit\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hyphenationZone\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotHyphenateCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showEnvelope\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"summaryLength\" type=\"CT_DecimalNumberOrPrecent\" minOccurs=\"0\"/>\n      <xsd:element name=\"clickAndTypeStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTableStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"evenAndOddHeaders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldRevPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrintingSheets\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHorizontalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayVerticalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseMarginsForDrawingGridOrigin\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotShadeFormData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noPunctuationKerning\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"characterSpacingControl\" type=\"CT_CharacterSpacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"printTwoOnOne\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strictFirstAndLastChars\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksAfter\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksBefore\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"savePreviewPicture\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotValidateAgainstSchema\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ignoreMixedContent\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysShowPlaceholderText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDemarcateInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveXmlDataOnly\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useXSLTWhenSaving\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveThroughXslt\" type=\"CT_SaveThroughXslt\" minOccurs=\"0\"/>\n      <xsd:element name=\"showXMLTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysMergeEmptyNamespace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"updateFields\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hdrShapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"compat\" type=\"CT_Compat\" minOccurs=\"0\"/>\n      <xsd:element name=\"docVars\" type=\"CT_DocVars\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsids\" type=\"CT_DocRsids\" minOccurs=\"0\"/>\n      <xsd:element ref=\"m:mathPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attachedSchema\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"themeFontLang\" type=\"CT_Language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrSchemeMapping\" type=\"CT_ColorSchemeMapping\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotIncludeSubdocsInStats\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutoCompressPictures\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forceUpgrade\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"captions\" type=\"CT_Captions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"readModeInkLockDown\" type=\"CT_ReadingModeInkLockDown\" minOccurs=\"0\"/>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"sl:schemaLibrary\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotEmbedSmartTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"decimalSymbol\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"listSeparator\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleSort\">\n    <xsd:attribute name=\"val\" type=\"ST_StyleSort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StylePaneFilter\">\n    <xsd:attribute name=\"allStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"customStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"latentStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"stylesInUse\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"headingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"numberingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"tableStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnRuns\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnParagraphs\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnNumbering\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnTables\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"clearFormatting\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"top3HeadingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"visibleStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"alternateStyleNames\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleSort\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"name\"/>\n      <xsd:enumeration value=\"priority\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"font\"/>\n      <xsd:enumeration value=\"basedOn\"/>\n      <xsd:enumeration value=\"type\"/>\n      <xsd:enumeration value=\"0000\"/>\n      <xsd:enumeration value=\"0001\"/>\n      <xsd:enumeration value=\"0002\"/>\n      <xsd:enumeration value=\"0003\"/>\n      <xsd:enumeration value=\"0004\"/>\n      <xsd:enumeration value=\"0005\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\"/>\n      <xsd:element name=\"divs\" type=\"CT_Divs\" minOccurs=\"0\"/>\n      <xsd:element name=\"encoding\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"optimizeForBrowser\" type=\"CT_OptimizeForBrowser\" minOccurs=\"0\"/>\n      <xsd:element name=\"relyOnVML\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowPNG\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotRelyOnCSS\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSaveAsSingleFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotOrganizeInFolder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseLongFileNames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pixelsPerInch\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"targetScreenSz\" type=\"CT_TargetScreenSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSmartTagsAsXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameScrollbar\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameScrollbar\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameScrollbar\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptimizeForBrowser\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_OnOff\">\n        <xsd:attribute name=\"target\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frame\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"longDesc\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"sourceFileName\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"marW\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"marH\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"scrollbar\" type=\"CT_FrameScrollbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"noResizeAllowed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkedToFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameLayout\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rows\"/>\n      <xsd:enumeration value=\"cols\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameLayout\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameLayout\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FramesetSplitbar\">\n    <xsd:sequence>\n      <xsd:element name=\"w\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBorder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"flatBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frameset\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"framesetSplitbar\" type=\"CT_FramesetSplitbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"frameLayout\" type=\"CT_FrameLayout\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xsd:element name=\"frame\" type=\"CT_Frame\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumPicBullet\">\n    <xsd:choice>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"numPicBulletId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LevelSuffix\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tab\"/>\n      <xsd:enumeration value=\"space\"/>\n      <xsd:enumeration value=\"nothing\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LevelSuffix\">\n    <xsd:attribute name=\"val\" type=\"ST_LevelSuffix\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"null\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LvlLegacy\">\n    <xsd:attribute name=\"legacy\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"legacySpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"legacyIndent\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlRestart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"isLgl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suff\" type=\"CT_LevelSuffix\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlText\" type=\"CT_LevelText\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlPicBulletId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"legacy\" type=\"CT_LvlLegacy\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlJc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n    <xsd:attribute name=\"tplc\" type=\"ST_LongHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"tentative\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MultiLevelType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"singleLevel\"/>\n      <xsd:enumeration value=\"multilevel\"/>\n      <xsd:enumeration value=\"hybridMultilevel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MultiLevelType\">\n    <xsd:attribute name=\"val\" type=\"ST_MultiLevelType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbstractNum\">\n    <xsd:sequence>\n      <xsd:element name=\"nsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"multiLevelType\" type=\"CT_MultiLevelType\" minOccurs=\"0\"/>\n      <xsd:element name=\"tmpl\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"numStyleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"abstractNumId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumLvl\">\n    <xsd:sequence>\n      <xsd:element name=\"startOverride\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Num\">\n    <xsd:sequence>\n      <xsd:element name=\"abstractNumId\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"lvlOverride\" type=\"CT_NumLvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Numbering\">\n    <xsd:sequence>\n      <xsd:element name=\"numPicBullet\" type=\"CT_NumPicBullet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"abstractNum\" type=\"CT_AbstractNum\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"num\" type=\"CT_Num\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"numIdMacAtCleanup\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblStyleOverrideType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"firstRow\"/>\n      <xsd:enumeration value=\"lastRow\"/>\n      <xsd:enumeration value=\"firstCol\"/>\n      <xsd:enumeration value=\"lastCol\"/>\n      <xsd:enumeration value=\"band1Vert\"/>\n      <xsd:enumeration value=\"band2Vert\"/>\n      <xsd:enumeration value=\"band1Horz\"/>\n      <xsd:enumeration value=\"band2Horz\"/>\n      <xsd:enumeration value=\"neCell\"/>\n      <xsd:enumeration value=\"nwCell\"/>\n      <xsd:enumeration value=\"seCell\"/>\n      <xsd:enumeration value=\"swCell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblStylePr\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_TblStyleOverrideType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"table\"/>\n      <xsd:enumeration value=\"numbering\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"aliases\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"basedOn\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"next\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"link\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoRedefine\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"uiPriority\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"semiHidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"unhideWhenUsed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"qFormat\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"locked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personal\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalCompose\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalReply\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStylePr\" type=\"CT_TblStylePr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_StyleType\" use=\"optional\"/>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"default\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"customStyle\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LsdException\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"uiPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"semiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"unhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"qFormat\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LatentStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"lsdException\" type=\"CT_LsdException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"defLockedState\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUIPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"defSemiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUnhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defQFormat\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"count\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Styles\">\n    <xsd:sequence>\n      <xsd:element name=\"docDefaults\" type=\"CT_DocDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"latentStyles\" type=\"CT_LatentStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Panose\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Panose\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decorative\"/>\n      <xsd:enumeration value=\"modern\"/>\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"swiss\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pitch\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"variable\"/>\n      <xsd:enumeration value=\"default\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pitch\">\n    <xsd:attribute name=\"val\" type=\"ST_Pitch\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSig\">\n    <xsd:attribute name=\"usb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb2\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb3\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontRel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"fontKey\" type=\"s:ST_Guid\"/>\n        <xsd:attribute name=\"subsetted\" type=\"s:ST_OnOff\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:sequence>\n      <xsd:element name=\"altName\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"panose1\" type=\"CT_Panose\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_Charset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notTrueType\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pitch\" type=\"CT_Pitch\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sig\" type=\"CT_FontSig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedRegular\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBold\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBoldItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontsList\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DivBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Div\">\n    <xsd:sequence>\n      <xsd:element name=\"blockQuote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bodyDiv\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"marLeft\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marRight\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marTop\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marBottom\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"divBdr\" type=\"CT_DivBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"divsChild\" type=\"CT_Divs\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Divs\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"div\" type=\"CT_Div\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\"/>\n  <xsd:group name=\"EG_MathContent\">\n    <xsd:choice>\n      <xsd:element ref=\"m:oMathPara\"/>\n      <xsd:element ref=\"m:oMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelChunkElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_BlockLevelChunkElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"altChunk\" type=\"CT_AltChunk\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RunLevelElts\">\n    <xsd:choice>\n      <xsd:element name=\"proofErr\" minOccurs=\"0\" type=\"CT_ProofErr\"/>\n      <xsd:element name=\"permStart\" minOccurs=\"0\" type=\"CT_PermStart\"/>\n      <xsd:element name=\"permEnd\" minOccurs=\"0\" type=\"CT_Perm\"/>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ins\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_RunTrackChange\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_RunTrackChange\"/>\n      <xsd:group ref=\"EG_MathContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Body\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sectPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SectPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n        minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Footnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"footnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"footnotes\" type=\"CT_Footnotes\"/>\n  <xsd:complexType name=\"CT_Endnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"endnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"endnotes\" type=\"CT_Endnotes\"/>\n  <xsd:element name=\"hdr\" type=\"CT_HdrFtr\"/>\n  <xsd:element name=\"ftr\" type=\"CT_HdrFtr\"/>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceuri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ThemeColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"background1\"/>\n      <xsd:enumeration value=\"text1\"/>\n      <xsd:enumeration value=\"background2\"/>\n      <xsd:enumeration value=\"text2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DocPartBehavior\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"pg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartBehavior\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartBehavior\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartBehaviors\">\n    <xsd:choice>\n      <xsd:element name=\"behavior\" type=\"CT_DocPartBehavior\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"autoExp\"/>\n      <xsd:enumeration value=\"toolbar\"/>\n      <xsd:enumeration value=\"speller\"/>\n      <xsd:enumeration value=\"formFld\"/>\n      <xsd:enumeration value=\"bbPlcHdr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartTypes\">\n    <xsd:choice>\n      <xsd:element name=\"type\" type=\"CT_DocPartType\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"all\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartGallery\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"placeholder\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"docParts\"/>\n      <xsd:enumeration value=\"coverPg\"/>\n      <xsd:enumeration value=\"eq\"/>\n      <xsd:enumeration value=\"ftrs\"/>\n      <xsd:enumeration value=\"hdrs\"/>\n      <xsd:enumeration value=\"pgNum\"/>\n      <xsd:enumeration value=\"tbls\"/>\n      <xsd:enumeration value=\"watermarks\"/>\n      <xsd:enumeration value=\"autoTxt\"/>\n      <xsd:enumeration value=\"txtBox\"/>\n      <xsd:enumeration value=\"pgNumT\"/>\n      <xsd:enumeration value=\"pgNumB\"/>\n      <xsd:enumeration value=\"pgNumMargins\"/>\n      <xsd:enumeration value=\"tblOfContents\"/>\n      <xsd:enumeration value=\"bib\"/>\n      <xsd:enumeration value=\"custQuickParts\"/>\n      <xsd:enumeration value=\"custCoverPg\"/>\n      <xsd:enumeration value=\"custEq\"/>\n      <xsd:enumeration value=\"custFtrs\"/>\n      <xsd:enumeration value=\"custHdrs\"/>\n      <xsd:enumeration value=\"custPgNum\"/>\n      <xsd:enumeration value=\"custTbls\"/>\n      <xsd:enumeration value=\"custWatermarks\"/>\n      <xsd:enumeration value=\"custAutoTxt\"/>\n      <xsd:enumeration value=\"custTxtBox\"/>\n      <xsd:enumeration value=\"custPgNumT\"/>\n      <xsd:enumeration value=\"custPgNumB\"/>\n      <xsd:enumeration value=\"custPgNumMargins\"/>\n      <xsd:enumeration value=\"custTblOfContents\"/>\n      <xsd:enumeration value=\"custBib\"/>\n      <xsd:enumeration value=\"custom1\"/>\n      <xsd:enumeration value=\"custom2\"/>\n      <xsd:enumeration value=\"custom3\"/>\n      <xsd:enumeration value=\"custom4\"/>\n      <xsd:enumeration value=\"custom5\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartGallery\">\n    <xsd:attribute name=\"val\" type=\"ST_DocPartGallery\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartCategory\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gallery\" type=\"CT_DocPartGallery\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"decorated\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartPr\">\n    <xsd:all>\n      <xsd:element name=\"name\" type=\"CT_DocPartName\" minOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"category\" type=\"CT_DocPartCategory\" minOccurs=\"0\"/>\n      <xsd:element name=\"types\" type=\"CT_DocPartTypes\" minOccurs=\"0\"/>\n      <xsd:element name=\"behaviors\" type=\"CT_DocPartBehaviors\" minOccurs=\"0\"/>\n      <xsd:element name=\"description\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"guid\" type=\"CT_Guid\" minOccurs=\"0\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartPr\" type=\"CT_DocPartPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartBody\" type=\"CT_Body\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocParts\">\n    <xsd:choice>\n      <xsd:element name=\"docPart\" type=\"CT_DocPart\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:element name=\"settings\" type=\"CT_Settings\"/>\n  <xsd:element name=\"webSettings\" type=\"CT_WebSettings\"/>\n  <xsd:element name=\"fonts\" type=\"CT_FontsList\"/>\n  <xsd:element name=\"numbering\" type=\"CT_Numbering\"/>\n  <xsd:element name=\"styles\" type=\"CT_Styles\"/>\n  <xsd:simpleType name=\"ST_CaptionPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"above\"/>\n      <xsd:enumeration value=\"below\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Caption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_CaptionPos\" use=\"optional\"/>\n    <xsd:attribute name=\"chapNum\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"heading\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"noLabel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"numFmt\" type=\"ST_NumberFormat\" use=\"optional\"/>\n    <xsd:attribute name=\"sep\" type=\"ST_ChapterSep\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaptions\">\n    <xsd:sequence>\n      <xsd:element name=\"autoCaption\" type=\"CT_AutoCaption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Captions\">\n    <xsd:sequence>\n      <xsd:element name=\"caption\" type=\"CT_Caption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"autoCaptions\" type=\"CT_AutoCaptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocumentBase\">\n    <xsd:sequence>\n      <xsd:element name=\"background\" type=\"CT_Background\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Document\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"body\" type=\"CT_Body\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n        <xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlossaryDocument\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"docParts\" type=\"CT_DocParts\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:element name=\"document\" type=\"CT_Document\"/>\n  <xsd:element name=\"glossaryDocument\" type=\"CT_GlossaryDocument\"/>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd",
    "content": "<?xml version='1.0'?>\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xs:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xs:element name=\"Types\" type=\"CT_Types\"/>\n  <xs:element name=\"Default\" type=\"CT_Default\"/>\n  <xs:element name=\"Override\" type=\"CT_Override\"/>\n\n  <xs:complexType name=\"CT_Types\">\n    <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element ref=\"Default\"/>\n      <xs:element ref=\"Override\"/>\n    </xs:choice>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Default\">\n    <xs:attribute name=\"Extension\" type=\"ST_Extension\" use=\"required\"/>\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Override\">\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n    <xs:attribute name=\"PartName\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:simpleType name=\"ST_ContentType\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))/((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))((\\s+)*;(\\s+)*(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))=((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+)|(&quot;(([\\p{IsLatin-1Supplement}\\p{IsBasicLatin}-[\\p{Cc}&#127;&quot;\\n\\r]]|(\\s+))|(\\\\[\\p{IsBasicLatin}]))*&quot;))))*)\"\n      />\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:simpleType name=\"ST_Extension\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"([!$&amp;'\\(\\)\\*\\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\\-_~])+\"/>\n    </xs:restriction>\n  </xs:simpleType>\n</xs:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:dcterms=\"http://purl.org/dc/terms/\" elementFormDefault=\"qualified\" blockDefault=\"#all\">\n\n  <xs:import namespace=\"http://purl.org/dc/elements/1.1/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd\"/>\n  <xs:import namespace=\"http://purl.org/dc/terms/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd\"/>\n  <xs:import id=\"xml\" namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n\n  <xs:element name=\"coreProperties\" type=\"CT_CoreProperties\"/>\n\n  <xs:complexType name=\"CT_CoreProperties\">\n    <xs:all>\n      <xs:element name=\"category\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"contentStatus\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dcterms:created\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:creator\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:description\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:identifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"keywords\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Keywords\"/>\n      <xs:element ref=\"dc:language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"lastModifiedBy\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"lastPrinted\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:dateTime\"/>\n      <xs:element ref=\"dcterms:modified\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"revision\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dc:subject\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"version\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n    </xs:all>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keywords\" mixed=\"true\">\n    <xs:sequence>\n      <xs:element name=\"value\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Keyword\"/>\n    </xs:sequence>\n    <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keyword\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"SignatureTime\" type=\"CT_SignatureTime\"/>\n  <xsd:element name=\"RelationshipReference\" type=\"CT_RelationshipReference\"/>\n  <xsd:element name=\"RelationshipsGroupReference\" type=\"CT_RelationshipsGroupReference\"/>\n\n  <xsd:complexType name=\"CT_SignatureTime\">\n    <xsd:sequence>\n      <xsd:element name=\"Format\" type=\"ST_Format\"/>\n      <xsd:element name=\"Value\" type=\"ST_Value\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceId\" type=\"xsd:string\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipsGroupReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceType\" type=\"xsd:anyURI\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_Format\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n\n  <xsd:simpleType name=\"ST_Value\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\\.[0-9])(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"Relationships\" type=\"CT_Relationships\"/>\n  <xsd:element name=\"Relationship\" type=\"CT_Relationship\"/>\n\n  <xsd:complexType name=\"CT_Relationships\">\n    <xsd:sequence>\n      <xsd:element ref=\"Relationship\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_Relationship\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"TargetMode\" type=\"ST_TargetMode\" use=\"optional\"/>\n        <xsd:attribute name=\"Target\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Type\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Id\" type=\"xsd:ID\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_TargetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"External\"/>\n      <xsd:enumeration value=\"Internal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/mce/mc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\tattributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\"\n\ttargetNamespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--\n    This XSD is a modified version of the one found at:\n    https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd\n\n    This XSD has 2 objectives:\n\n        1. round tripping @mc:Ignorable\n\n\t\t\t<w:document\n\t\t\t            xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t            xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t\t\t            mc:Ignorable=\"w14 w15 wp14\">\n\n        2. enabling AlternateContent to be manipulated in certain elements\n           (in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)\n\n\t\tSee further ECMA-376, 4th Edition, Office Open XML File Formats\n\t\tPart 3 : Markup Compatibility and Extensibility\n   -->\n\n  <!--  Objective 1 -->\n  <xsd:attribute name=\"Ignorable\" type=\"xsd:string\" />\n\n  <!--  Objective 2 -->\n\t<xsd:attribute name=\"MustUnderstand\" type=\"xsd:string\"  />\n\t<xsd:attribute name=\"ProcessContent\" type=\"xsd:string\"  />\n\n<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a\nFallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice\nelements. -->\n\t<xsd:element name=\"AlternateContent\">\n\t\t<xsd:complexType>\n\t\t\t<xsd:sequence>\n\t\t\t\t<xsd:element name=\"Choice\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute name=\"Requires\" type=\"xsd:string\" use=\"required\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t\t<xsd:element name=\"Fallback\" minOccurs=\"0\" maxOccurs=\"1\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t</xsd:sequence>\n\t\t\t<!-- AlternateContent elements might include the attributes Ignorable,\n\t\t\t\tMustUnderstand and ProcessContent described in this Part of ECMA-376. These\n\t\t\t\tattributes’ qualified names shall be prefixed when associated with an AlternateContent\n\t\t\t\telement. -->\n\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t</xsd:complexType>\n\t</xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns=\"http://schemas.microsoft.com/office/word/2010/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2010/wordml\">\n   <!-- <xsd:import id=\"rel\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" schemaLocation=\"orel.xsd\"/> -->\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <!-- <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartbasetypes.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartsplineproperties.xsd\"/> -->\n   <xsd:complexType name=\"CT_LongHexNumber\">\n     <xsd:attribute name=\"val\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_OnOff\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"true\"/>\n       <xsd:enumeration value=\"false\"/>\n       <xsd:enumeration value=\"0\"/>\n       <xsd:enumeration value=\"1\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_OnOff\">\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\"/>\n   </xsd:complexType>\n   <xsd:element name=\"docId\" type=\"CT_LongHexNumber\"/>\n   <xsd:element name=\"conflictMode\" type=\"CT_OnOff\"/>\n   <xsd:attributeGroup name=\"AG_Parids\">\n     <xsd:attribute name=\"paraId\" type=\"w:ST_LongHexNumber\"/>\n     <xsd:attribute name=\"textId\" type=\"w:ST_LongHexNumber\"/>\n   </xsd:attributeGroup>\n   <xsd:attribute name=\"anchorId\" type=\"w:ST_LongHexNumber\"/>\n   <xsd:attribute name=\"noSpellErr\" type=\"ST_OnOff\"/>\n   <xsd:element name=\"customXmlConflictInsRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictInsRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:element name=\"customXmlConflictDelRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictDelRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:group name=\"EG_RunLevelConflicts\">\n     <xsd:sequence>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:group name=\"EG_Conflicts\">\n     <xsd:choice>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Percentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_Percentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositivePercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_SchemeColorVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"bg1\"/>\n       <xsd:enumeration value=\"tx1\"/>\n       <xsd:enumeration value=\"bg2\"/>\n       <xsd:enumeration value=\"tx2\"/>\n       <xsd:enumeration value=\"accent1\"/>\n       <xsd:enumeration value=\"accent2\"/>\n       <xsd:enumeration value=\"accent3\"/>\n       <xsd:enumeration value=\"accent4\"/>\n       <xsd:enumeration value=\"accent5\"/>\n       <xsd:enumeration value=\"accent6\"/>\n       <xsd:enumeration value=\"hlink\"/>\n       <xsd:enumeration value=\"folHlink\"/>\n       <xsd:enumeration value=\"dk1\"/>\n       <xsd:enumeration value=\"lt1\"/>\n       <xsd:enumeration value=\"dk2\"/>\n       <xsd:enumeration value=\"lt2\"/>\n       <xsd:enumeration value=\"phClr\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_RectAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PathShadeType\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"shape\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"rect\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LineCap\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"rnd\"/>\n       <xsd:enumeration value=\"sq\"/>\n       <xsd:enumeration value=\"flat\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PresetLineDashVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"solid\"/>\n       <xsd:enumeration value=\"dot\"/>\n       <xsd:enumeration value=\"sysDot\"/>\n       <xsd:enumeration value=\"dash\"/>\n       <xsd:enumeration value=\"sysDash\"/>\n       <xsd:enumeration value=\"lgDash\"/>\n       <xsd:enumeration value=\"dashDot\"/>\n       <xsd:enumeration value=\"sysDashDot\"/>\n       <xsd:enumeration value=\"lgDashDot\"/>\n       <xsd:enumeration value=\"lgDashDotDot\"/>\n       <xsd:enumeration value=\"sysDashDotDot\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PenAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"in\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_CompoundLine\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"sng\"/>\n       <xsd:enumeration value=\"dbl\"/>\n       <xsd:enumeration value=\"thickThin\"/>\n       <xsd:enumeration value=\"thinThick\"/>\n       <xsd:enumeration value=\"tri\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_RelativeRect\">\n     <xsd:attribute name=\"l\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"t\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"r\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"b\" use=\"optional\" type=\"a:ST_Percentage\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorTransform\">\n     <xsd:choice>\n       <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\"/>\n       <xsd:element name=\"sat\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satMod\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lum\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumMod\" type=\"CT_Percentage\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SRgbColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SchemeColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorChoice\">\n     <xsd:choice>\n       <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\"/>\n       <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Color\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStop\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"pos\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStopList\">\n     <xsd:sequence>\n       <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"10\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_LinearShadeProperties\">\n     <xsd:attribute name=\"ang\" type=\"a:ST_PositiveFixedAngle\" use=\"optional\"/>\n     <xsd:attribute name=\"scaled\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PathShadeProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ShadeProperties\">\n     <xsd:choice>\n       <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\"/>\n       <xsd:element name=\"path\" type=\"CT_PathShadeProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SolidColorFillProperties\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientFillProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_FillProperties\">\n     <xsd:choice>\n       <xsd:element name=\"noFill\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\"/>\n       <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_PresetLineDashProperties\">\n     <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineDashProperties\">\n     <xsd:choice>\n       <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n     <xsd:attribute name=\"lim\" type=\"a:ST_PositivePercentage\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineJoinProperties\">\n     <xsd:choice>\n       <xsd:element name=\"round\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"bevel\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_PresetCameraType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueTop\"/>\n       <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n       <xsd:enumeration value=\"legacyObliqueLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueFront\"/>\n       <xsd:enumeration value=\"legacyObliqueRight\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueBottom\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n       <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n       <xsd:enumeration value=\"orthographicFront\"/>\n       <xsd:enumeration value=\"isometricTopUp\"/>\n       <xsd:enumeration value=\"isometricTopDown\"/>\n       <xsd:enumeration value=\"isometricBottomUp\"/>\n       <xsd:enumeration value=\"isometricBottomDown\"/>\n       <xsd:enumeration value=\"isometricLeftUp\"/>\n       <xsd:enumeration value=\"isometricLeftDown\"/>\n       <xsd:enumeration value=\"isometricRightUp\"/>\n       <xsd:enumeration value=\"isometricRightDown\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n       <xsd:enumeration value=\"obliqueTopLeft\"/>\n       <xsd:enumeration value=\"obliqueTop\"/>\n       <xsd:enumeration value=\"obliqueTopRight\"/>\n       <xsd:enumeration value=\"obliqueLeft\"/>\n       <xsd:enumeration value=\"obliqueRight\"/>\n       <xsd:enumeration value=\"obliqueBottomLeft\"/>\n       <xsd:enumeration value=\"obliqueBottom\"/>\n       <xsd:enumeration value=\"obliqueBottomRight\"/>\n       <xsd:enumeration value=\"perspectiveFront\"/>\n       <xsd:enumeration value=\"perspectiveLeft\"/>\n       <xsd:enumeration value=\"perspectiveRight\"/>\n       <xsd:enumeration value=\"perspectiveAbove\"/>\n       <xsd:enumeration value=\"perspectiveBelow\"/>\n       <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveRelaxed\"/>\n       <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Camera\">\n     <xsd:attribute name=\"prst\" use=\"required\" type=\"ST_PresetCameraType\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SphereCoords\">\n     <xsd:attribute name=\"lat\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"lon\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"rev\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_LightRigType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyFlat1\"/>\n       <xsd:enumeration value=\"legacyFlat2\"/>\n       <xsd:enumeration value=\"legacyFlat3\"/>\n       <xsd:enumeration value=\"legacyFlat4\"/>\n       <xsd:enumeration value=\"legacyNormal1\"/>\n       <xsd:enumeration value=\"legacyNormal2\"/>\n       <xsd:enumeration value=\"legacyNormal3\"/>\n       <xsd:enumeration value=\"legacyNormal4\"/>\n       <xsd:enumeration value=\"legacyHarsh1\"/>\n       <xsd:enumeration value=\"legacyHarsh2\"/>\n       <xsd:enumeration value=\"legacyHarsh3\"/>\n       <xsd:enumeration value=\"legacyHarsh4\"/>\n       <xsd:enumeration value=\"threePt\"/>\n       <xsd:enumeration value=\"balanced\"/>\n       <xsd:enumeration value=\"soft\"/>\n       <xsd:enumeration value=\"harsh\"/>\n       <xsd:enumeration value=\"flood\"/>\n       <xsd:enumeration value=\"contrasting\"/>\n       <xsd:enumeration value=\"morning\"/>\n       <xsd:enumeration value=\"sunrise\"/>\n       <xsd:enumeration value=\"sunset\"/>\n       <xsd:enumeration value=\"chilly\"/>\n       <xsd:enumeration value=\"freezing\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"twoPt\"/>\n       <xsd:enumeration value=\"glow\"/>\n       <xsd:enumeration value=\"brightRoom\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LightRigDirection\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_LightRig\">\n     <xsd:sequence>\n       <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n     <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_BevelPresetType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"relaxedInset\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"slope\"/>\n       <xsd:enumeration value=\"cross\"/>\n       <xsd:enumeration value=\"angle\"/>\n       <xsd:enumeration value=\"softRound\"/>\n       <xsd:enumeration value=\"convex\"/>\n       <xsd:enumeration value=\"coolSlant\"/>\n       <xsd:enumeration value=\"divot\"/>\n       <xsd:enumeration value=\"riblet\"/>\n       <xsd:enumeration value=\"hardEdge\"/>\n       <xsd:enumeration value=\"artDeco\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Bevel\">\n     <xsd:attribute name=\"w\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"h\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_PresetMaterialType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyMatte\"/>\n       <xsd:enumeration value=\"legacyPlastic\"/>\n       <xsd:enumeration value=\"legacyMetal\"/>\n       <xsd:enumeration value=\"legacyWireframe\"/>\n       <xsd:enumeration value=\"matte\"/>\n       <xsd:enumeration value=\"plastic\"/>\n       <xsd:enumeration value=\"metal\"/>\n       <xsd:enumeration value=\"warmMatte\"/>\n       <xsd:enumeration value=\"translucentPowder\"/>\n       <xsd:enumeration value=\"powder\"/>\n       <xsd:enumeration value=\"dkEdge\"/>\n       <xsd:enumeration value=\"softEdge\"/>\n       <xsd:enumeration value=\"clear\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"softmetal\"/>\n       <xsd:enumeration value=\"none\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Glow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Shadow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Reflection\">\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"stA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"stPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"fadeDir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_FillTextEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_TextOutlineEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"w\" use=\"optional\" type=\"a:ST_LineWidth\"/>\n     <xsd:attribute name=\"cap\" use=\"optional\" type=\"ST_LineCap\"/>\n     <xsd:attribute name=\"cmpd\" use=\"optional\" type=\"ST_CompoundLine\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_PenAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Scene3D\">\n     <xsd:sequence>\n       <xsd:element name=\"camera\" type=\"CT_Camera\"/>\n       <xsd:element name=\"lightRig\" type=\"CT_LightRig\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Props3D\">\n     <xsd:sequence>\n       <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n       <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"extrusionH\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"contourW\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrTextEffects\">\n     <xsd:sequence>\n       <xsd:element name=\"glow\" minOccurs=\"0\" type=\"CT_Glow\"/>\n       <xsd:element name=\"shadow\" minOccurs=\"0\" type=\"CT_Shadow\"/>\n       <xsd:element name=\"reflection\" minOccurs=\"0\" type=\"CT_Reflection\"/>\n       <xsd:element name=\"textOutline\" minOccurs=\"0\" type=\"CT_TextOutlineEffect\"/>\n       <xsd:element name=\"textFill\" minOccurs=\"0\" type=\"CT_FillTextEffect\"/>\n       <xsd:element name=\"scene3d\" minOccurs=\"0\" type=\"CT_Scene3D\"/>\n       <xsd:element name=\"props3d\" minOccurs=\"0\" type=\"CT_Props3D\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_Ligatures\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"standard\"/>\n       <xsd:enumeration value=\"contextual\"/>\n       <xsd:enumeration value=\"historical\"/>\n       <xsd:enumeration value=\"discretional\"/>\n       <xsd:enumeration value=\"standardContextual\"/>\n       <xsd:enumeration value=\"standardHistorical\"/>\n       <xsd:enumeration value=\"contextualHistorical\"/>\n       <xsd:enumeration value=\"standardDiscretional\"/>\n       <xsd:enumeration value=\"contextualDiscretional\"/>\n       <xsd:enumeration value=\"historicalDiscretional\"/>\n       <xsd:enumeration value=\"standardContextualHistorical\"/>\n       <xsd:enumeration value=\"standardContextualDiscretional\"/>\n       <xsd:enumeration value=\"standardHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"contextualHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"all\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Ligatures\">\n     <xsd:attribute name=\"val\" type=\"ST_Ligatures\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumForm\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"lining\"/>\n       <xsd:enumeration value=\"oldStyle\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumForm\">\n     <xsd:attribute name=\"val\" type=\"ST_NumForm\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumSpacing\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"proportional\"/>\n       <xsd:enumeration value=\"tabular\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumSpacing\">\n     <xsd:attribute name=\"val\" type=\"ST_NumSpacing\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StyleSet\">\n     <xsd:attribute name=\"id\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StylisticSets\">\n     <xsd:sequence minOccurs=\"0\">\n       <xsd:element name=\"styleSet\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_StyleSet\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrOpenType\">\n     <xsd:sequence>\n       <xsd:element name=\"ligatures\" minOccurs=\"0\" type=\"CT_Ligatures\"/>\n       <xsd:element name=\"numForm\" minOccurs=\"0\" type=\"CT_NumForm\"/>\n       <xsd:element name=\"numSpacing\" minOccurs=\"0\" type=\"CT_NumSpacing\"/>\n       <xsd:element name=\"stylisticSets\" minOccurs=\"0\" type=\"CT_StylisticSets\"/>\n       <xsd:element name=\"cntxtAlts\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:element name=\"discardImageEditingData\" type=\"CT_OnOff\"/>\n   <xsd:element name=\"defaultImageDpi\" type=\"CT_DefaultImageDpi\"/>\n   <xsd:complexType name=\"CT_DefaultImageDpi\">\n     <xsd:attribute name=\"val\" type=\"w:ST_DecimalNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"entityPicker\" type=\"w:CT_Empty\"/>\n   <xsd:complexType name=\"CT_SdtCheckboxSymbol\">\n     <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n     <xsd:attribute name=\"val\" type=\"w:ST_ShortHexNumber\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SdtCheckbox\">\n     <xsd:sequence>\n       <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n       <xsd:element name=\"checkedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n       <xsd:element name=\"uncheckedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:element name=\"checkbox\" type=\"CT_SdtCheckbox\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2012/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:element name=\"color\" type=\"w12:CT_Color\"/>\n   <xsd:simpleType name=\"ST_SdtAppearance\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"boundingBox\"/>\n       <xsd:enumeration value=\"tags\"/>\n       <xsd:enumeration value=\"hidden\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:element name=\"dataBinding\" type=\"w12:CT_DataBinding\"/>\n   <xsd:complexType name=\"CT_SdtAppearance\">\n     <xsd:attribute name=\"val\" type=\"ST_SdtAppearance\"/>\n   </xsd:complexType>\n   <xsd:element name=\"appearance\" type=\"CT_SdtAppearance\"/>\n   <xsd:complexType name=\"CT_CommentsEx\">\n     <xsd:sequence>\n       <xsd:element name=\"commentEx\" type=\"CT_CommentEx\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentEx\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"paraIdParent\" type=\"w12:ST_LongHexNumber\" use=\"optional\"/>\n     <xsd:attribute name=\"done\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsEx\" type=\"CT_CommentsEx\"/>\n   <xsd:complexType name=\"CT_People\">\n     <xsd:sequence>\n       <xsd:element name=\"person\" type=\"CT_Person\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PresenceInfo\">\n     <xsd:attribute name=\"providerId\" type=\"xsd:string\" use=\"required\"/>\n     <xsd:attribute name=\"userId\" type=\"xsd:string\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Person\">\n     <xsd:sequence>\n       <xsd:element name=\"presenceInfo\" type=\"CT_PresenceInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"people\" type=\"CT_People\"/>\n   <xsd:complexType name=\"CT_SdtRepeatedSection\">\n     <xsd:sequence>\n       <xsd:element name=\"sectionTitle\" type=\"w12:CT_String\" minOccurs=\"0\"/>\n       <xsd:element name=\"doNotAllowInsertDeleteSection\" type=\"w12:CT_OnOff\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_Guid\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Guid\">\n     <xsd:attribute name=\"val\" type=\"ST_Guid\"/>\n   </xsd:complexType>\n   <xsd:element name=\"repeatingSection\" type=\"CT_SdtRepeatedSection\"/>\n   <xsd:element name=\"repeatingSectionItem\" type=\"w12:CT_Empty\"/>\n   <xsd:element name=\"chartTrackingRefBased\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"collapsed\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"docId\" type=\"CT_Guid\"/>\n   <xsd:element name=\"footnoteColumns\" type=\"w12:CT_DecimalNumber\"/>\n   <xsd:element name=\"webExtensionLinked\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"webExtensionCreated\" type=\"w12:CT_OnOff\"/>\n   <xsd:attribute name=\"restartNumberingAfterBreak\" type=\"s:ST_OnOff\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_Extension\">\n     <xsd:sequence>\n       <xsd:any processContents=\"lax\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_ExtensionList\">\n     <xsd:sequence>\n       <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\">\n   <xsd:import id=\"w16\" namespace=\"http://schemas.microsoft.com/office/word/2018/wordml\" schemaLocation=\"wml-2018.xsd\"/>\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import id=\"s\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"commentExtensible\" type=\"CT_CommentExtensible\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"durableId\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"dateUtc\" type=\"w:ST_DateTime\" use=\"optional\"/>\n     <xsd:attribute name=\"intelligentPlaceholder\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsExtensible\" type=\"CT_CommentsExtensible\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" targetNamespace=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsIds\">\n     <xsd:sequence>\n       <xsd:element name=\"commentId\" type=\"CT_CommentId\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentId\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"durableId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsIds\" type=\"CT_CommentsIds\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" targetNamespace=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:attribute name=\"storeItemChecksum\" type=\"w12:ST_String\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_SymEx\">\n     <xsd:attribute name=\"font\" type=\"w12:ST_String\"/>\n     <xsd:attribute name=\"char\" type=\"w12:ST_LongHexNumber\"/>\n   </xsd:complexType>\n   <xsd:element name=\"symEx\" type=\"CT_SymEx\"/>\n </xsd:schema>\n"
  },
  {
    "path": "skills/xlsx/scripts/office/soffice.py",
    "content": "\"\"\"\nHelper for running LibreOffice (soffice) in environments where AF_UNIX\nsockets may be blocked (e.g., sandboxed VMs).  Detects the restriction\nat runtime and applies an LD_PRELOAD shim if needed.\n\nUsage:\n    from office.soffice import run_soffice, get_soffice_env\n\n    # Option 1 – run soffice directly\n    result = run_soffice([\"--headless\", \"--convert-to\", \"pdf\", \"input.docx\"])\n\n    # Option 2 – get env dict for your own subprocess calls\n    env = get_soffice_env()\n    subprocess.run([\"soffice\", ...], env=env)\n\"\"\"\n\nimport os\nimport socket\nimport subprocess\nimport tempfile\nfrom pathlib import Path\n\n\ndef get_soffice_env() -> dict:\n    env = os.environ.copy()\n    env[\"SAL_USE_VCLPLUGIN\"] = \"svp\"\n\n    if _needs_shim():\n        shim = _ensure_shim()\n        env[\"LD_PRELOAD\"] = str(shim)\n\n    return env\n\n\ndef run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:\n    env = get_soffice_env()\n    return subprocess.run([\"soffice\"] + args, env=env, **kwargs)\n\n\n\n_SHIM_SO = Path(tempfile.gettempdir()) / \"lo_socket_shim.so\"\n\n\ndef _needs_shim() -> bool:\n    try:\n        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        s.close()\n        return False\n    except OSError:\n        return True\n\n\ndef _ensure_shim() -> Path:\n    if _SHIM_SO.exists():\n        return _SHIM_SO\n\n    src = Path(tempfile.gettempdir()) / \"lo_socket_shim.c\"\n    src.write_text(_SHIM_SOURCE)\n    subprocess.run(\n        [\"gcc\", \"-shared\", \"-fPIC\", \"-o\", str(_SHIM_SO), str(src), \"-ldl\"],\n        check=True,\n        capture_output=True,\n    )\n    src.unlink()\n    return _SHIM_SO\n\n\n\n_SHIM_SOURCE = r\"\"\"\n#define _GNU_SOURCE\n#include <dlfcn.h>\n#include <errno.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/socket.h>\n#include <unistd.h>\n\nstatic int (*real_socket)(int, int, int);\nstatic int (*real_socketpair)(int, int, int, int[2]);\nstatic int (*real_listen)(int, int);\nstatic int (*real_accept)(int, struct sockaddr *, socklen_t *);\nstatic int (*real_close)(int);\nstatic int (*real_read)(int, void *, size_t);\n\n/* Per-FD bookkeeping (FDs >= 1024 are passed through unshimmed). */\nstatic int is_shimmed[1024];\nstatic int peer_of[1024];\nstatic int wake_r[1024];            /* accept() blocks reading this */\nstatic int wake_w[1024];            /* close()  writes to this      */\nstatic int listener_fd = -1;        /* FD that received listen()    */\n\n__attribute__((constructor))\nstatic void init(void) {\n    real_socket     = dlsym(RTLD_NEXT, \"socket\");\n    real_socketpair = dlsym(RTLD_NEXT, \"socketpair\");\n    real_listen     = dlsym(RTLD_NEXT, \"listen\");\n    real_accept     = dlsym(RTLD_NEXT, \"accept\");\n    real_close      = dlsym(RTLD_NEXT, \"close\");\n    real_read       = dlsym(RTLD_NEXT, \"read\");\n    for (int i = 0; i < 1024; i++) {\n        peer_of[i] = -1;\n        wake_r[i]  = -1;\n        wake_w[i]  = -1;\n    }\n}\n\n/* ---- socket ---------------------------------------------------------- */\nint socket(int domain, int type, int protocol) {\n    if (domain == AF_UNIX) {\n        int fd = real_socket(domain, type, protocol);\n        if (fd >= 0) return fd;\n        /* socket(AF_UNIX) blocked – fall back to socketpair(). */\n        int sv[2];\n        if (real_socketpair(domain, type, protocol, sv) == 0) {\n            if (sv[0] >= 0 && sv[0] < 1024) {\n                is_shimmed[sv[0]] = 1;\n                peer_of[sv[0]]    = sv[1];\n                int wp[2];\n                if (pipe(wp) == 0) {\n                    wake_r[sv[0]] = wp[0];\n                    wake_w[sv[0]] = wp[1];\n                }\n            }\n            return sv[0];\n        }\n        errno = EPERM;\n        return -1;\n    }\n    return real_socket(domain, type, protocol);\n}\n\n/* ---- listen ---------------------------------------------------------- */\nint listen(int sockfd, int backlog) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        listener_fd = sockfd;\n        return 0;\n    }\n    return real_listen(sockfd, backlog);\n}\n\n/* ---- accept ---------------------------------------------------------- */\nint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {\n    if (sockfd >= 0 && sockfd < 1024 && is_shimmed[sockfd]) {\n        /* Block until close() writes to the wake pipe. */\n        if (wake_r[sockfd] >= 0) {\n            char buf;\n            real_read(wake_r[sockfd], &buf, 1);\n        }\n        errno = ECONNABORTED;\n        return -1;\n    }\n    return real_accept(sockfd, addr, addrlen);\n}\n\n/* ---- close ----------------------------------------------------------- */\nint close(int fd) {\n    if (fd >= 0 && fd < 1024 && is_shimmed[fd]) {\n        int was_listener = (fd == listener_fd);\n        is_shimmed[fd] = 0;\n\n        if (wake_w[fd] >= 0) {              /* unblock accept() */\n            char c = 0;\n            write(wake_w[fd], &c, 1);\n            real_close(wake_w[fd]);\n            wake_w[fd] = -1;\n        }\n        if (wake_r[fd] >= 0) { real_close(wake_r[fd]); wake_r[fd]  = -1; }\n        if (peer_of[fd] >= 0) { real_close(peer_of[fd]); peer_of[fd] = -1; }\n\n        if (was_listener)\n            _exit(0);                        /* conversion done – exit */\n    }\n    return real_close(fd);\n}\n\"\"\"\n\n\n\nif __name__ == \"__main__\":\n    import sys\n    result = run_soffice(sys.argv[1:])\n    sys.exit(result.returncode)\n"
  },
  {
    "path": "skills/xlsx/scripts/office/unpack.py",
    "content": "\"\"\"Unpack Office files (DOCX, PPTX, XLSX) for editing.\n\nExtracts the ZIP archive, pretty-prints XML files, and optionally:\n- Merges adjacent runs with identical formatting (DOCX only)\n- Simplifies adjacent tracked changes from same author (DOCX only)\n\nUsage:\n    python unpack.py <office_file> <output_dir> [options]\n\nExamples:\n    python unpack.py document.docx unpacked/\n    python unpack.py presentation.pptx unpacked/\n    python unpack.py document.docx unpacked/ --merge-runs false\n\"\"\"\n\nimport argparse\nimport sys\nimport zipfile\nfrom pathlib import Path\n\nimport defusedxml.minidom\n\nfrom helpers.merge_runs import merge_runs as do_merge_runs\nfrom helpers.simplify_redlines import simplify_redlines as do_simplify_redlines\n\nSMART_QUOTE_REPLACEMENTS = {\n    \"\\u201c\": \"&#x201C;\",  \n    \"\\u201d\": \"&#x201D;\",  \n    \"\\u2018\": \"&#x2018;\",  \n    \"\\u2019\": \"&#x2019;\",  \n}\n\n\ndef unpack(\n    input_file: str,\n    output_directory: str,\n    merge_runs: bool = True,\n    simplify_redlines: bool = True,\n) -> tuple[None, str]:\n    input_path = Path(input_file)\n    output_path = Path(output_directory)\n    suffix = input_path.suffix.lower()\n\n    if not input_path.exists():\n        return None, f\"Error: {input_file} does not exist\"\n\n    if suffix not in {\".docx\", \".pptx\", \".xlsx\"}:\n        return None, f\"Error: {input_file} must be a .docx, .pptx, or .xlsx file\"\n\n    try:\n        output_path.mkdir(parents=True, exist_ok=True)\n\n        with zipfile.ZipFile(input_path, \"r\") as zf:\n            zf.extractall(output_path)\n\n        xml_files = list(output_path.rglob(\"*.xml\")) + list(output_path.rglob(\"*.rels\"))\n        for xml_file in xml_files:\n            _pretty_print_xml(xml_file)\n\n        message = f\"Unpacked {input_file} ({len(xml_files)} XML files)\"\n\n        if suffix == \".docx\":\n            if simplify_redlines:\n                simplify_count, _ = do_simplify_redlines(str(output_path))\n                message += f\", simplified {simplify_count} tracked changes\"\n\n            if merge_runs:\n                merge_count, _ = do_merge_runs(str(output_path))\n                message += f\", merged {merge_count} runs\"\n\n        for xml_file in xml_files:\n            _escape_smart_quotes(xml_file)\n\n        return None, message\n\n    except zipfile.BadZipFile:\n        return None, f\"Error: {input_file} is not a valid Office file\"\n    except Exception as e:\n        return None, f\"Error unpacking: {e}\"\n\n\ndef _pretty_print_xml(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        dom = defusedxml.minidom.parseString(content)\n        xml_file.write_bytes(dom.toprettyxml(indent=\"  \", encoding=\"utf-8\"))\n    except Exception:\n        pass  \n\n\ndef _escape_smart_quotes(xml_file: Path) -> None:\n    try:\n        content = xml_file.read_text(encoding=\"utf-8\")\n        for char, entity in SMART_QUOTE_REPLACEMENTS.items():\n            content = content.replace(char, entity)\n        xml_file.write_text(content, encoding=\"utf-8\")\n    except Exception:\n        pass\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description=\"Unpack an Office file (DOCX, PPTX, XLSX) for editing\"\n    )\n    parser.add_argument(\"input_file\", help=\"Office file to unpack\")\n    parser.add_argument(\"output_directory\", help=\"Output directory\")\n    parser.add_argument(\n        \"--merge-runs\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent runs with identical formatting (DOCX only, default: true)\",\n    )\n    parser.add_argument(\n        \"--simplify-redlines\",\n        type=lambda x: x.lower() == \"true\",\n        default=True,\n        metavar=\"true|false\",\n        help=\"Merge adjacent tracked changes from same author (DOCX only, default: true)\",\n    )\n    args = parser.parse_args()\n\n    _, message = unpack(\n        args.input_file,\n        args.output_directory,\n        merge_runs=args.merge_runs,\n        simplify_redlines=args.simplify_redlines,\n    )\n    print(message)\n\n    if \"Error\" in message:\n        sys.exit(1)\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validate.py",
    "content": "\"\"\"\nCommand line tool to validate Office document XML files against XSD schemas and tracked changes.\n\nUsage:\n    python validate.py <path> [--original <original_file>] [--auto-repair] [--author NAME]\n\nThe first argument can be either:\n- An unpacked directory containing the Office document XML files\n- A packed Office file (.docx/.pptx/.xlsx) which will be unpacked to a temp directory\n\nAuto-repair fixes:\n- paraId/durableId values that exceed OOXML limits\n- Missing xml:space=\"preserve\" on w:t elements with whitespace\n\"\"\"\n\nimport argparse\nimport sys\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\nfrom validators import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Validate Office document XML files\")\n    parser.add_argument(\n        \"path\",\n        help=\"Path to unpacked directory or packed Office file (.docx/.pptx/.xlsx)\",\n    )\n    parser.add_argument(\n        \"--original\",\n        required=False,\n        default=None,\n        help=\"Path to original file (.docx/.pptx/.xlsx). If omitted, all XSD errors are reported and redlining validation is skipped.\",\n    )\n    parser.add_argument(\n        \"-v\",\n        \"--verbose\",\n        action=\"store_true\",\n        help=\"Enable verbose output\",\n    )\n    parser.add_argument(\n        \"--auto-repair\",\n        action=\"store_true\",\n        help=\"Automatically repair common issues (hex IDs, whitespace preservation)\",\n    )\n    parser.add_argument(\n        \"--author\",\n        default=\"Claude\",\n        help=\"Author name for redlining validation (default: Claude)\",\n    )\n    args = parser.parse_args()\n\n    path = Path(args.path)\n    assert path.exists(), f\"Error: {path} does not exist\"\n\n    original_file = None\n    if args.original:\n        original_file = Path(args.original)\n        assert original_file.is_file(), f\"Error: {original_file} is not a file\"\n        assert original_file.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"], (\n            f\"Error: {original_file} must be a .docx, .pptx, or .xlsx file\"\n        )\n\n    file_extension = (original_file or path).suffix.lower()\n    assert file_extension in [\".docx\", \".pptx\", \".xlsx\"], (\n        f\"Error: Cannot determine file type from {path}. Use --original or provide a .docx/.pptx/.xlsx file.\"\n    )\n\n    if path.is_file() and path.suffix.lower() in [\".docx\", \".pptx\", \".xlsx\"]:\n        temp_dir = tempfile.mkdtemp()\n        with zipfile.ZipFile(path, \"r\") as zf:\n            zf.extractall(temp_dir)\n        unpacked_dir = Path(temp_dir)\n    else:\n        assert path.is_dir(), f\"Error: {path} is not a directory or Office file\"\n        unpacked_dir = path\n\n    match file_extension:\n        case \".docx\":\n            validators = [\n                DOCXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n            if original_file:\n                validators.append(\n                    RedliningValidator(unpacked_dir, original_file, verbose=args.verbose, author=args.author)  \n                )\n        case \".pptx\":\n            validators = [\n                PPTXSchemaValidator(unpacked_dir, original_file, verbose=args.verbose),\n            ]\n        case _:\n            print(f\"Error: Validation not supported for file type {file_extension}\")\n            sys.exit(1)\n\n    if args.auto_repair:\n        total_repairs = sum(v.repair() for v in validators)\n        if total_repairs:\n            print(f\"Auto-repaired {total_repairs} issue(s)\")\n\n    success = all(v.validate() for v in validators)\n\n    if success:\n        print(\"All validations PASSED!\")\n\n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validators/__init__.py",
    "content": "\"\"\"\nValidation modules for Word document processing.\n\"\"\"\n\nfrom .base import BaseSchemaValidator\nfrom .docx import DOCXSchemaValidator\nfrom .pptx import PPTXSchemaValidator\nfrom .redlining import RedliningValidator\n\n__all__ = [\n    \"BaseSchemaValidator\",\n    \"DOCXSchemaValidator\",\n    \"PPTXSchemaValidator\",\n    \"RedliningValidator\",\n]\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validators/base.py",
    "content": "\"\"\"\nBase validator with common validation logic for document files.\n\"\"\"\n\nimport re\nfrom pathlib import Path\n\nimport defusedxml.minidom\nimport lxml.etree\n\n\nclass BaseSchemaValidator:\n\n    IGNORED_VALIDATION_ERRORS = [\n        \"hyphenationZone\",\n        \"purl.org/dc/terms\",\n    ]\n\n    UNIQUE_ID_REQUIREMENTS = {\n        \"comment\": (\"id\", \"file\"),  \n        \"commentrangestart\": (\"id\", \"file\"),  \n        \"commentrangeend\": (\"id\", \"file\"),  \n        \"bookmarkstart\": (\"id\", \"file\"),  \n        \"bookmarkend\": (\"id\", \"file\"),  \n        \"sldid\": (\"id\", \"file\"),  \n        \"sldmasterid\": (\"id\", \"global\"),  \n        \"sldlayoutid\": (\"id\", \"global\"),  \n        \"cm\": (\"authorid\", \"file\"),  \n        \"sheet\": (\"sheetid\", \"file\"),  \n        \"definedname\": (\"id\", \"file\"),  \n        \"cxnsp\": (\"id\", \"file\"),  \n        \"sp\": (\"id\", \"file\"),  \n        \"pic\": (\"id\", \"file\"),  \n        \"grpsp\": (\"id\", \"file\"),  \n    }\n\n    EXCLUDED_ID_CONTAINERS = {\n        \"sectionlst\",  \n    }\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    SCHEMA_MAPPINGS = {\n        \"word\": \"ISO-IEC29500-4_2016/wml.xsd\",  \n        \"ppt\": \"ISO-IEC29500-4_2016/pml.xsd\",  \n        \"xl\": \"ISO-IEC29500-4_2016/sml.xsd\",  \n        \"[Content_Types].xml\": \"ecma/fouth-edition/opc-contentTypes.xsd\",\n        \"app.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd\",\n        \"core.xml\": \"ecma/fouth-edition/opc-coreProperties.xsd\",\n        \"custom.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd\",\n        \".rels\": \"ecma/fouth-edition/opc-relationships.xsd\",\n        \"people.xml\": \"microsoft/wml-2012.xsd\",\n        \"commentsIds.xml\": \"microsoft/wml-cid-2016.xsd\",\n        \"commentsExtensible.xml\": \"microsoft/wml-cex-2018.xsd\",\n        \"commentsExtended.xml\": \"microsoft/wml-2012.xsd\",\n        \"chart\": \"ISO-IEC29500-4_2016/dml-chart.xsd\",\n        \"theme\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n        \"drawing\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n    }\n\n    MC_NAMESPACE = \"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\"\n\n    PACKAGE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/relationships\"\n    )\n    OFFICE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    )\n    CONTENT_TYPES_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/content-types\"\n    )\n\n    MAIN_CONTENT_FOLDERS = {\"word\", \"ppt\", \"xl\"}\n\n    OOXML_NAMESPACES = {\n        \"http://schemas.openxmlformats.org/officeDocument/2006/math\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n        \"http://schemas.openxmlformats.org/schemaLibrary/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chart\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/diagram\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n        \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\",\n        \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\",\n        \"http://www.w3.org/XML/1998/namespace\",\n    }\n\n    def __init__(self, unpacked_dir, original_file=None, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir).resolve()\n        self.original_file = Path(original_file) if original_file else None\n        self.verbose = verbose\n\n        self.schemas_dir = Path(__file__).parent.parent / \"schemas\"\n\n        patterns = [\"*.xml\", \"*.rels\"]\n        self.xml_files = [\n            f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)\n        ]\n\n        if not self.xml_files:\n            print(f\"Warning: No XML files found in {self.unpacked_dir}\")\n\n    def validate(self):\n        raise NotImplementedError(\"Subclasses must implement the validate method\")\n\n    def repair(self) -> int:\n        return self.repair_whitespace_preservation()\n\n    def repair_whitespace_preservation(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if elem.tagName.endswith(\":t\") and elem.firstChild:\n                        text = elem.firstChild.nodeValue\n                        if text and (text.startswith((' ', '\\t')) or text.endswith((' ', '\\t'))):\n                            if elem.getAttribute(\"xml:space\") != \"preserve\":\n                                elem.setAttribute(\"xml:space\", \"preserve\")\n                                text_preview = repr(text[:30]) + \"...\" if len(text) > 30 else repr(text)\n                                print(f\"  Repaired: {xml_file.name}: Added xml:space='preserve' to {elem.tagName}: {text_preview}\")\n                                repairs += 1\n                                modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n    def validate_xml(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                lxml.etree.parse(str(xml_file))\n            except lxml.etree.XMLSyntaxError as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Line {e.lineno}: {e.msg}\"\n                )\n            except Exception as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Unexpected error: {str(e)}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} XML violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All XML files are well-formed\")\n            return True\n\n    def validate_namespaces(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                declared = set(root.nsmap.keys()) - {None}  \n\n                for attr_val in [\n                    v for k, v in root.attrib.items() if k.endswith(\"Ignorable\")\n                ]:\n                    undeclared = set(attr_val.split()) - declared\n                    errors.extend(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Namespace '{ns}' in Ignorable but not declared\"\n                        for ns in undeclared\n                    )\n            except lxml.etree.XMLSyntaxError:\n                continue\n\n        if errors:\n            print(f\"FAILED - {len(errors)} namespace issues:\")\n            for error in errors:\n                print(error)\n            return False\n        if self.verbose:\n            print(\"PASSED - All namespace prefixes properly declared\")\n        return True\n\n    def validate_unique_ids(self):\n        errors = []\n        global_ids = {}  \n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                file_ids = {}  \n\n                mc_elements = root.xpath(\n                    \".//mc:AlternateContent\", namespaces={\"mc\": self.MC_NAMESPACE}\n                )\n                for elem in mc_elements:\n                    elem.getparent().remove(elem)\n\n                for elem in root.iter():\n                    tag = (\n                        elem.tag.split(\"}\")[-1].lower()\n                        if \"}\" in elem.tag\n                        else elem.tag.lower()\n                    )\n\n                    if tag in self.UNIQUE_ID_REQUIREMENTS:\n                        in_excluded_container = any(\n                            ancestor.tag.split(\"}\")[-1].lower() in self.EXCLUDED_ID_CONTAINERS\n                            for ancestor in elem.iterancestors()\n                        )\n                        if in_excluded_container:\n                            continue\n\n                        attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]\n\n                        id_value = None\n                        for attr, value in elem.attrib.items():\n                            attr_local = (\n                                attr.split(\"}\")[-1].lower()\n                                if \"}\" in attr\n                                else attr.lower()\n                            )\n                            if attr_local == attr_name:\n                                id_value = value\n                                break\n\n                        if id_value is not None:\n                            if scope == \"global\":\n                                if id_value in global_ids:\n                                    prev_file, prev_line, prev_tag = global_ids[\n                                        id_value\n                                    ]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> \"\n                                        f\"already used in {prev_file} at line {prev_line} in <{prev_tag}>\"\n                                    )\n                                else:\n                                    global_ids[id_value] = (\n                                        xml_file.relative_to(self.unpacked_dir),\n                                        elem.sourceline,\n                                        tag,\n                                    )\n                            elif scope == \"file\":\n                                key = (tag, attr_name)\n                                if key not in file_ids:\n                                    file_ids[key] = {}\n\n                                if id_value in file_ids[key]:\n                                    prev_line = file_ids[key][id_value]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> \"\n                                        f\"(first occurrence at line {prev_line})\"\n                                    )\n                                else:\n                                    file_ids[key][id_value] = elem.sourceline\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} ID uniqueness violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All required IDs are unique\")\n            return True\n\n    def validate_file_references(self):\n        errors = []\n\n        rels_files = list(self.unpacked_dir.rglob(\"*.rels\"))\n\n        if not rels_files:\n            if self.verbose:\n                print(\"PASSED - No .rels files found\")\n            return True\n\n        all_files = []\n        for file_path in self.unpacked_dir.rglob(\"*\"):\n            if (\n                file_path.is_file()\n                and file_path.name != \"[Content_Types].xml\"\n                and not file_path.name.endswith(\".rels\")\n            ):  \n                all_files.append(file_path.resolve())\n\n        all_referenced_files = set()\n\n        if self.verbose:\n            print(\n                f\"Found {len(rels_files)} .rels files and {len(all_files)} target files\"\n            )\n\n        for rels_file in rels_files:\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                rels_dir = rels_file.parent\n\n                referenced_files = set()\n                broken_refs = []\n\n                for rel in rels_root.findall(\n                    \".//ns:Relationship\",\n                    namespaces={\"ns\": self.PACKAGE_RELATIONSHIPS_NAMESPACE},\n                ):\n                    target = rel.get(\"Target\")\n                    if target and not target.startswith(\n                        (\"http\", \"mailto:\")\n                    ):  \n                        if target.startswith(\"/\"):\n                            target_path = self.unpacked_dir / target.lstrip(\"/\")\n                        elif rels_file.name == \".rels\":\n                            target_path = self.unpacked_dir / target\n                        else:\n                            base_dir = rels_dir.parent\n                            target_path = base_dir / target\n\n                        try:\n                            target_path = target_path.resolve()\n                            if target_path.exists() and target_path.is_file():\n                                referenced_files.add(target_path)\n                                all_referenced_files.add(target_path)\n                            else:\n                                broken_refs.append((target, rel.sourceline))\n                        except (OSError, ValueError):\n                            broken_refs.append((target, rel.sourceline))\n\n                if broken_refs:\n                    rel_path = rels_file.relative_to(self.unpacked_dir)\n                    for broken_ref, line_num in broken_refs:\n                        errors.append(\n                            f\"  {rel_path}: Line {line_num}: Broken reference to {broken_ref}\"\n                        )\n\n            except Exception as e:\n                rel_path = rels_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error parsing {rel_path}: {e}\")\n\n        unreferenced_files = set(all_files) - all_referenced_files\n\n        if unreferenced_files:\n            for unref_file in sorted(unreferenced_files):\n                unref_rel_path = unref_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Unreferenced file: {unref_rel_path}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"CRITICAL: These errors will cause the document to appear corrupt. \"\n                + \"Broken references MUST be fixed, \"\n                + \"and unreferenced files MUST be referenced or removed.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All references are valid and all files are properly referenced\"\n                )\n            return True\n\n    def validate_all_relationship_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.suffix == \".rels\":\n                continue\n\n            rels_dir = xml_file.parent / \"_rels\"\n            rels_file = rels_dir / f\"{xml_file.name}.rels\"\n\n            if not rels_file.exists():\n                continue\n\n            try:\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n                rid_to_type = {}\n\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rid = rel.get(\"Id\")\n                    rel_type = rel.get(\"Type\", \"\")\n                    if rid:\n                        if rid in rid_to_type:\n                            rels_rel_path = rels_file.relative_to(self.unpacked_dir)\n                            errors.append(\n                                f\"  {rels_rel_path}: Line {rel.sourceline}: \"\n                                f\"Duplicate relationship ID '{rid}' (IDs must be unique)\"\n                            )\n                        type_name = (\n                            rel_type.split(\"/\")[-1] if \"/\" in rel_type else rel_type\n                        )\n                        rid_to_type[rid] = type_name\n\n                xml_root = lxml.etree.parse(str(xml_file)).getroot()\n\n                r_ns = self.OFFICE_RELATIONSHIPS_NAMESPACE\n                rid_attrs_to_check = [\"id\", \"embed\", \"link\"]\n                for elem in xml_root.iter():\n                    for attr_name in rid_attrs_to_check:\n                        rid_attr = elem.get(f\"{{{r_ns}}}{attr_name}\")\n                        if not rid_attr:\n                            continue\n                        xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                        elem_name = (\n                            elem.tag.split(\"}\")[-1] if \"}\" in elem.tag else elem.tag\n                        )\n\n                        if rid_attr not in rid_to_type:\n                            errors.append(\n                                f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                f\"<{elem_name}> r:{attr_name} references non-existent relationship '{rid_attr}' \"\n                                f\"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})\"\n                            )\n                        elif attr_name == \"id\" and self.ELEMENT_RELATIONSHIP_TYPES:\n                            expected_type = self._get_expected_relationship_type(\n                                elem_name\n                            )\n                            if expected_type:\n                                actual_type = rid_to_type[rid_attr]\n                                if expected_type not in actual_type.lower():\n                                    errors.append(\n                                        f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                        f\"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' \"\n                                        f\"but should point to a '{expected_type}' relationship\"\n                                    )\n\n            except Exception as e:\n                xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error processing {xml_rel_path}: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship ID reference errors:\")\n            for error in errors:\n                print(error)\n            print(\"\\nThese ID mismatches will cause the document to appear corrupt!\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All relationship ID references are valid\")\n            return True\n\n    def _get_expected_relationship_type(self, element_name):\n        elem_lower = element_name.lower()\n\n        if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:\n            return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]\n\n        if elem_lower.endswith(\"id\") and len(elem_lower) > 2:\n            prefix = elem_lower[:-2]  \n            if prefix.endswith(\"master\"):\n                return prefix.lower()\n            elif prefix.endswith(\"layout\"):\n                return prefix.lower()\n            else:\n                if prefix == \"sld\":\n                    return \"slide\"\n                return prefix.lower()\n\n        if elem_lower.endswith(\"reference\") and len(elem_lower) > 9:\n            prefix = elem_lower[:-9]  \n            return prefix.lower()\n\n        return None\n\n    def validate_content_types(self):\n        errors = []\n\n        content_types_file = self.unpacked_dir / \"[Content_Types].xml\"\n        if not content_types_file.exists():\n            print(\"FAILED - [Content_Types].xml file not found\")\n            return False\n\n        try:\n            root = lxml.etree.parse(str(content_types_file)).getroot()\n            declared_parts = set()\n            declared_extensions = set()\n\n            for override in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override\"\n            ):\n                part_name = override.get(\"PartName\")\n                if part_name is not None:\n                    declared_parts.add(part_name.lstrip(\"/\"))\n\n            for default in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default\"\n            ):\n                extension = default.get(\"Extension\")\n                if extension is not None:\n                    declared_extensions.add(extension.lower())\n\n            declarable_roots = {\n                \"sld\",\n                \"sldLayout\",\n                \"sldMaster\",\n                \"presentation\",  \n                \"document\",  \n                \"workbook\",\n                \"worksheet\",  \n                \"theme\",  \n            }\n\n            media_extensions = {\n                \"png\": \"image/png\",\n                \"jpg\": \"image/jpeg\",\n                \"jpeg\": \"image/jpeg\",\n                \"gif\": \"image/gif\",\n                \"bmp\": \"image/bmp\",\n                \"tiff\": \"image/tiff\",\n                \"wmf\": \"image/x-wmf\",\n                \"emf\": \"image/x-emf\",\n            }\n\n            all_files = list(self.unpacked_dir.rglob(\"*\"))\n            all_files = [f for f in all_files if f.is_file()]\n\n            for xml_file in self.xml_files:\n                path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(\n                    \"\\\\\", \"/\"\n                )\n\n                if any(\n                    skip in path_str\n                    for skip in [\".rels\", \"[Content_Types]\", \"docProps/\", \"_rels/\"]\n                ):\n                    continue\n\n                try:\n                    root_tag = lxml.etree.parse(str(xml_file)).getroot().tag\n                    root_name = root_tag.split(\"}\")[-1] if \"}\" in root_tag else root_tag\n\n                    if root_name in declarable_roots and path_str not in declared_parts:\n                        errors.append(\n                            f\"  {path_str}: File with <{root_name}> root not declared in [Content_Types].xml\"\n                        )\n\n                except Exception:\n                    continue  \n\n            for file_path in all_files:\n                if file_path.suffix.lower() in {\".xml\", \".rels\"}:\n                    continue\n                if file_path.name == \"[Content_Types].xml\":\n                    continue\n                if \"_rels\" in file_path.parts or \"docProps\" in file_path.parts:\n                    continue\n\n                extension = file_path.suffix.lstrip(\".\").lower()\n                if extension and extension not in declared_extensions:\n                    if extension in media_extensions:\n                        relative_path = file_path.relative_to(self.unpacked_dir)\n                        errors.append(\n                            f'  {relative_path}: File with extension \\'{extension}\\' not declared in [Content_Types].xml - should add: <Default Extension=\"{extension}\" ContentType=\"{media_extensions[extension]}\"/>'\n                        )\n\n        except Exception as e:\n            errors.append(f\"  Error parsing [Content_Types].xml: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} content type declaration errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All content files are properly declared in [Content_Types].xml\"\n                )\n            return True\n\n    def validate_file_against_xsd(self, xml_file, verbose=False):\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n\n        is_valid, current_errors = self._validate_single_file_xsd(\n            xml_file, unpacked_dir\n        )\n\n        if is_valid is None:\n            return None, set()  \n        elif is_valid:\n            return True, set()  \n\n        original_errors = self._get_original_file_errors(xml_file)\n\n        assert current_errors is not None\n        new_errors = current_errors - original_errors\n\n        new_errors = {\n            e for e in new_errors\n            if not any(pattern in e for pattern in self.IGNORED_VALIDATION_ERRORS)\n        }\n\n        if new_errors:\n            if verbose:\n                relative_path = xml_file.relative_to(unpacked_dir)\n                print(f\"FAILED - {relative_path}: {len(new_errors)} new error(s)\")\n                for error in list(new_errors)[:3]:\n                    truncated = error[:250] + \"...\" if len(error) > 250 else error\n                    print(f\"  - {truncated}\")\n            return False, new_errors\n        else:\n            if verbose:\n                print(\n                    f\"PASSED - No new errors (original had {len(current_errors)} errors)\"\n                )\n            return True, set()\n\n    def validate_against_xsd(self):\n        new_errors = []\n        original_error_count = 0\n        valid_count = 0\n        skipped_count = 0\n\n        for xml_file in self.xml_files:\n            relative_path = str(xml_file.relative_to(self.unpacked_dir))\n            is_valid, new_file_errors = self.validate_file_against_xsd(\n                xml_file, verbose=False\n            )\n\n            if is_valid is None:\n                skipped_count += 1\n                continue\n            elif is_valid and not new_file_errors:\n                valid_count += 1\n                continue\n            elif is_valid:\n                original_error_count += 1\n                valid_count += 1\n                continue\n\n            new_errors.append(f\"  {relative_path}: {len(new_file_errors)} new error(s)\")\n            for error in list(new_file_errors)[:3]:  \n                new_errors.append(\n                    f\"    - {error[:250]}...\" if len(error) > 250 else f\"    - {error}\"\n                )\n\n        if self.verbose:\n            print(f\"Validated {len(self.xml_files)} files:\")\n            print(f\"  - Valid: {valid_count}\")\n            print(f\"  - Skipped (no schema): {skipped_count}\")\n            if original_error_count:\n                print(f\"  - With original errors (ignored): {original_error_count}\")\n            print(\n                f\"  - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith('    ')]) or 0}\"\n            )\n\n        if new_errors:\n            print(\"\\nFAILED - Found NEW validation errors:\")\n            for error in new_errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"\\nPASSED - No new XSD validation errors introduced\")\n            return True\n\n    def _get_schema_path(self, xml_file):\n        if xml_file.name in self.SCHEMA_MAPPINGS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]\n\n        if xml_file.suffix == \".rels\":\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\".rels\"]\n\n        if \"charts/\" in str(xml_file) and xml_file.name.startswith(\"chart\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"chart\"]\n\n        if \"theme/\" in str(xml_file) and xml_file.name.startswith(\"theme\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"theme\"]\n\n        if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]\n\n        return None\n\n    def _clean_ignorable_namespaces(self, xml_doc):\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        for elem in xml_copy.iter():\n            attrs_to_remove = []\n\n            for attr in elem.attrib:\n                if \"{\" in attr:\n                    ns = attr.split(\"}\")[0][1:]\n                    if ns not in self.OOXML_NAMESPACES:\n                        attrs_to_remove.append(attr)\n\n            for attr in attrs_to_remove:\n                del elem.attrib[attr]\n\n        self._remove_ignorable_elements(xml_copy)\n\n        return lxml.etree.ElementTree(xml_copy)\n\n    def _remove_ignorable_elements(self, root):\n        elements_to_remove = []\n\n        for elem in list(root):\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n\n            tag_str = str(elem.tag)\n            if tag_str.startswith(\"{\"):\n                ns = tag_str.split(\"}\")[0][1:]\n                if ns not in self.OOXML_NAMESPACES:\n                    elements_to_remove.append(elem)\n                    continue\n\n            self._remove_ignorable_elements(elem)\n\n        for elem in elements_to_remove:\n            root.remove(elem)\n\n    def _preprocess_for_mc_ignorable(self, xml_doc):\n        root = xml_doc.getroot()\n\n        if f\"{{{self.MC_NAMESPACE}}}Ignorable\" in root.attrib:\n            del root.attrib[f\"{{{self.MC_NAMESPACE}}}Ignorable\"]\n\n        return xml_doc\n\n    def _validate_single_file_xsd(self, xml_file, base_path):\n        schema_path = self._get_schema_path(xml_file)\n        if not schema_path:\n            return None, None  \n\n        try:\n            with open(schema_path, \"rb\") as xsd_file:\n                parser = lxml.etree.XMLParser()\n                xsd_doc = lxml.etree.parse(\n                    xsd_file, parser=parser, base_url=str(schema_path)\n                )\n                schema = lxml.etree.XMLSchema(xsd_doc)\n\n            with open(xml_file, \"r\") as f:\n                xml_doc = lxml.etree.parse(f)\n\n            xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)\n            xml_doc = self._preprocess_for_mc_ignorable(xml_doc)\n\n            relative_path = xml_file.relative_to(base_path)\n            if (\n                relative_path.parts\n                and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS\n            ):\n                xml_doc = self._clean_ignorable_namespaces(xml_doc)\n\n            if schema.validate(xml_doc):\n                return True, set()\n            else:\n                errors = set()\n                for error in schema.error_log:\n                    errors.add(error.message)\n                return False, errors\n\n        except Exception as e:\n            return False, {str(e)}\n\n    def _get_original_file_errors(self, xml_file):\n        if self.original_file is None:\n            return set()\n\n        import tempfile\n        import zipfile\n\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n        relative_path = xml_file.relative_to(unpacked_dir)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                zip_ref.extractall(temp_path)\n\n            original_xml_file = temp_path / relative_path\n\n            if not original_xml_file.exists():\n                return set()\n\n            is_valid, errors = self._validate_single_file_xsd(\n                original_xml_file, temp_path\n            )\n            return errors if errors else set()\n\n    def _remove_template_tags_from_text_nodes(self, xml_doc):\n        warnings = []\n        template_pattern = re.compile(r\"\\{\\{[^}]*\\}\\}\")\n\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        def process_text_content(text, content_type):\n            if not text:\n                return text\n            matches = list(template_pattern.finditer(text))\n            if matches:\n                for match in matches:\n                    warnings.append(\n                        f\"Found template tag in {content_type}: {match.group()}\"\n                    )\n                return template_pattern.sub(\"\", text)\n            return text\n\n        for elem in xml_copy.iter():\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n            tag_str = str(elem.tag)\n            if tag_str.endswith(\"}t\") or tag_str == \"t\":\n                continue\n\n            elem.text = process_text_content(elem.text, \"text content\")\n            elem.tail = process_text_content(elem.tail, \"tail content\")\n\n        return lxml.etree.ElementTree(xml_copy), warnings\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validators/docx.py",
    "content": "\"\"\"\nValidator for Word document XML files against XSD schemas.\n\"\"\"\n\nimport random\nimport re\nimport tempfile\nimport zipfile\n\nimport defusedxml.minidom\nimport lxml.etree\n\nfrom .base import BaseSchemaValidator\n\n\nclass DOCXSchemaValidator(BaseSchemaValidator):\n\n    WORD_2006_NAMESPACE = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    W14_NAMESPACE = \"http://schemas.microsoft.com/office/word/2010/wordml\"\n    W16CID_NAMESPACE = \"http://schemas.microsoft.com/office/word/2016/wordml/cid\"\n\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_whitespace_preservation():\n            all_valid = False\n\n        if not self.validate_deletions():\n            all_valid = False\n\n        if not self.validate_insertions():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_id_constraints():\n            all_valid = False\n\n        if not self.validate_comment_markers():\n            all_valid = False\n\n        self.compare_paragraph_counts()\n\n        return all_valid\n\n    def validate_whitespace_preservation(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter(f\"{{{self.WORD_2006_NAMESPACE}}}t\"):\n                    if elem.text:\n                        text = elem.text\n                        if re.search(r\"^[ \\t\\n\\r]\", text) or re.search(\n                            r\"[ \\t\\n\\r]$\", text\n                        ):\n                            xml_space_attr = f\"{{{self.XML_NAMESPACE}}}space\"\n                            if (\n                                xml_space_attr not in elem.attrib\n                                or elem.attrib[xml_space_attr] != \"preserve\"\n                            ):\n                                text_preview = (\n                                    repr(text)[:50] + \"...\"\n                                    if len(repr(text)) > 50\n                                    else repr(text)\n                                )\n                                errors.append(\n                                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                    f\"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}\"\n                                )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} whitespace preservation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All whitespace is properly preserved\")\n            return True\n\n    def validate_deletions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                for t_elem in root.xpath(\".//w:del//w:t\", namespaces=namespaces):\n                    if t_elem.text:\n                        text_preview = (\n                            repr(t_elem.text)[:50] + \"...\"\n                            if len(repr(t_elem.text)) > 50\n                            else repr(t_elem.text)\n                        )\n                        errors.append(\n                            f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}\"\n                        )\n\n                for instr_elem in root.xpath(\n                    \".//w:del//w:instrText\", namespaces=namespaces\n                ):\n                    text_preview = (\n                        repr(instr_elem.text or \"\")[:50] + \"...\"\n                        if len(repr(instr_elem.text or \"\")) > 50\n                        else repr(instr_elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {instr_elem.sourceline}: <w:instrText> found within <w:del> (use <w:delInstrText>): {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} deletion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:t elements found within w:del elements\")\n            return True\n\n    def count_paragraphs_in_unpacked(self):\n        count = 0\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n            except Exception as e:\n                print(f\"Error counting paragraphs in unpacked document: {e}\")\n\n        return count\n\n    def count_paragraphs_in_original(self):\n        original = self.original_file\n        if original is None:\n            return 0\n\n        count = 0\n\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                with zipfile.ZipFile(original, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_dir)\n\n                doc_xml_path = temp_dir + \"/word/document.xml\"\n                root = lxml.etree.parse(doc_xml_path).getroot()\n\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n\n        except Exception as e:\n            print(f\"Error counting paragraphs in original document: {e}\")\n\n        return count\n\n    def validate_insertions(self):\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                invalid_elements = root.xpath(\n                    \".//w:ins//w:delText[not(ancestor::w:del)]\", namespaces=namespaces\n                )\n\n                for elem in invalid_elements:\n                    text_preview = (\n                        repr(elem.text or \"\")[:50] + \"...\"\n                        if len(repr(elem.text or \"\")) > 50\n                        else repr(elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} insertion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:delText elements within w:ins elements\")\n            return True\n\n    def compare_paragraph_counts(self):\n        original_count = self.count_paragraphs_in_original()\n        new_count = self.count_paragraphs_in_unpacked()\n\n        diff = new_count - original_count\n        diff_str = f\"+{diff}\" if diff > 0 else str(diff)\n        print(f\"\\nParagraphs: {original_count} → {new_count} ({diff_str})\")\n\n    def _parse_id_value(self, val: str, base: int = 16) -> int:\n        return int(val, base)\n\n    def validate_id_constraints(self):\n        errors = []\n        para_id_attr = f\"{{{self.W14_NAMESPACE}}}paraId\"\n        durable_id_attr = f\"{{{self.W16CID_NAMESPACE}}}durableId\"\n\n        for xml_file in self.xml_files:\n            try:\n                for elem in lxml.etree.parse(str(xml_file)).iter():\n                    if val := elem.get(para_id_attr):\n                        if self._parse_id_value(val, base=16) >= 0x80000000:\n                            errors.append(\n                                f\"  {xml_file.name}:{elem.sourceline}: paraId={val} >= 0x80000000\"\n                            )\n\n                    if val := elem.get(durable_id_attr):\n                        if xml_file.name == \"numbering.xml\":\n                            try:\n                                if self._parse_id_value(val, base=10) >= 0x7FFFFFFF:\n                                    errors.append(\n                                        f\"  {xml_file.name}:{elem.sourceline}: \"\n                                        f\"durableId={val} >= 0x7FFFFFFF\"\n                                    )\n                            except ValueError:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} must be decimal in numbering.xml\"\n                                )\n                        else:\n                            if self._parse_id_value(val, base=16) >= 0x7FFFFFFF:\n                                errors.append(\n                                    f\"  {xml_file.name}:{elem.sourceline}: \"\n                                    f\"durableId={val} >= 0x7FFFFFFF\"\n                                )\n            except Exception:\n                pass\n\n        if errors:\n            print(f\"FAILED - {len(errors)} ID constraint violations:\")\n            for e in errors:\n                print(e)\n        elif self.verbose:\n            print(\"PASSED - All paraId/durableId values within constraints\")\n        return not errors\n\n    def validate_comment_markers(self):\n        errors = []\n\n        document_xml = None\n        comments_xml = None\n        for xml_file in self.xml_files:\n            if xml_file.name == \"document.xml\" and \"word\" in str(xml_file):\n                document_xml = xml_file\n            elif xml_file.name == \"comments.xml\":\n                comments_xml = xml_file\n\n        if not document_xml:\n            if self.verbose:\n                print(\"PASSED - No document.xml found (skipping comment validation)\")\n            return True\n\n        try:\n            doc_root = lxml.etree.parse(str(document_xml)).getroot()\n            namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n            range_starts = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeStart\", namespaces=namespaces\n                )\n            }\n            range_ends = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentRangeEnd\", namespaces=namespaces\n                )\n            }\n            references = {\n                elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                for elem in doc_root.xpath(\n                    \".//w:commentReference\", namespaces=namespaces\n                )\n            }\n\n            orphaned_ends = range_ends - range_starts\n            for comment_id in sorted(\n                orphaned_ends, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeEnd id=\"{comment_id}\" has no matching commentRangeStart'\n                )\n\n            orphaned_starts = range_starts - range_ends\n            for comment_id in sorted(\n                orphaned_starts, key=lambda x: int(x) if x and x.isdigit() else 0\n            ):\n                errors.append(\n                    f'  document.xml: commentRangeStart id=\"{comment_id}\" has no matching commentRangeEnd'\n                )\n\n            comment_ids = set()\n            if comments_xml and comments_xml.exists():\n                comments_root = lxml.etree.parse(str(comments_xml)).getroot()\n                comment_ids = {\n                    elem.get(f\"{{{self.WORD_2006_NAMESPACE}}}id\")\n                    for elem in comments_root.xpath(\n                        \".//w:comment\", namespaces=namespaces\n                    )\n                }\n\n                marker_ids = range_starts | range_ends | references\n                invalid_refs = marker_ids - comment_ids\n                for comment_id in sorted(\n                    invalid_refs, key=lambda x: int(x) if x and x.isdigit() else 0\n                ):\n                    if comment_id:  \n                        errors.append(\n                            f'  document.xml: marker id=\"{comment_id}\" references non-existent comment'\n                        )\n\n        except (lxml.etree.XMLSyntaxError, Exception) as e:\n            errors.append(f\"  Error parsing XML: {e}\")\n\n        if errors:\n            print(f\"FAILED - {len(errors)} comment marker violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All comment markers properly paired\")\n            return True\n\n    def repair(self) -> int:\n        repairs = super().repair()\n        repairs += self.repair_durableId()\n        return repairs\n\n    def repair_durableId(self) -> int:\n        repairs = 0\n\n        for xml_file in self.xml_files:\n            try:\n                content = xml_file.read_text(encoding=\"utf-8\")\n                dom = defusedxml.minidom.parseString(content)\n                modified = False\n\n                for elem in dom.getElementsByTagName(\"*\"):\n                    if not elem.hasAttribute(\"w16cid:durableId\"):\n                        continue\n\n                    durable_id = elem.getAttribute(\"w16cid:durableId\")\n                    needs_repair = False\n\n                    if xml_file.name == \"numbering.xml\":\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=10) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n                    else:\n                        try:\n                            needs_repair = (\n                                self._parse_id_value(durable_id, base=16) >= 0x7FFFFFFF\n                            )\n                        except ValueError:\n                            needs_repair = True\n\n                    if needs_repair:\n                        value = random.randint(1, 0x7FFFFFFE)\n                        if xml_file.name == \"numbering.xml\":\n                            new_id = str(value)  \n                        else:\n                            new_id = f\"{value:08X}\"  \n\n                        elem.setAttribute(\"w16cid:durableId\", new_id)\n                        print(\n                            f\"  Repaired: {xml_file.name}: durableId {durable_id} → {new_id}\"\n                        )\n                        repairs += 1\n                        modified = True\n\n                if modified:\n                    xml_file.write_bytes(dom.toxml(encoding=\"UTF-8\"))\n\n            except Exception:\n                pass\n\n        return repairs\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validators/pptx.py",
    "content": "\"\"\"\nValidator for PowerPoint presentation XML files against XSD schemas.\n\"\"\"\n\nimport re\n\nfrom .base import BaseSchemaValidator\n\n\nclass PPTXSchemaValidator(BaseSchemaValidator):\n\n    PRESENTATIONML_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\"\n    )\n\n    ELEMENT_RELATIONSHIP_TYPES = {\n        \"sldid\": \"slide\",\n        \"sldmasterid\": \"slidemaster\",\n        \"notesmasterid\": \"notesmaster\",\n        \"sldlayoutid\": \"slidelayout\",\n        \"themeid\": \"theme\",\n        \"tablestyleid\": \"tablestyles\",\n    }\n\n    def validate(self):\n        if not self.validate_xml():\n            return False\n\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        if not self.validate_uuid_ids():\n            all_valid = False\n\n        if not self.validate_file_references():\n            all_valid = False\n\n        if not self.validate_slide_layout_ids():\n            all_valid = False\n\n        if not self.validate_content_types():\n            all_valid = False\n\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        if not self.validate_notes_slide_references():\n            all_valid = False\n\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        if not self.validate_no_duplicate_slide_layouts():\n            all_valid = False\n\n        return all_valid\n\n    def validate_uuid_ids(self):\n        import lxml.etree\n\n        errors = []\n        uuid_pattern = re.compile(\n            r\"^[\\{\\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\\}\\)]?$\"\n        )\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                for elem in root.iter():\n                    for attr, value in elem.attrib.items():\n                        attr_name = attr.split(\"}\")[-1].lower()\n                        if attr_name == \"id\" or attr_name.endswith(\"id\"):\n                            if self._looks_like_uuid(value):\n                                if not uuid_pattern.match(value):\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters\"\n                                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} UUID ID validation errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All UUID-like IDs contain valid hex values\")\n            return True\n\n    def _looks_like_uuid(self, value):\n        clean_value = value.strip(\"{}()\").replace(\"-\", \"\")\n        return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)\n\n    def validate_slide_layout_ids(self):\n        import lxml.etree\n\n        errors = []\n\n        slide_masters = list(self.unpacked_dir.glob(\"ppt/slideMasters/*.xml\"))\n\n        if not slide_masters:\n            if self.verbose:\n                print(\"PASSED - No slide masters found\")\n            return True\n\n        for slide_master in slide_masters:\n            try:\n                root = lxml.etree.parse(str(slide_master)).getroot()\n\n                rels_file = slide_master.parent / \"_rels\" / f\"{slide_master.name}.rels\"\n\n                if not rels_file.exists():\n                    errors.append(\n                        f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                        f\"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}\"\n                    )\n                    continue\n\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                valid_layout_rids = set()\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"slideLayout\" in rel_type:\n                        valid_layout_rids.add(rel.get(\"Id\"))\n\n                for sld_layout_id in root.findall(\n                    f\".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId\"\n                ):\n                    r_id = sld_layout_id.get(\n                        f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\"\n                    )\n                    layout_id = sld_layout_id.get(\"id\")\n\n                    if r_id and r_id not in valid_layout_rids:\n                        errors.append(\n                            f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' \"\n                            f\"references r:id='{r_id}' which is not found in slide layout relationships\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {slide_master.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} slide layout ID validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"Remove invalid references or add missing slide layouts to the relationships file.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slide layout IDs reference valid slide layouts\")\n            return True\n\n    def validate_no_duplicate_slide_layouts(self):\n        import lxml.etree\n\n        errors = []\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                layout_rels = [\n                    rel\n                    for rel in root.findall(\n                        f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                    )\n                    if \"slideLayout\" in rel.get(\"Type\", \"\")\n                ]\n\n                if len(layout_rels) > 1:\n                    errors.append(\n                        f\"  {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references\"\n                    )\n\n            except Exception as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(\"FAILED - Found slides with duplicate slideLayout references:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slides have exactly one slideLayout reference\")\n            return True\n\n    def validate_notes_slide_references(self):\n        import lxml.etree\n\n        errors = []\n        notes_slide_references = {}  \n\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        if not slide_rels_files:\n            if self.verbose:\n                print(\"PASSED - No slide relationship files found\")\n            return True\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                for rel in root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"notesSlide\" in rel_type:\n                        target = rel.get(\"Target\", \"\")\n                        if target:\n                            normalized_target = target.replace(\"../\", \"\")\n\n                            slide_name = rels_file.stem.replace(\n                                \".xml\", \"\"\n                            )  \n\n                            if normalized_target not in notes_slide_references:\n                                notes_slide_references[normalized_target] = []\n                            notes_slide_references[normalized_target].append(\n                                (slide_name, rels_file)\n                            )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        for target, references in notes_slide_references.items():\n            if len(references) > 1:\n                slide_names = [ref[0] for ref in references]\n                errors.append(\n                    f\"  Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}\"\n                )\n                for slide_name, rels_file in references:\n                    errors.append(f\"    - {rels_file.relative_to(self.unpacked_dir)}\")\n\n        if errors:\n            print(\n                f\"FAILED - Found {len([e for e in errors if not e.startswith('    ')])} notes slide reference validation errors:\"\n            )\n            for error in errors:\n                print(error)\n            print(\"Each slide may optionally have its own slide file.\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All notes slide references are unique\")\n            return True\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/xlsx/scripts/office/validators/redlining.py",
    "content": "\"\"\"\nValidator for tracked changes in Word documents.\n\"\"\"\n\nimport subprocess\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\n\nclass RedliningValidator:\n\n    def __init__(self, unpacked_dir, original_docx, verbose=False, author=\"Claude\"):\n        self.unpacked_dir = Path(unpacked_dir)\n        self.original_docx = Path(original_docx)\n        self.verbose = verbose\n        self.author = author\n        self.namespaces = {\n            \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n        }\n\n    def repair(self) -> int:\n        return 0\n\n    def validate(self):\n        modified_file = self.unpacked_dir / \"word\" / \"document.xml\"\n        if not modified_file.exists():\n            print(f\"FAILED - Modified document.xml not found at {modified_file}\")\n            return False\n\n        try:\n            import xml.etree.ElementTree as ET\n\n            tree = ET.parse(modified_file)\n            root = tree.getroot()\n\n            del_elements = root.findall(\".//w:del\", self.namespaces)\n            ins_elements = root.findall(\".//w:ins\", self.namespaces)\n\n            author_del_elements = [\n                elem\n                for elem in del_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n            author_ins_elements = [\n                elem\n                for elem in ins_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == self.author\n            ]\n\n            if not author_del_elements and not author_ins_elements:\n                if self.verbose:\n                    print(f\"PASSED - No tracked changes by {self.author} found.\")\n                return True\n\n        except Exception:\n            pass\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            try:\n                with zipfile.ZipFile(self.original_docx, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_path)\n            except Exception as e:\n                print(f\"FAILED - Error unpacking original docx: {e}\")\n                return False\n\n            original_file = temp_path / \"word\" / \"document.xml\"\n            if not original_file.exists():\n                print(\n                    f\"FAILED - Original document.xml not found in {self.original_docx}\"\n                )\n                return False\n\n            try:\n                import xml.etree.ElementTree as ET\n\n                modified_tree = ET.parse(modified_file)\n                modified_root = modified_tree.getroot()\n                original_tree = ET.parse(original_file)\n                original_root = original_tree.getroot()\n            except ET.ParseError as e:\n                print(f\"FAILED - Error parsing XML files: {e}\")\n                return False\n\n            self._remove_author_tracked_changes(original_root)\n            self._remove_author_tracked_changes(modified_root)\n\n            modified_text = self._extract_text_content(modified_root)\n            original_text = self._extract_text_content(original_root)\n\n            if modified_text != original_text:\n                error_message = self._generate_detailed_diff(\n                    original_text, modified_text\n                )\n                print(error_message)\n                return False\n\n            if self.verbose:\n                print(f\"PASSED - All changes by {self.author} are properly tracked\")\n            return True\n\n    def _generate_detailed_diff(self, original_text, modified_text):\n        error_parts = [\n            f\"FAILED - Document text doesn't match after removing {self.author}'s tracked changes\",\n            \"\",\n            \"Likely causes:\",\n            \"  1. Modified text inside another author's <w:ins> or <w:del> tags\",\n            \"  2. Made edits without proper tracked changes\",\n            \"  3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion\",\n            \"\",\n            \"For pre-redlined documents, use correct patterns:\",\n            \"  - To reject another's INSERTION: Nest <w:del> inside their <w:ins>\",\n            \"  - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>\",\n            \"\",\n        ]\n\n        git_diff = self._get_git_word_diff(original_text, modified_text)\n        if git_diff:\n            error_parts.extend([\"Differences:\", \"============\", git_diff])\n        else:\n            error_parts.append(\"Unable to generate word diff (git not available)\")\n\n        return \"\\n\".join(error_parts)\n\n    def _get_git_word_diff(self, original_text, modified_text):\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                temp_path = Path(temp_dir)\n\n                original_file = temp_path / \"original.txt\"\n                modified_file = temp_path / \"modified.txt\"\n\n                original_file.write_text(original_text, encoding=\"utf-8\")\n                modified_file.write_text(modified_text, encoding=\"utf-8\")\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"--word-diff-regex=.\",  \n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n\n                    if content_lines:\n                        return \"\\n\".join(content_lines)\n\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"-U0\",  \n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n                    return \"\\n\".join(content_lines)\n\n        except (subprocess.CalledProcessError, FileNotFoundError, Exception):\n            pass\n\n        return None\n\n    def _remove_author_tracked_changes(self, root):\n        ins_tag = f\"{{{self.namespaces['w']}}}ins\"\n        del_tag = f\"{{{self.namespaces['w']}}}del\"\n        author_attr = f\"{{{self.namespaces['w']}}}author\"\n\n        for parent in root.iter():\n            to_remove = []\n            for child in parent:\n                if child.tag == ins_tag and child.get(author_attr) == self.author:\n                    to_remove.append(child)\n            for elem in to_remove:\n                parent.remove(elem)\n\n        deltext_tag = f\"{{{self.namespaces['w']}}}delText\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        for parent in root.iter():\n            to_process = []\n            for child in parent:\n                if child.tag == del_tag and child.get(author_attr) == self.author:\n                    to_process.append((child, list(parent).index(child)))\n\n            for del_elem, del_index in reversed(to_process):\n                for elem in del_elem.iter():\n                    if elem.tag == deltext_tag:\n                        elem.tag = t_tag\n\n                for child in reversed(list(del_elem)):\n                    parent.insert(del_index, child)\n                parent.remove(del_elem)\n\n    def _extract_text_content(self, root):\n        p_tag = f\"{{{self.namespaces['w']}}}p\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        paragraphs = []\n        for p_elem in root.findall(f\".//{p_tag}\"):\n            text_parts = []\n            for t_elem in p_elem.findall(f\".//{t_tag}\"):\n                if t_elem.text:\n                    text_parts.append(t_elem.text)\n            paragraph_text = \"\".join(text_parts)\n            if paragraph_text:\n                paragraphs.append(paragraph_text)\n\n        return \"\\n\".join(paragraphs)\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "skills/xlsx/scripts/recalc.py",
    "content": "\"\"\"\nExcel Formula Recalculation Script\nRecalculates all formulas in an Excel file using LibreOffice\n\"\"\"\n\nimport json\nimport os\nimport platform\nimport subprocess\nimport sys\nfrom pathlib import Path\n\nfrom office.soffice import get_soffice_env\n\nfrom openpyxl import load_workbook\n\nMACRO_DIR_MACOS = \"~/Library/Application Support/LibreOffice/4/user/basic/Standard\"\nMACRO_DIR_LINUX = \"~/.config/libreoffice/4/user/basic/Standard\"\nMACRO_FILENAME = \"Module1.xba\"\n\nRECALCULATE_MACRO = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE script:module PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"module.dtd\">\n<script:module xmlns:script=\"http://openoffice.org/2000/script\" script:name=\"Module1\" script:language=\"StarBasic\">\n    Sub RecalculateAndSave()\n      ThisComponent.calculateAll()\n      ThisComponent.store()\n      ThisComponent.close(True)\n    End Sub\n</script:module>\"\"\"\n\n\ndef has_gtimeout():\n    try:\n        subprocess.run(\n            [\"gtimeout\", \"--version\"], capture_output=True, timeout=1, check=False\n        )\n        return True\n    except (FileNotFoundError, subprocess.TimeoutExpired):\n        return False\n\n\ndef setup_libreoffice_macro():\n    macro_dir = os.path.expanduser(\n        MACRO_DIR_MACOS if platform.system() == \"Darwin\" else MACRO_DIR_LINUX\n    )\n    macro_file = os.path.join(macro_dir, MACRO_FILENAME)\n\n    if (\n        os.path.exists(macro_file)\n        and \"RecalculateAndSave\" in Path(macro_file).read_text()\n    ):\n        return True\n\n    if not os.path.exists(macro_dir):\n        subprocess.run(\n            [\"soffice\", \"--headless\", \"--terminate_after_init\"],\n            capture_output=True,\n            timeout=10,\n            env=get_soffice_env(),\n        )\n        os.makedirs(macro_dir, exist_ok=True)\n\n    try:\n        Path(macro_file).write_text(RECALCULATE_MACRO)\n        return True\n    except Exception:\n        return False\n\n\ndef recalc(filename, timeout=30):\n    if not Path(filename).exists():\n        return {\"error\": f\"File {filename} does not exist\"}\n\n    abs_path = str(Path(filename).absolute())\n\n    if not setup_libreoffice_macro():\n        return {\"error\": \"Failed to setup LibreOffice macro\"}\n\n    cmd = [\n        \"soffice\",\n        \"--headless\",\n        \"--norestore\",\n        \"vnd.sun.star.script:Standard.Module1.RecalculateAndSave?language=Basic&location=application\",\n        abs_path,\n    ]\n\n    if platform.system() == \"Linux\":\n        cmd = [\"timeout\", str(timeout)] + cmd\n    elif platform.system() == \"Darwin\" and has_gtimeout():\n        cmd = [\"gtimeout\", str(timeout)] + cmd\n\n    result = subprocess.run(cmd, capture_output=True, text=True, env=get_soffice_env())\n\n    if result.returncode != 0 and result.returncode != 124:  \n        error_msg = result.stderr or \"Unknown error during recalculation\"\n        if \"Module1\" in error_msg or \"RecalculateAndSave\" not in error_msg:\n            return {\"error\": \"LibreOffice macro not configured properly\"}\n        return {\"error\": error_msg}\n\n    try:\n        wb = load_workbook(filename, data_only=True)\n\n        excel_errors = [\n            \"#VALUE!\",\n            \"#DIV/0!\",\n            \"#REF!\",\n            \"#NAME?\",\n            \"#NULL!\",\n            \"#NUM!\",\n            \"#N/A\",\n        ]\n        error_details = {err: [] for err in excel_errors}\n        total_errors = 0\n\n        for sheet_name in wb.sheetnames:\n            ws = wb[sheet_name]\n            for row in ws.iter_rows():\n                for cell in row:\n                    if cell.value is not None and isinstance(cell.value, str):\n                        for err in excel_errors:\n                            if err in cell.value:\n                                location = f\"{sheet_name}!{cell.coordinate}\"\n                                error_details[err].append(location)\n                                total_errors += 1\n                                break\n\n        wb.close()\n\n        result = {\n            \"status\": \"success\" if total_errors == 0 else \"errors_found\",\n            \"total_errors\": total_errors,\n            \"error_summary\": {},\n        }\n\n        for err_type, locations in error_details.items():\n            if locations:\n                result[\"error_summary\"][err_type] = {\n                    \"count\": len(locations),\n                    \"locations\": locations[:20],  \n                }\n\n        wb_formulas = load_workbook(filename, data_only=False)\n        formula_count = 0\n        for sheet_name in wb_formulas.sheetnames:\n            ws = wb_formulas[sheet_name]\n            for row in ws.iter_rows():\n                for cell in row:\n                    if (\n                        cell.value\n                        and isinstance(cell.value, str)\n                        and cell.value.startswith(\"=\")\n                    ):\n                        formula_count += 1\n        wb_formulas.close()\n\n        result[\"total_formulas\"] = formula_count\n\n        return result\n\n    except Exception as e:\n        return {\"error\": str(e)}\n\n\ndef main():\n    if len(sys.argv) < 2:\n        print(\"Usage: python recalc.py <excel_file> [timeout_seconds]\")\n        print(\"\\nRecalculates all formulas in an Excel file using LibreOffice\")\n        print(\"\\nReturns JSON with error details:\")\n        print(\"  - status: 'success' or 'errors_found'\")\n        print(\"  - total_errors: Total number of Excel errors found\")\n        print(\"  - total_formulas: Number of formulas in the file\")\n        print(\"  - error_summary: Breakdown by error type with locations\")\n        print(\"    - #VALUE!, #DIV/0!, #REF!, #NAME?, #NULL!, #NUM!, #N/A\")\n        sys.exit(1)\n\n    filename = sys.argv[1]\n    timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 30\n\n    result = recalc(filename, timeout)\n    print(json.dumps(result, indent=2))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "start.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nMLA V3 启动脚本\n使用新的XML结构化上下文系统\n\"\"\"\n\nimport sys\nimport argparse\nfrom pathlib import Path\nimport os\nfrom datetime import datetime\nimport json\nimport threading\n\n# Windows控制台UTF-8编码支持（解决emoji显示问题）\nif sys.platform == 'win32':\n    try:\n        # 设置控制台代码页为UTF-8\n        import codecs\n        # 使用line buffering确保每行立即输出\n        sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')\n        sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict')\n        # 强制无缓冲模式\n        import io\n        sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', line_buffering=True, write_through=True)\n        sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', line_buffering=True, write_through=True)\n    except Exception:\n        pass\n\n# 首次导入时检查PATH配置（仅在非导入模式下）\nif __name__ == \"__main__\" and not hasattr(sys, '_mla_path_checked'):\n    sys._mla_path_checked = True\n    try:\n        import site\n        # 获取用户级 Scripts 目录\n        if sys.platform == 'win32':\n            user_base = site.USER_BASE\n            if user_base:\n                scripts_dir = os.path.join(user_base, 'Scripts')\n            else:\n                scripts_dir = None\n        else:\n            user_base = site.USER_BASE\n            if user_base:\n                scripts_dir = os.path.join(user_base, 'bin')\n            else:\n                scripts_dir = None\n        \n        if scripts_dir and os.path.exists(scripts_dir):\n            # 检查是否在 PATH 中\n            path_env = os.environ.get('PATH', '')\n            path_dirs = path_env.split(os.pathsep)\n            scripts_dir_normalized = os.path.normpath(scripts_dir).lower()\n            in_path = any(os.path.normpath(p).lower() == scripts_dir_normalized for p in path_dirs)\n            \n            if not in_path:\n                print(\"\\n\" + \"=\"*80, file=sys.stderr)\n                print(\"[提示] 要直接使用 'mla-agent' 命令，请运行: python check_path.py\", file=sys.stderr)\n                print(\"=\"*80 + \"\\n\", file=sys.stderr)\n    except Exception:\n        pass\n\n# 添加项目根目录到路径\nproject_root = Path(__file__).parent\nsys.path.insert(0, str(project_root))\n\n\ndef _configure_packaged_playwright_runtime() -> None:\n    \"\"\"在打包后的后端中优先使用 bundle 内置的 Playwright 浏览器。\"\"\"\n    try:\n        if not getattr(sys, \"frozen\", False):\n            return\n        bundle_root = Path(sys.executable).resolve().parent\n        bundled_browsers = (\n            bundle_root\n            / \"_internal\"\n            / \"playwright\"\n            / \"driver\"\n            / \"package\"\n            / \".local-browsers\"\n        )\n        if bundled_browsers.exists():\n            os.environ[\"PLAYWRIGHT_BROWSERS_PATH\"] = str(bundled_browsers)\n    except Exception:\n        return\n\n\n_configure_packaged_playwright_runtime()\n\nfrom utils.user_paths import apply_runtime_env_defaults, get_user_data_root\nfrom utils.runtime_control import get_running_task, request_fresh\nfrom utils.config_loader import ConfigLoader\nfrom core.hierarchy_manager import get_hierarchy_manager\nfrom core.agent_executor import AgentExecutor\n\n# 统一运行时默认环境：用户目录配置 / agent_library / skills_library / command_mode\napply_runtime_env_defaults()\n\n\ndef main():\n    \"\"\"主函数\"\"\"\n    import time\n    import uuid\n    \n    # 解析命令行参数\n    parser = argparse.ArgumentParser(description='MLA V3 - Multi-Level Agent System')\n    \n    # 主命令参数\n    parser.add_argument('--task_id', type=str, help='任务ID（绝对路径，作为workspace）')\n    parser.add_argument('--agent_system', type=str, default='Researcher', help='Agent系统名称')\n    #parser.add_argument('--agent_system', type=str, default='Test_agent', help='Agent系统名称')\n    parser.add_argument('--agent_name', type=str, default='alpha_agent', help='启动的Agent名称')\n    parser.add_argument('--user_input', type=str, help='用户输入/任务描述')\n    parser.add_argument('--jsonl', action='store_true', help='启用 JSONL 事件输出模式（用于 VS Code 插件集成）')\n    parser.add_argument('--cli', action='store_true', help='启动交互式 CLI 模式')\n    parser.add_argument('--test', action='store_true', help='运行默认测试任务')\n    parser.add_argument('--config-show', action='store_true', help='显示当前配置')\n    parser.add_argument('--config-set', nargs=2, metavar=('KEY', 'VALUE'), help='设置配置项（如 api_key \"YOUR_KEY\"）')\n    parser.add_argument('--config-file', type=str, help='使用自定义配置文件路径')\n    parser.add_argument('--force-new', action='store_true', help='强制清空所有状态，开始新任务')\n    parser.add_argument('--auto-mode', type=str, choices=['true', 'false'], help='工具执行模式：true=自动执行，false=需要确认')\n    parser.add_argument('--direct-tools', action='store_true', help='兼容旧参数；当前后端始终使用进程内 direct-tools 模式')\n    \n    args = parser.parse_args()\n    \n    # Windows命令行参数编码修复\n    if sys.platform == 'win32' and args.user_input:\n        try:\n            # 尝试修复Windows命令行的编码问题\n            # 场景：Windows cmd/PowerShell 可能将 UTF-8 字符错误解析为 Latin-1\n            original = args.user_input\n            fixed = args.user_input.encode('latin-1').decode('utf-8')\n            # 只在修复后看起来更合理时才应用（避免破坏正常输入）\n            if fixed != original:\n                args.user_input = fixed\n        except (UnicodeDecodeError, UnicodeEncodeError, AttributeError) as e:\n            # 如果修复失败，保持原样（不影响正常使用）\n            # 可选：记录日志用于调试\n            # print(f\"[调试] 编码修复失败: {e}\", file=sys.stderr)\n            pass\n    \n    # 处理 CLI 模式\n    if args.cli:\n        from utils.cli_mode import start_cli_mode\n        # 不传入 agent_system，让用户在 CLI 中选择\n        start_cli_mode()\n        return 0\n    \n    # 处理配置命令（优先）\n    if args.config_show:\n        from utils.config_manager import show_config\n        show_config()\n        return 0\n    \n    if args.config_set:\n        from utils.config_manager import set_config\n        set_config(args.config_set[0], args.config_set[1])\n        return 0\n    \n    # 初始化事件发射器\n    from utils.event_emitter import init_event_emitter\n    emitter = init_event_emitter(enabled=args.jsonl)\n    \n    # JSONL 模式：将所有 print 重定向到 stderr\n    if args.jsonl:\n        sys.stdout_orig = sys.stdout\n        sys.stderr_orig = sys.stderr\n        # 所有 print 输出到 stderr\n        sys.stdout = sys.stderr\n\n    # 桌面端（JSONL）无感 HIL 交互：从 stdin 接收前端回复并写回 HIL 任务\n    #\n    # 约定：Electron 主进程通过 stdin 写入一行 JSON：\n    #   {\"type\":\"hil_response\",\"hil_id\":\"...\",\"response\":\"...\"}\n    # 本进程在 direct-tools 模式下会在同一进程内维护 HIL_TASKS，收到回复后直接 respond_hil_task 即可让 human_in_loop 工具继续执行。\n    def _start_stdin_control_thread():\n        try:\n            from tool_server_lite.tools.human_tools import respond_hil_task, respond_tool_confirmation\n        except Exception:\n            respond_hil_task = None\n            respond_tool_confirmation = None\n        \n        def _worker():\n            if respond_hil_task is None and respond_tool_confirmation is None:\n                return\n            try:\n                for line in sys.stdin:\n                    line = (line or \"\").strip()\n                    if not line:\n                        continue\n                    try:\n                        msg = json.loads(line)\n                    except Exception:\n                        continue\n                    if not isinstance(msg, dict):\n                        continue\n                    msg_type = (msg.get(\"type\") or \"\").strip()\n                    if msg_type == \"hil_response\" and respond_hil_task is not None:\n                        hil_id = (msg.get(\"hil_id\") or \"\").strip()\n                        response = msg.get(\"response\")\n                        if not hil_id or response is None:\n                            continue\n                        try:\n                            respond_hil_task(hil_id, str(response))\n                        except Exception:\n                            continue\n                    elif msg_type == \"tool_confirmation_response\" and respond_tool_confirmation is not None:\n                        confirm_id = (msg.get(\"confirm_id\") or \"\").strip()\n                        approved = msg.get(\"approved\")\n                        if not confirm_id or approved is None:\n                            continue\n                        try:\n                            respond_tool_confirmation(confirm_id, bool(approved))\n                        except Exception:\n                            continue\n                    elif msg_type == \"fresh_request\":\n                        reason = msg.get(\"reason\") or \"\"\n                        target_task_id = msg.get(\"task_id\") or args.task_id\n                        try:\n                            request_fresh(\n                                reason=str(reason),\n                                task_id=str(target_task_id) if target_task_id else None\n                            )\n                        except Exception:\n                            continue\n            except Exception:\n                # 控制通道异常不应影响主流程\n                return\n        \n        t = threading.Thread(target=_worker, daemon=True)\n        t.start()\n\n    if args.jsonl:\n        _start_stdin_control_thread()\n    \n    # 如果没有提供参数或指定了--test，使用默认测试\n    if args.test or (not args.task_id and not args.user_input):\n        if not args.jsonl:\n            print(\"🧪 使用默认测试模式\")\n        # 跨平台默认task_id：使用用户主目录下的测试目录\n        default_task_dir = get_user_data_root() / \"task_test\"\n        default_task_dir.mkdir(parents=True, exist_ok=True)\n        args.task_id = args.task_id or str(default_task_dir)\n        args.user_input = args.user_input or \"刚才完成了什么任务？\"\n    \n    # 检查必需参数\n    if not args.task_id or not args.user_input:\n        parser.error(\"需要提供 --task_id 和 --user_input，或使用 --test 运行默认测试\")\n        return 1\n\n    running_meta = get_running_task(args.task_id)\n    if running_meta:\n        print(f\"❌ 任务已在运行: {args.task_id} (pid={running_meta.get('pid')})\")\n        return 2\n    \n    # 生成 call_id\n    call_id = f\"c-{int(time.time())}-{uuid.uuid4().hex[:6]}\"\n    t0 = time.time()\n    \n    # 发送开始事件\n    if args.jsonl:\n        emitter.start(call_id, args.task_id, args.agent_name, args.user_input)\n    else:\n        print(\"\\n\" + \"=\"*100)\n        print(\"🚀 MLA V3 - Multi-Level Agent System\")\n        print(\"=\"*100)\n        print(f\"📋 任务ID: {args.task_id}\")\n        print(f\"🎛️  Agent系统: {args.agent_system}\")\n        print(f\"🤖 启动Agent: {args.agent_name}\")\n        print(f\"📝 用户输入: {args.user_input}\")\n        print(\"=\"*100 + \"\\n\")\n    \n    try:\n        # 初始化配置加载器\n        if args.jsonl:\n            emitter.token(\"加载配置...\")\n        else:\n            print(\"📦 加载配置...\")\n        \n        config_loader = ConfigLoader(args.agent_system)\n        \n        if args.jsonl:\n            emitter.token(f\"配置加载成功，共 {len(config_loader.all_tools)} 个工具/Agent\")\n            emitter.progress(\"init\", 10)\n        else:\n            print(f\"✅ 配置加载成功，共 {len(config_loader.all_tools)} 个工具/Agent\")\n        \n        # 初始化层级管理器\n        if not args.jsonl:\n            print(\"\\n📊 初始化层级管理器...\")\n        hierarchy_manager = get_hierarchy_manager(args.task_id)\n        if not args.jsonl:\n            print(\"✅ 层级管理器初始化成功\")\n        \n        # 启动前清理状态\n        if not args.jsonl:\n            print(\"\\n🧹 检查并清理状态...\")\n\n        # 重要：必须先清理，再注册本次用户指令\n        # 否则 clean_before_start() 会把“刚写入的本次指令”误判为 last_input，导致 is_same_task 恒为 True，\n        # 进而不会按“新任务”清空栈，留下上一轮中断的栈条目，造成任务结束后 stack 仍不为空。\n        if args.force_new:\n            if not args.jsonl:\n                print(\"🗑️  --force-new: 清空所有状态，开始新任务\")\n            context = hierarchy_manager._load_context()\n            context[\"current\"] = {\n                \"instructions\": [],\n                \"hierarchy\": {},\n                \"agents_status\": {},\n                \"start_time\": datetime.now().isoformat(),\n                \"last_updated\": datetime.now().isoformat()\n            }\n            # 保留全局 history/agent_time_history 等其他字段不动\n            hierarchy_manager._save_context(context)\n            hierarchy_manager._save_stack([])\n        else:\n            from core.state_cleaner import clean_before_start\n            clean_before_start(args.task_id, args.user_input)\n\n        # 注册用户指令（清理后写入）\n        if not args.jsonl:\n            print(f\"\\n📝 注册用户指令...\")\n        instruction_id = hierarchy_manager.start_new_instruction(args.user_input)\n        if not args.jsonl:\n            print(f\"✅ 指令已注册: {instruction_id}\")\n        \n        # 获取Agent配置\n        if not args.jsonl:\n            print(f\"\\n🔍 查找Agent配置: {args.agent_name}\")\n        agent_config = config_loader.get_tool_config(args.agent_name)\n        \n        if agent_config.get(\"type\") != \"llm_call_agent\":\n            error_msg = f\"❌ 错误: {args.agent_name} 不是一个LLM Agent\"\n            if args.jsonl:\n                emitter.error(error_msg)\n            else:\n                print(error_msg)\n            return\n        \n        if not args.jsonl:\n            print(f\"✅ Agent配置加载成功\")\n            print(f\"   - Level: {agent_config.get('level', 'unknown')}\")\n            print(f\"   - Execution Model: {agent_config.get('execution_model') or agent_config.get('model_type', 'unknown')}\")\n            print(f\"   - Tools: {len(agent_config.get('available_tools', []))}\")\n            \n            # 创建并运行Agent\n            print(f\"\\n{'='*100}\")\n            print(\"▶️  开始执行任务\")\n            print(f\"{'='*100}\\n\")\n        \n        \n        \n        agent = AgentExecutor(\n            agent_name=args.agent_name,\n            agent_config=agent_config,\n            config_loader=config_loader,\n            hierarchy_manager=hierarchy_manager,\n            direct_tools=getattr(args, 'direct_tools', False)\n        )\n        \n        # 设置工具执行权限模式\n        if args.auto_mode is not None:\n            auto_mode = args.auto_mode == 'true'\n            agent.tool_executor.set_task_permission(args.task_id, auto_mode)\n        \n        result = agent.run(args.task_id, args.user_input)\n        \n        # 输出结果\n        if args.jsonl:\n            # JSONL 模式 - 发送 result 和 end 事件（完整输出）\n            ok = result.get('status') == 'success'\n            summary = result.get('output', '')  # 不截断\n            emitter.result(ok, summary)\n            emitter.end(\"ok\" if ok else \"error\")\n        else:\n            # 普通模式\n            print(f\"\\n{'='*100}\")\n            print(\"📊 执行结果\")\n            print(f\"{'='*100}\")\n            print(f\"状态: {result.get('status', 'unknown')}\")\n            print(f\"输出: {result.get('output', 'N/A')}\")\n            if result.get('error_information'):\n                print(f\"错误信息: {result.get('error_information')}\")\n            print(f\"{'='*100}\\n\")\n        \n        # 返回状态码\n        if result.get('status') == 'success':\n            return 0\n        else:\n            return 1\n    \n    except KeyboardInterrupt:\n        print(\"\\n\\n⚠️  用户中断执行\")\n        return 130\n    \n    except Exception as e:\n        if args.jsonl:\n            emitter.error(str(e))\n            emitter.end(\"error\")\n        else:\n            print(f\"\\n\\n❌ 执行失败: {e}\")\n            import traceback\n            traceback.print_exc()\n        return 1\n\n\nif __name__ == \"__main__\":\n    exit_code = main()\n    sys.exit(exit_code)\n"
  },
  {
    "path": "tests/image_read.py",
    "content": "import base64\nfrom pathlib import Path\n\ndef main(img_path):\n    print('hihi')\n    img_path = Path(img_path)\n    print(img_path)\n    if True: # 读取并编码图片\n        with open(img_path, \"rb\") as image_file:\n            image_data = base64.b64encode(image_file.read()).decode('utf-8')\n        \n        # 判断图片格式\n        suffix = img_path.suffix.lower()\n        mime_type_map = {\n            '.jpg': 'image/jpeg',\n            '.jpeg': 'image/jpeg',\n            '.png': 'image/png',\n            '.gif': 'image/gif',\n            '.webp': 'image/webp'\n        }\n        mime_type = mime_type_map.get(suffix, 'image/jpeg')\n    print(image_data)\n\n\nif __name__ == '__main__':\n    # 使用脚本所在目录作为基准路径\n    script_dir = Path(__file__).parent\n    img_path = script_dir / 'current.png'\n    main(img_path)"
  },
  {
    "path": "tests/llm_config_dummy.yaml",
    "content": "temperature: 0\nmax_tokens: 0\nmax_context_window: 200000\nbase_url: \"http://127.0.0.1:1\"\napi_key: \"DUMMY_KEY_FOR_DEBUG\"\ntimeout: 5\nstream_timeout: 5\nfirst_chunk_timeout: 5\nmodels:\n  - openai/gpt-4o-mini\nmultimodal: false\ncompressor_multimodal: false\n\n"
  },
  {
    "path": "tests/test_cheapclaw_service.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport importlib.util\nimport json\nimport os\nimport shutil\nimport signal\nimport sys\nimport tempfile\nimport time\nimport unittest\nimport warnings\nfrom datetime import datetime\nfrom pathlib import Path\nfrom unittest import mock\n\nfrom core.hierarchy_manager import get_hierarchy_manager\nfrom utils.config_loader import ConfigLoader\nfrom tool_server_lite.registry import reload_runtime_registry\nfrom utils.user_paths import runtime_env_scope\n\nMODULE_PATH = Path(__file__).resolve().parent.parent / \"apps\" / \"cheapclaw\" / \"cheapclaw_service.py\"\nSPEC = importlib.util.spec_from_file_location(\"cheapclaw_service\", MODULE_PATH)\nCHEAPCLAW = importlib.util.module_from_spec(SPEC)\nassert SPEC and SPEC.loader\nsys.modules[SPEC.name] = CHEAPCLAW\nSPEC.loader.exec_module(CHEAPCLAW)\n\nCheapClawPanelStore = CHEAPCLAW.CheapClawPanelStore\nCheapClawPaths = CHEAPCLAW.CheapClawPaths\nCheapClawService = CHEAPCLAW.CheapClawService\nTelegramAdapter = CHEAPCLAW.TelegramAdapter\nHELPER_SPEC = importlib.util.spec_from_file_location(\n    \"cheapclaw_list_conversation_tasks_tool\",\n    Path(__file__).resolve().parent.parent / \"apps\" / \"cheapclaw\" / \"tools_library\" / \"cheapclaw_list_conversation_tasks\" / \"cheapclaw_list_conversation_tasks.py\",\n)\nHELPER_MODULE = importlib.util.module_from_spec(HELPER_SPEC)\nassert HELPER_SPEC and HELPER_SPEC.loader\nsys.modules[HELPER_SPEC.name] = HELPER_MODULE\nHELPER_SPEC.loader.exec_module(HELPER_MODULE)\nCheapClawListConversationTasksTool = HELPER_MODULE.CheapClawListConversationTasksTool\n\n\nclass CheapClawServiceTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.root = Path(self.temp_dir.name).resolve()\n        self.llm_config = str((Path(__file__).resolve().parent / \"llm_config_dummy.yaml\").resolve())\n\n    def test_panel_store_bootstraps_layout(self):\n        paths = CheapClawPaths.from_user_data_root(self.root)\n        store = CheapClawPanelStore(paths)\n        panel = store.load_panel()\n\n        self.assertTrue(paths.panel_path.exists())\n        self.assertTrue(paths.plans_path.exists())\n        self.assertEqual(panel[\"service_state\"][\"main_agent_task_id\"], str(paths.supervisor_task_id))\n        self.assertEqual(panel[\"channels\"], {})\n\n    def test_record_social_message_updates_panel_and_history(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        service.record_social_message(\n            channel=\"telegram\",\n            conversation_id=\"group_123\",\n            conversation_type=\"group\",\n            display_name=\"ML Group\",\n            sender_id=\"u1\",\n            sender_name=\"alice\",\n            message_text=\"@bot continue yesterday task\",\n            is_mention_to_bot=True,\n        )\n\n        panel = service.panel_store.load_panel()\n        conv = panel[\"channels\"][\"telegram\"][\"conversations\"][\"group_123\"]\n        self.assertTrue(conv[\"dirty\"])\n        self.assertEqual(conv[\"unread_event_count\"], 1)\n        self.assertEqual(len(conv[\"messages\"]), 1)\n        history_path = Path(conv[\"message_history_path\"])\n        self.assertTrue(history_path.exists())\n        self.assertTrue(Path(conv[\"context_summary_path\"]).exists())\n        lines = history_path.read_text(encoding=\"utf-8\").strip().splitlines()\n        self.assertEqual(len(lines), 1)\n        self.assertEqual(json.loads(lines[0])[\"text\"], \"@bot continue yesterday task\")\n\n    def test_supervisor_input_contains_latest_user_text(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        service.record_social_message(\n            channel=\"telegram\",\n            conversation_id=\"group_input\",\n            conversation_type=\"person\",\n            sender_id=\"u1\",\n            sender_name=\"alice\",\n            message_text=\"请把默认输出改成前 20 个\",\n            message_id=\"m20\",\n            is_mention_to_bot=True,\n        )\n        payload = json.loads(service._build_supervisor_input(\"dirty_panel\"))\n        conv = payload[\"dirty_conversations\"][0]\n        self.assertEqual(conv[\"latest_user_message\"][\"text\"], \"请把默认输出改成前 20 个\")\n        self.assertEqual(conv[\"pending_user_messages\"][0][\"message_id\"], \"m20\")\n        self.assertNotIn(\"panel_path\", payload)\n        self.assertNotIn(\"plans_path\", payload)\n        self.assertNotIn(\"message_history_path\", conv)\n        self.assertIn(\"context_excerpt\", conv)\n        self.assertIn(\"lookup_hints\", conv)\n\n    def test_supervisor_input_is_event_focused_not_path_heavy(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        task_id = str((self.root / \"cheapclaw\" / \"tasks\" / \"telegram\" / \"conv_focus\" / \"task_one\").resolve())\n        def seed_conversation(panel):\n            conv = CHEAPCLAW.ensure_conversation(panel, channel=\"telegram\", conversation_id=\"conv_focus\", conversation_type=\"group\")\n            conv[\"messages\"] = [{\n                \"message_id\": \"m1\",\n                \"direction\": \"inbound\",\n                \"timestamp\": \"2026-03-10T12:00:00+08:00\",\n                \"text\": \"@bot 帮我继续刚才那个任务\",\n            }]\n            conv[\"pending_events\"] = [{\n                \"type\": \"social_message\",\n                \"message_id\": \"m1\",\n                \"timestamp\": \"2026-03-10T12:00:00+08:00\",\n            }]\n            conv[\"dirty\"] = True\n            conv[\"latest_user_message_at\"] = \"2026-03-10T12:00:00+08:00\"\n            panel.setdefault(\"service_state\", {})[\"main_agent_dirty\"] = True\n            return panel\n\n        service.panel_store.mutate(seed_conversation)\n        def add_pending_event(panel):\n            conv = panel[\"channels\"][\"telegram\"][\"conversations\"][\"conv_focus\"]\n            conv[\"linked_tasks\"] = [{\n                \"task_id\": task_id,\n                \"agent_system\": \"CheapClawWorkerGeneral\",\n                \"agent_name\": \"worker_agent\",\n                \"status\": \"idle\",\n                \"last_final_output\": \"任务已完成初稿，请根据用户反馈继续修改。\",\n                \"last_final_output_at\": \"2026-03-10T12:00:00+08:00\",\n                \"share_context_path\": \"/tmp/share.json\",\n                \"log_path\": \"/tmp/task.log\",\n                \"watchdog_suspected_state\": \"healthy\",\n            }]\n            conv[\"pending_events\"].append({\n                \"type\": \"task_completed\",\n                \"task_id\": task_id,\n                \"timestamp\": \"2026-03-10T12:01:00+08:00\",\n            })\n            return panel\n\n        service.panel_store.mutate(add_pending_event)\n        payload = json.loads(service._build_supervisor_input(\"dirty_panel\"))\n        conv = payload[\"dirty_conversations\"][0]\n        self.assertIn(\"pending_events\", conv)\n        self.assertIn(\"context_excerpt\", conv)\n        self.assertIn(task_id, conv[\"context_excerpt\"])\n        self.assertNotIn(\"linked_tasks\", conv)\n        self.assertNotIn(\"message_task_bindings\", conv)\n        self.assertNotIn(\"relevant_tasks\", conv)\n\n    def test_compute_next_scheduled_run_supports_daily_and_weekly(self):\n        now = datetime.fromisoformat(\"2026-03-10T07:30:00+08:00\")\n        daily = CHEAPCLAW.compute_next_scheduled_run(\n            schedule_type=\"daily\",\n            time_of_day=\"08:00\",\n            now=now,\n        )\n        weekly = CHEAPCLAW.compute_next_scheduled_run(\n            schedule_type=\"weekly\",\n            time_of_day=\"08:00\",\n            days_of_week=[\"wed\"],\n            now=now,\n        )\n        self.assertEqual(daily, \"2026-03-10T08:00:00+08:00\")\n        self.assertEqual(weekly, \"2026-03-11T08:00:00+08:00\")\n\n    def test_message_ids_can_be_bound_to_task(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        service.record_social_message(\n            channel=\"telegram\",\n            conversation_id=\"group_bind\",\n            conversation_type=\"group\",\n            sender_id=\"u1\",\n            sender_name=\"alice\",\n            message_text=\"@bot continue report\",\n            message_id=\"m1\",\n            is_mention_to_bot=True,\n        )\n        task_id = str((self.root / \"task_bind\").resolve())\n        service.add_task_message(\n            task_id=task_id,\n            message=\"continue the same report\",\n            source=\"user\",\n            channel=\"telegram\",\n            conversation_id=\"group_bind\",\n            source_message_ids=[\"m1\"],\n        )\n        panel = service.panel_store.load_panel()\n        conv = panel[\"channels\"][\"telegram\"][\"conversations\"][\"group_bind\"]\n        bindings = conv[\"message_task_bindings\"]\n        self.assertEqual(len(bindings), 1)\n        self.assertEqual(bindings[0][\"message_id\"], \"m1\")\n        self.assertEqual(bindings[0][\"task_id\"], task_id)\n\n    def test_sdk_runtime_introspection_is_public(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        runtime = service.describe_runtime()\n        systems = service.list_agent_systems()\n\n        self.assertEqual(runtime[\"user_data_root\"], str(self.root))\n        self.assertFalse(runtime[\"seed_builtin_resources\"])\n        self.assertTrue(any(item[\"name\"] == \"CheapClawSupervisor\" for item in systems[\"agent_systems\"]))\n        self.assertTrue(any(item[\"name\"] == \"CheapClawWorkerGeneral\" for item in systems[\"agent_systems\"]))\n        self.assertTrue(any(\"agent_names\" in item for item in systems[\"agent_systems\"]))\n\n    def test_send_file_tool_queues_attachment(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        sample = self.root / \"sample.txt\"\n        sample.write_text(\"cheapclaw file test\", encoding=\"utf-8\")\n\n        tool_path = Path(__file__).resolve().parent.parent / \"apps\" / \"cheapclaw\" / \"tools_library\" / \"cheapclaw_send_file\" / \"cheapclaw_send_file.py\"\n        spec = importlib.util.spec_from_file_location(\"cheapclaw_send_file_tool\", tool_path)\n        module = importlib.util.module_from_spec(spec)\n        assert spec and spec.loader\n        sys.modules[spec.name] = module\n        spec.loader.exec_module(module)\n        tool = module.CheapClawSendFileTool()\n\n        from utils.user_paths import runtime_env_scope\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            result = tool.execute(\"\", {\n                \"channel\": \"telegram\",\n                \"conversation_id\": \"c1\",\n                \"local_path\": str(sample),\n                \"message\": \"file ready\",\n            })\n\n        self.assertEqual(result[\"status\"], \"success\")\n        payload = json.loads((self.root / \"cheapclaw\" / \"outbox\" / f\"{result['event_id']}.json\").read_text(encoding=\"utf-8\"))\n        self.assertEqual(payload[\"channel\"], \"telegram\")\n        self.assertEqual(payload[\"attachments\"][0][\"local_path\"], str(sample))\n\n    def test_reconcile_task_statuses_updates_panel_from_share_history(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        task_id = str((self.root / \"cheapclaw\" / \"tasks\" / \"telegram\" / \"conv_status\" / \"fib_task\").resolve())\n        with service._runtime_scope():\n            manager = get_hierarchy_manager(task_id)\n            context = manager._load_context()\n            context[\"history\"] = [{\n                \"instructions\": [],\n                \"hierarchy\": {\"worker_agent_demo\": {\"parent\": None, \"children\": [], \"level\": 0}},\n                \"agents_status\": {\n                    \"worker_agent_demo\": {\n                        \"agent_name\": \"worker_agent\",\n                        \"status\": \"completed\",\n                        \"final_output\": \"task finished\",\n                        \"end_time\": \"2026-03-10T12:00:00+08:00\",\n                    }\n                },\n                \"start_time\": \"2026-03-10T11:58:00+08:00\",\n                \"completion_time\": \"2026-03-10T12:00:00+08:00\",\n            }]\n            manager._save_context(context)\n            service.panel_store.mutate(lambda panel: CHEAPCLAW.ensure_conversation(panel, channel=\"telegram\", conversation_id=\"conv_status\"))\n            CHEAPCLAW.update_conversation_task(\"telegram\", \"conv_status\", task_id, {\n                \"status\": \"running\",\n                \"last_final_output\": \"\",\n                \"last_final_output_at\": \"\",\n            }, mark_dirty=False)\n\n        observations = service.reconcile_task_statuses()\n        self.assertTrue(any(item[\"task_id\"] == task_id for item in observations))\n        panel = service.panel_store.load_panel()\n        conv = panel[\"channels\"][\"telegram\"][\"conversations\"][\"conv_status\"]\n        task_view = next(item for item in conv[\"linked_tasks\"] if item[\"task_id\"] == task_id)\n        self.assertEqual(task_view[\"status\"], \"idle\")\n        self.assertEqual(task_view[\"last_final_output\"], \"task finished\")\n        self.assertEqual(task_view[\"watchdog_suspected_state\"], \"healthy\")\n        self.assertTrue(any(item[\"type\"] == \"task_completed\" for item in conv[\"pending_events\"]))\n        self.assertTrue(conv[\"dirty\"])\n\n    def test_telegram_group_message_detects_mention_entity(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        adapter = TelegramAdapter({\"bot_token\": \"dummy\"}, service)\n        adapter._me_cache = {\"username\": \"consine_15_bot\", \"id\": 123456}\n        message = {\n            \"text\": \"@consine_15_bot help me\",\n            \"entities\": [{\"type\": \"mention\", \"offset\": 0, \"length\": 15}],\n        }\n        self.assertTrue(adapter._message_mentions_bot(message, message[\"text\"], True))\n\n    def test_telegram_group_message_detects_reply_to_bot(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        adapter = TelegramAdapter({\"bot_token\": \"dummy\"}, service)\n        adapter._me_cache = {\"username\": \"consine_15_bot\", \"id\": 123456}\n        message = {\n            \"text\": \"continue that\",\n            \"reply_to_message\": {\"from\": {\"id\": 123456, \"username\": \"consine_15_bot\", \"is_bot\": True}},\n        }\n        self.assertTrue(adapter._message_mentions_bot(message, message[\"text\"], True))\n\n    def test_telegram_poll_events_accepts_supergroup_mention(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        adapter = TelegramAdapter({\"bot_token\": \"dummy\"}, service)\n        adapter._me_cache = {\"username\": \"consine_15_bot\", \"id\": 123456}\n        with mock.patch.object(adapter, \"_request\", return_value={\n            \"ok\": True,\n            \"result\": [{\n                \"update_id\": 77,\n                \"message\": {\n                    \"message_id\": 9,\n                    \"date\": int(time.time()),\n                    \"text\": \"@consine_15_bot do this\",\n                    \"entities\": [{\"type\": \"mention\", \"offset\": 0, \"length\": 15}],\n                    \"chat\": {\"id\": -10001, \"type\": \"supergroup\", \"title\": \"Ops Group\"},\n                    \"from\": {\"id\": 42, \"first_name\": \"Alice\"},\n                },\n            }],\n        }):\n            items = adapter.poll_events()\n        self.assertEqual(len(items), 1)\n        self.assertEqual(items[0][\"conversation_type\"], \"group\")\n        self.assertTrue(items[0][\"is_mention_to_bot\"])\n\n    def test_bootstrap_installs_agent_systems_tools_and_skill(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        result = service.bootstrap_assets(force=True)\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertTrue((self.root / \"agent_library\" / \"CheapClawSupervisor\" / \"level_3_agents.yaml\").exists())\n        self.assertTrue((self.root / \"agent_library\" / \"CheapClawWorkerGeneral\" / \"level_3_agents.yaml\").exists())\n        self.assertTrue((Path(service.describe_runtime()[\"skills_dir\"]) / \"cheapclaw-watchdog\" / \"SKILL.md\").exists())\n        self.assertTrue((Path(service.describe_runtime()[\"skills_dir\"]) / \"find-skills\" / \"SKILL.md\").exists())\n        self.assertTrue(Path(result[\"tools_dir\"]).joinpath(\"cheapclaw_read_panel\", \"cheapclaw_read_panel.py\").exists())\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            loader = ConfigLoader(\"CheapClawSupervisor\")\n            self.assertIn(\"cheapclaw_start_task\", loader.all_tools)\n            self.assertIn(\"cheapclaw_send_file\", loader.all_tools)\n            self.assertNotIn(\"human_in_loop\", loader.all_tools)\n            self.assertIn(\"supervisor_agent\", loader.all_tools)\n            worker_loader = ConfigLoader(\"CheapClawWorkerGeneral\")\n            self.assertIn(\"cheapclaw_reveal_skills\", worker_loader.all_tools)\n            self.assertIn(\"worker_agent\", worker_loader.all_tools)\n            self.assertNotIn(\"human_in_loop\", worker_loader.all_tools)\n\n    def test_bootstrap_removes_bundled_systems_even_without_force(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        agent_root = self.root / \"agent_library\"\n        (agent_root / \"OpenCowork\").mkdir(parents=True, exist_ok=True)\n        (agent_root / \"Researcher\").mkdir(parents=True, exist_ok=True)\n\n        service.bootstrap_assets(force=False)\n\n        self.assertFalse((agent_root / \"OpenCowork\").exists())\n        self.assertFalse((agent_root / \"Researcher\").exists())\n        self.assertTrue((agent_root / \"CheapClawSupervisor\").exists())\n        self.assertTrue((agent_root / \"CheapClawWorkerGeneral\").exists())\n\n    def test_start_task_rejects_supervisor_system(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        result = service.start_task(\n            channel=\"telegram\",\n            conversation_id=\"self_loop\",\n            task_name=\"bad\",\n            user_input=\"should fail\",\n            agent_system=\"CheapClawSupervisor\",\n        )\n        self.assertEqual(result[\"status\"], \"error\")\n        self.assertIn(\"不能调用本身\", result[\"error\"])\n\n    def test_start_task_uses_default_exposed_skills_and_dispatch_timestamp(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n\n        with warnings.catch_warnings():\n            warnings.simplefilter(\"ignore\", ResourceWarning)\n            result = service.start_task(\n                channel=\"telegram\",\n                conversation_id=\"skill_defaults\",\n                conversation_type=\"person\",\n                task_name=\"default-skill-worker\",\n                user_input=\"same input baseline\",\n                force_new=True,\n            )\n        self.assertEqual(result[\"status\"], \"success\")\n        overlay = result.get(\"overlay_skills\") or {}\n        revealed = overlay.get(\"revealed_skills\") or []\n        self.assertIn(\"docx\", revealed)\n        self.assertIn(\"find-skills\", revealed)\n        self.assertIn(\"pptx\", revealed)\n        self.assertIn(\"xlsx\", revealed)\n\n        pid = result.get(\"pid\")\n        self.assertIsInstance(pid, int)\n        time.sleep(0.5)\n        try:\n            os.kill(pid, signal.SIGTERM)\n        except ProcessLookupError:\n            pass\n\n    def test_runtime_registry_loads_cheapclaw_custom_tools_from_dynamic_tools_dir(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        runtime = service.describe_runtime()\n        with runtime_env_scope({\n            \"MLA_USER_DATA_ROOT\": str(self.root),\n            \"MLA_TOOLS_LIBRARY_DIR\": runtime[\"tools_dir\"],\n        }):\n            registry, metadata, failures = reload_runtime_registry()\n        self.assertIn(\"cheapclaw_read_panel\", registry)\n        self.assertIn(\"cheapclaw_start_task\", registry)\n        self.assertEqual(metadata[\"cheapclaw_start_task\"][\"source\"], \"custom\")\n        self.assertFalse(any(item.get(\"name\") == \"cheapclaw_start_task\" for item in failures))\n\n    def test_build_task_skills_overlay_creates_manifest(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        skills = service.list_global_skills()[\"skills\"]\n        self.assertTrue(skills)\n        selected = skills[0][\"name\"]\n\n        result = service.build_task_skills_overlay(\n            task_id=str((self.root / \"tasks\" / \"demo_task\").resolve()),\n            exposed_skills=[selected],\n        )\n        overlay_root = Path(result[\"overlay_root\"])\n\n        self.assertTrue((overlay_root / \"manifest.json\").exists())\n        self.assertEqual(result[\"revealed_skills\"], [selected])\n        self.assertTrue((overlay_root / selected).exists())\n\n    def test_update_task_preferences_persists_default_skills_and_mcp(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        with warnings.catch_warnings():\n            warnings.simplefilter(\"ignore\", ResourceWarning)\n            result = service.start_task(\n                channel=\"telegram\",\n                conversation_id=\"prefs_group\",\n                conversation_type=\"group\",\n                display_name=\"Prefs Group\",\n                task_name=\"prefs-worker\",\n                user_input=\"background smoke test\",\n                force_new=True,\n            )\n        task_id = result[\"task_id\"]\n        updated = service.update_task_preferences(\n            task_id=task_id,\n            default_exposed_skills=[\"docx\", \"find-skills\"],\n            mcp_servers=[{\"name\": \"github\", \"transport\": \"streamable_http\", \"url\": \"https://example.com/mcp\"}],\n        )\n        self.assertEqual(updated[\"status\"], \"success\")\n        self.assertEqual(updated[\"default_exposed_skills\"], [\"docx\", \"find-skills\"])\n        self.assertEqual(updated[\"mcp_servers\"][0][\"name\"], \"github\")\n        panel = service.panel_store.load_panel()\n        task_view = next(item for item in panel[\"channels\"][\"telegram\"][\"conversations\"][\"prefs_group\"][\"linked_tasks\"] if item[\"task_id\"] == task_id)\n        self.assertEqual(task_view[\"default_exposed_skills\"], [\"docx\", \"find-skills\"])\n        self.assertEqual(task_view[\"mcp_servers\"][0][\"name\"], \"github\")\n\n        pid = result.get(\"pid\")\n        self.assertIsInstance(pid, int)\n        time.sleep(0.5)\n        try:\n            os.kill(pid, signal.SIGTERM)\n        except ProcessLookupError:\n            pass\n\n    def test_start_task_binds_panel_entry(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n\n        with warnings.catch_warnings():\n            warnings.simplefilter(\"ignore\", ResourceWarning)\n            result = service.start_task(\n                channel=\"telegram\",\n                conversation_id=\"group_456\",\n                conversation_type=\"group\",\n                display_name=\"Ops Group\",\n                task_name=\"ops-summary\",\n                user_input=\"background smoke test\",\n                force_new=True,\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        panel = service.panel_store.load_panel()\n        conv = panel[\"channels\"][\"telegram\"][\"conversations\"][\"group_456\"]\n        self.assertEqual(len(conv[\"linked_tasks\"]), 1)\n        task_view = conv[\"linked_tasks\"][0]\n        self.assertEqual(task_view[\"task_id\"], result[\"task_id\"])\n        self.assertTrue(task_view[\"log_path\"].startswith(str(self.root / \"runtime\" / \"launched_tasks\")))\n        self.assertTrue(Path(task_view[\"share_context_path\"]).name.endswith(\"_share_context.json\"))\n\n        pid = result.get(\"pid\")\n        self.assertIsInstance(pid, int)\n        time.sleep(0.5)\n        try:\n            os.kill(pid, signal.SIGTERM)\n        except ProcessLookupError:\n            pass\n        else:\n            for _ in range(20):\n                try:\n                    waited_pid, _ = os.waitpid(pid, os.WNOHANG)\n                except ChildProcessError:\n                    break\n                if waited_pid == pid:\n                    break\n                time.sleep(0.1)\n\n    def test_start_task_falls_back_to_valid_worker_agent(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n\n        with warnings.catch_warnings():\n            warnings.simplefilter(\"ignore\", ResourceWarning)\n            result = service.start_task(\n                channel=\"telegram\",\n                conversation_id=\"group_fallback\",\n                conversation_type=\"group\",\n                display_name=\"Fallback Group\",\n                task_name=\"fallback-worker\",\n                user_input=\"background smoke test\",\n                force_new=True,\n                agent_system=\"CheapClawWorkerGeneral\",\n                agent_name=\"nonexistent_worker\",\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertEqual(result[\"agent_name\"], \"worker_agent\")\n\n        pid = result.get(\"pid\")\n        self.assertIsInstance(pid, int)\n        time.sleep(0.5)\n        try:\n            os.kill(pid, signal.SIGTERM)\n        except ProcessLookupError:\n            pass\n\n    def test_list_conversation_tasks_returns_recommended_task(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        old_task = str((self.root / \"cheapclaw\" / \"tasks\" / \"telegram\" / \"conv\" / \"old_task\").resolve())\n        new_task = str((self.root / \"cheapclaw\" / \"tasks\" / \"telegram\" / \"conv\" / \"new_task\").resolve())\n        service.record_social_message(\n            channel=\"telegram\",\n            conversation_id=\"conv\",\n            conversation_type=\"person\",\n            sender_id=\"u1\",\n            sender_name=\"alice\",\n            message_text=\"first request\",\n            message_id=\"m1\",\n            is_mention_to_bot=True,\n        )\n        service.start_task(\n            channel=\"telegram\",\n            conversation_id=\"conv\",\n            conversation_type=\"person\",\n            task_id=old_task,\n            task_name=\"old\",\n            user_input=\"first job\",\n            force_new=True,\n        )\n        service.record_social_message(\n            channel=\"telegram\",\n            conversation_id=\"conv\",\n            conversation_type=\"person\",\n            sender_id=\"u1\",\n            sender_name=\"alice\",\n            message_text=\"change that result\",\n            message_id=\"m2\",\n            is_mention_to_bot=True,\n        )\n        service.start_task(\n            channel=\"telegram\",\n            conversation_id=\"conv\",\n            conversation_type=\"person\",\n            task_id=new_task,\n            task_name=\"new\",\n            user_input=\"second job\",\n            force_new=True,\n            source_message_ids=[\"m2\"],\n        )\n\n        from utils.user_paths import runtime_env_scope\n\n        tool = CheapClawListConversationTasksTool()\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            payload = tool.execute(\"\", {\"channel\": \"telegram\", \"conversation_id\": \"conv\"})\n        self.assertEqual(payload[\"status\"], \"success\")\n        self.assertEqual(payload[\"recommended_task_id\"], new_task)\n        self.assertEqual(payload[\"latest_bound_task_id\"], new_task)\n        self.assertIn(payload[\"recommended_action\"], {\"append_to_running_task\", \"continue_existing_task\"})\n        self.assertTrue(payload[\"heuristic_note\"])\n\n    def test_add_task_message_appends_timestamp(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        task_id = str((self.root / \"manual_task\").resolve())\n\n        result = service.add_task_message(\n            task_id=task_id,\n            message=\"keep previous outputs and only extend them\",\n            source=\"user\",\n        )\n        self.assertEqual(result[\"status\"], \"success\")\n        snapshot = service.get_task_snapshot(task_id=task_id)\n        latest_instruction = snapshot[\"latest_instruction\"]\n        self.assertIn(\"message_appended_at\", latest_instruction[\"instruction\"])\n        self.assertTrue(snapshot[\"share_context_path\"].startswith(str(self.root / \"conversations\")))\n\n    def test_reset_task_public_api_clears_current_instructions(self):\n        service = CheapClawService(user_data_root=str(self.root), llm_config_path=self.llm_config)\n        task_id = str((self.root / \"reset_task\").resolve())\n        service.add_task_message(task_id=task_id, message=\"first\", source=\"user\")\n        before = service.get_task_snapshot(task_id=task_id)\n        self.assertEqual(before[\"instruction_count\"], 1)\n\n        result = service.reset_task(task_id=task_id, reason=\"unit-test\")\n        self.assertEqual(result[\"status\"], \"success\")\n\n        after = service.get_task_snapshot(task_id=task_id)\n        self.assertEqual(after[\"instruction_count\"], 0)\n        self.assertEqual(after[\"history_count\"], 1)\n\n    def test_external_copy_can_import_service_module(self):\n        external_root = self.root / \"external_service\"\n        external_root.mkdir(parents=True, exist_ok=True)\n        shutil.copy2(MODULE_PATH, external_root / \"cheapclaw_service.py\")\n        shutil.copy2(MODULE_PATH.parent / \"tool_runtime_helpers.py\", external_root / \"tool_runtime_helpers.py\")\n\n        spec = importlib.util.spec_from_file_location(\"external_cheapclaw_service\", external_root / \"cheapclaw_service.py\")\n        module = importlib.util.module_from_spec(spec)\n        assert spec and spec.loader\n        sys.modules[spec.name] = module\n        spec.loader.exec_module(module)\n\n        self.assertTrue(hasattr(module, \"CheapClawService\"))\n        self.assertTrue(hasattr(module, \"CheapClawPaths\"))\n\n    def test_external_copy_can_import_custom_tool_module(self):\n        external_root = self.root / \"external_tool_app\"\n        tool_dir = external_root / \"tools_library\" / \"cheapclaw_generate_task_id\"\n        tool_dir.mkdir(parents=True, exist_ok=True)\n        shutil.copy2(MODULE_PATH.parent / \"tool_runtime_helpers.py\", external_root / \"tool_runtime_helpers.py\")\n        shutil.copy2(\n            MODULE_PATH.parent / \"tools_library\" / \"cheapclaw_generate_task_id\" / \"cheapclaw_generate_task_id.py\",\n            tool_dir / \"cheapclaw_generate_task_id.py\",\n        )\n\n        spec = importlib.util.spec_from_file_location(\n            \"external_cheapclaw_generate_task_id\",\n            tool_dir / \"cheapclaw_generate_task_id.py\",\n        )\n        module = importlib.util.module_from_spec(spec)\n        assert spec and spec.loader\n        sys.modules[spec.name] = module\n        spec.loader.exec_module(module)\n\n        self.assertTrue(hasattr(module, \"CheapClawGenerateTaskIdTool\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_code_tools_system_terminal.py",
    "content": "from pathlib import Path\n\nimport tool_server_lite.tools.code_tools as code_tools\nfrom tool_server_lite.tools.code_tools import ExecuteCommandTool\n\n\ndef test_find_idle_terminal_window_id_returns_none_when_no_tagged_idle_tab(monkeypatch):\n    tool = ExecuteCommandTool()\n\n    monkeypatch.setattr(tool, \"_run_osascript\", lambda script, timeout=10: \"\")\n\n    assert tool._find_idle_terminal_window_id() is None\n\n\ndef test_get_or_create_terminal_window_id_creates_fresh_window_when_all_tagged_tabs_busy(monkeypatch):\n    tool = ExecuteCommandTool()\n\n    monkeypatch.setattr(tool, \"_terminal_window_exists\", lambda window_id: False)\n    monkeypatch.setattr(tool, \"_force_reset_tagged_terminal_windows\", lambda: None)\n\n    captured = {}\n\n    def fake_run(script, timeout=10):\n        captured[\"script\"] = script\n        return \"5678\"\n\n    monkeypatch.setattr(tool, \"_run_osascript\", fake_run)\n    monkeypatch.setattr(code_tools, \"TERMINAL_SESSION_WINDOW_ID\", 1111)\n    monkeypatch.setattr(code_tools, \"TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\", False)\n\n    assert tool._get_or_create_terminal_window_id() == 5678\n    assert 'do script \"\"' in captured[\"script\"]\n    assert code_tools.TERMINAL_SESSION_WINDOW_ID == 5678\n\n\ndef test_launch_terminal_script_checks_busy_and_updates_cached_window(monkeypatch, tmp_path):\n    tool = ExecuteCommandTool()\n    script_path = tmp_path / \"run.sh\"\n    script_path.write_text(\"#!/bin/bash\\n\", encoding=\"utf-8\")\n\n    monkeypatch.setattr(tool, \"_get_or_create_terminal_window_id\", lambda force_new=False: 1234)\n    monkeypatch.setattr(tool, \"_wait_for_terminal_window_idle\", lambda window_id, timeout=1.5, poll_interval=0.1: True)\n    monkeypatch.setattr(code_tools, \"TERMINAL_SESSION_WINDOW_ID\", None)\n    monkeypatch.setattr(code_tools, \"TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\", False)\n\n    captured = {}\n\n    def fake_run(script, timeout=10):\n        captured[\"script\"] = script\n        return \"4321\"\n\n    monkeypatch.setattr(tool, \"_run_osascript\", fake_run)\n\n    tool._launch_terminal_script(script_path)\n\n    assert 'busy of t' in captured[\"script\"]\n    assert 'do script \"\"' in captured[\"script\"]\n    assert code_tools.TERMINAL_SESSION_WINDOW_ID == 4321\n\n\ndef test_launch_terminal_script_interrupts_busy_session_instead_of_creating_new_window(monkeypatch, tmp_path):\n    tool = ExecuteCommandTool()\n    script_path = tmp_path / \"run.sh\"\n    script_path.write_text(\"#!/bin/bash\\n\", encoding=\"utf-8\")\n\n    monkeypatch.setattr(tool, \"_get_or_create_terminal_window_id\", lambda force_new=False: 1234)\n    waits = iter([False])\n    monkeypatch.setattr(\n        tool,\n        \"_wait_for_terminal_window_idle\",\n        lambda window_id, timeout=1.5, poll_interval=0.1: next(waits, True),\n    )\n\n    interrupted = {\"called\": 0}\n\n    def fake_interrupt(window_id):\n        interrupted[\"called\"] += 1\n        return True\n\n    monkeypatch.setattr(tool, \"_interrupt_terminal_window_processes\", fake_interrupt)\n    monkeypatch.setattr(code_tools, \"TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\", True)\n\n    captured = {}\n\n    def fake_run(script, timeout=10):\n        captured[\"script\"] = script\n        return \"4321\"\n\n    monkeypatch.setattr(tool, \"_run_osascript\", fake_run)\n\n    tool._launch_terminal_script(script_path)\n\n    assert interrupted[\"called\"] == 1\n    assert 'do script \"\"' in captured[\"script\"]\n"
  },
  {
    "path": "tests/test_context_hooks.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom core.context_builder import ContextBuilder\nfrom utils.user_paths import runtime_env_scope\n\n\nclass _DummyHierarchyManager:\n    def __init__(self):\n        self._context = {\"current\": {\"instructions\": [], \"hierarchy\": {}, \"agents_status\": {}}, \"history\": []}\n\n    def get_context(self):\n        return self._context\n\n    def get_loaded_skills(self, agent_id):\n        return []\n\n    def _save_context(self, context):\n        self._context = context\n\n\nclass _DummyLoader:\n    agent_config_dir = \".\"\n\n\nclass ContextHookTests(unittest.TestCase):\n    def test_after_build_hook_can_modify_context_text(self):\n        with tempfile.TemporaryDirectory() as temp_dir:\n            root = Path(temp_dir)\n            hook_file = root / \"hook.py\"\n            hook_file.write_text(\n                \"def on_context(payload):\\n\"\n                \"    return {'context_text': payload['context_text'] + '\\\\n\\\\n<test-hook>enabled</test-hook>'}\\n\",\n                encoding=\"utf-8\",\n            )\n            with runtime_env_scope({\n                \"MLA_USER_DATA_ROOT\": str(root),\n                \"MLA_CONTEXT_HOOKS_JSON\": f'[{{\"name\":\"demo\",\"when\":\"after_build\",\"callback\":\"{hook_file}:on_context\"}}]',\n            }):\n                builder = ContextBuilder(\n                    _DummyHierarchyManager(),\n                    agent_config={\"prompts\": {}},\n                    config_loader=_DummyLoader(),\n                    llm_client=None,\n                )\n                context = builder.build_context(\n                    task_id=str(root / \"task\"),\n                    agent_id=\"agent_demo\",\n                    agent_name=\"alpha_agent\",\n                    task_input=\"hello\",\n                    action_history=[],\n                    include_action_history=False,\n                )\n            self.assertIn(\"<test-hook>enabled</test-hook>\", context)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_file_tools.py",
    "content": "import pytest\nimport json\nfrom pathlib import Path\nfrom tool_server_lite.tools.file_tools import (\n    FileReadTool,\n    FileWriteTool,\n    DirListTool,\n    DirCreateTool,\n    FileMoveTool,\n    FileDeleteTool,\n)\n\npytestmark = pytest.mark.unit\n\n@pytest.fixture\ndef workspace(tmp_path):\n    \"\"\"Fixture to provide a temporary workspace path.\"\"\"\n    return str(tmp_path)\n\nclass TestFileReadTool:\n    def test_read_single_file_success(self, workspace):\n        file_path = Path(workspace) / \"test.txt\"\n        file_path.write_text(\"Hello World\", encoding=\"utf-8\")\n        \n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"test.txt\"})\n        \n        assert result[\"status\"] == \"success\"\n        assert \"Hello World\" in result[\"output\"]\n\n    def test_read_single_file_not_found(self, workspace):\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"nonexistent.txt\"})\n        \n        assert result[\"status\"] == \"error\"\n        assert \"File not found\" in result[\"error\"]\n\n    def test_read_multiple_files_success(self, workspace):\n        (Path(workspace) / \"f1.txt\").write_text(\"C1\", encoding=\"utf-8\")\n        (Path(workspace) / \"f2.txt\").write_text(\"C2\", encoding=\"utf-8\")\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": [\"f1.txt\", \"f2.txt\"]})\n\n        assert result[\"status\"] == \"success\"\n        assert \"\\\"success_count\\\": 2\" in result[\"output\"]\n\n    def test_read_empty_file(self, workspace):\n        \"\"\"测试读取空文件\"\"\"\n        (Path(workspace) / \"empty.txt\").touch()\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"empty.txt\"})\n\n        assert result[\"status\"] == \"success\"\n\n    def test_read_binary_file_error(self, workspace):\n        \"\"\"测试读取二进制文件应返回错误\"\"\"\n        binary_file = Path(workspace) / \"test.png\"\n        binary_file.write_bytes(b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00')\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"test.png\"})\n\n        assert result[\"status\"] == \"error\"\n        assert \"binary\" in result[\"error\"].lower()\n\n    def test_read_with_line_range(self, workspace):\n        \"\"\"测试按行范围读取\"\"\"\n        content = \"line1\\nline2\\nline3\\nline4\\nline5\\n\"\n        (Path(workspace) / \"lines.txt\").write_text(content, encoding=\"utf-8\")\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"lines.txt\", \"start_line\": 2, \"end_line\": 4})\n\n        assert result[\"status\"] == \"success\"\n        output = json.loads(result[\"output\"])\n        assert len(output) == 3\n        assert output[0][\"line\"] == 2\n        assert output[0][\"content\"] == \"line2\"\n\n    def test_read_without_line_numbers(self, workspace):\n        \"\"\"测试不显示行号\"\"\"\n        (Path(workspace) / \"test.txt\").write_text(\"content\", encoding=\"utf-8\")\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": \"test.txt\", \"show_line_numbers\": False})\n\n        assert result[\"status\"] == \"success\"\n        assert result[\"output\"] == \"content\"\n\n    def test_read_missing_path_parameter(self, workspace):\n        \"\"\"测试缺少 path 参数\"\"\"\n        tool = FileReadTool()\n        result = tool.execute(workspace, {})\n\n        assert result[\"status\"] == \"error\"\n        assert \"path\" in result[\"error\"].lower()\n\n    def test_read_with_file_path_alias(self, workspace):\n        \"\"\"测试使用 file_path 参数别名\"\"\"\n        (Path(workspace) / \"test.txt\").write_text(\"alias test\", encoding=\"utf-8\")\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"file_path\": \"test.txt\"})\n\n        assert result[\"status\"] == \"success\"\n        assert \"alias test\" in result[\"output\"]\n\n    def test_read_multiple_files_partial_error(self, workspace):\n        \"\"\"测试多文件读取部分失败\"\"\"\n        (Path(workspace) / \"exists.txt\").write_text(\"ok\", encoding=\"utf-8\")\n\n        tool = FileReadTool()\n        result = tool.execute(workspace, {\"path\": [\"exists.txt\", \"not_exists.txt\"]})\n\n        assert result[\"status\"] == \"success\"\n        output = json.loads(result[\"output\"])\n        assert output[\"success_count\"] == 1\n        assert output[\"error_count\"] == 1\n\nclass TestFileWriteTool:\n    def test_write_file_success(self, workspace):\n        tool = FileWriteTool()\n        result = tool.execute(workspace, {\"path\": \"new.txt\", \"content\": \"New Content\"})\n\n        assert result[\"status\"] == \"success\"\n        assert (Path(workspace) / \"new.txt\").read_text(encoding=\"utf-8\") == \"New Content\"\n\n    def test_write_creates_parent_dirs(self, workspace):\n        \"\"\"测试写入时自动创建父目录\"\"\"\n        tool = FileWriteTool()\n        result = tool.execute(workspace, {\"path\": \"a/b/c/deep.txt\", \"content\": \"deep\"})\n\n        assert result[\"status\"] == \"success\"\n        assert (Path(workspace) / \"a/b/c/deep.txt\").read_text(encoding=\"utf-8\") == \"deep\"\n\n    def test_write_reference_bib_forbidden(self, workspace):\n        \"\"\"测试禁止写入 reference.bib\"\"\"\n        tool = FileWriteTool()\n        result = tool.execute(workspace, {\"path\": \"reference.bib\", \"content\": \"test\"})\n\n        assert result[\"status\"] == \"error\"\n        assert \"reference.bib\" in result[\"error\"]\n\n    def test_replace_lines_file_not_found(self, workspace):\n        \"\"\"测试行替换时文件不存在\"\"\"\n        tool = FileWriteTool()\n        result = tool.execute(workspace, {\n            \"path\": \"nonexistent.py\",\n            \"start_line\": 1,\n            \"end_line\": 2,\n            \"content\": \"new content\"\n        })\n\n        assert result[\"status\"] == \"error\"\n        assert \"not found\" in result[\"error\"].lower()\n\n    def test_append_file_success(self, workspace):\n        p = Path(workspace) / \"log.txt\"\n        p.write_text(\"Line1\\n\", encoding=\"utf-8\")\n        \n        tool = FileWriteTool()\n        result = tool.execute(workspace, {\"path\": \"log.txt\", \"content\": \"Line2\", \"mode\": \"append\"})\n        \n        assert result[\"status\"] == \"success\"\n        assert p.read_text(encoding=\"utf-8\") == \"Line1\\nLine2\"\n\n    def test_replace_lines_success(self, workspace):\n        p = Path(workspace) / \"code.py\"\n        p.write_text(\"lines = [\\n    'one',\\n    'two',\\n    'three'\\n]\\n\", encoding=\"utf-8\")\n        \n        tool = FileWriteTool()\n        # Replace lines 2-4 (0-indexed 1-3)\n        # Original:\n        # 1: lines = [\n        # 2:     'one',\n        # 3:     'two',\n        # 4:     'three'\n        # 5: ]\n        \n        result = tool.execute(workspace, {\n            \"path\": \"code.py\", \n            \"start_line\": 2, \n            \"end_line\": 4, \n            \"content\": \"    'updated'\"\n        })\n        \n        assert result[\"status\"] == \"success\"\n        expected = \"lines = [\\n    'updated'\\n]\\n\"\n        assert p.read_text(encoding=\"utf-8\") == expected\n\nclass TestDirListTool:\n    def test_list_dir_success(self, workspace):\n        (Path(workspace) / \"a.txt\").touch()\n        (Path(workspace) / \"b_dir\").mkdir()\n\n        tool = DirListTool()\n        result = tool.execute(workspace, {\"path\": \".\"})\n\n        assert result[\"status\"] == \"success\"\n        assert \"[file] a.txt\" in result[\"output\"]\n        assert \"[dir] b_dir\" in result[\"output\"]\n\n    def test_list_dir_not_found(self, workspace):\n        \"\"\"测试目录不存在\"\"\"\n        tool = DirListTool()\n        result = tool.execute(workspace, {\"path\": \"nonexistent_dir\"})\n\n        assert result[\"status\"] == \"error\"\n        assert \"not found\" in result[\"error\"].lower()\n\n    def test_list_not_a_directory(self, workspace):\n        \"\"\"测试路径不是目录\"\"\"\n        (Path(workspace) / \"file.txt\").touch()\n\n        tool = DirListTool()\n        result = tool.execute(workspace, {\"path\": \"file.txt\"})\n\n        assert result[\"status\"] == \"error\"\n        assert \"not a directory\" in result[\"error\"].lower()\n\n    def test_list_empty_directory(self, workspace):\n        \"\"\"测试空目录\"\"\"\n        (Path(workspace) / \"empty_dir\").mkdir()\n\n        tool = DirListTool()\n        result = tool.execute(workspace, {\"path\": \"empty_dir\"})\n\n        assert result[\"status\"] == \"success\"\n        assert \"empty\" in result[\"output\"].lower()\n\n    def test_list_recursive_success(self, workspace):\n        (Path(workspace) / \"parent\").mkdir()\n        (Path(workspace) / \"parent/child.txt\").touch()\n        \n        tool = DirListTool()\n        result = tool.execute(workspace, {\"path\": \".\", \"recursive\": True})\n        \n        assert result[\"status\"] == \"success\"\n        assert \"[dir] parent\" in result[\"output\"]\n        assert \"  [file] child.txt\" in result[\"output\"]\n\nclass TestDirCreateTool:\n    def test_create_dir_success(self, workspace):\n        tool = DirCreateTool()\n        result = tool.execute(workspace, {\"path\": \"new_folder/sub_folder\"})\n        \n        assert result[\"status\"] == \"success\"\n        assert (Path(workspace) / \"new_folder/sub_folder\").is_dir()\n\nclass TestFileMoveTool:\n    def test_move_file_success(self, workspace):\n        src = Path(workspace) / \"src.txt\"\n        src.touch()\n        (Path(workspace) / \"dest\").mkdir()\n        \n        tool = FileMoveTool()\n        result = tool.execute(workspace, {\"source\": [\"src.txt\"], \"destination\": \"dest/\"})\n        \n        assert result[\"status\"] == \"success\"\n        assert not src.exists()\n        assert (Path(workspace) / \"dest/src.txt\").exists()\n\n    def test_copy_file_success(self, workspace):\n        src = Path(workspace) / \"src.txt\"\n        src.touch()\n        (Path(workspace) / \"dest\").mkdir()\n        \n        tool = FileMoveTool()\n        result = tool.execute(workspace, {\"source\": [\"src.txt\"], \"destination\": \"dest/\", \"copy\": True})\n        \n        assert result[\"status\"] == \"success\"\n        assert src.exists()\n        assert (Path(workspace) / \"dest/src.txt\").exists()\n\nclass TestFileDeleteTool:\n    def test_delete_file_success(self, workspace):\n        f = Path(workspace) / \"todel.txt\"\n        f.touch()\n\n        tool = FileDeleteTool()\n        result = tool.execute(workspace, {\"path\": \"todel.txt\"})\n\n        assert result[\"status\"] == \"success\"\n        assert not f.exists()\n\n    def test_delete_dir_success(self, workspace):\n        d = Path(workspace) / \"deldir\"\n        d.mkdir()\n        (d / \"f.txt\").touch()\n\n        tool = FileDeleteTool()\n        result = tool.execute(workspace, {\"path\": \"deldir\"})\n\n        assert result[\"status\"] == \"success\"\n        assert not d.exists()\n\n    def test_delete_not_found(self, workspace):\n        \"\"\"测试删除不存在的路径\"\"\"\n        tool = FileDeleteTool()\n        result = tool.execute(workspace, {\"path\": \"nonexistent\"})\n\n        assert result[\"status\"] == \"error\"\n        assert \"not found\" in result[\"error\"].lower()\n"
  },
  {
    "path": "tests/test_image_read_message.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n测试 image_read 的 message 结构：\n1. 读取图片 → 压缩 → base64\n2. 构建完整的 messages JSON 并打印\n3. 调用 LLM 验证图片是否正确传递\n\"\"\"\n\nimport base64\nimport json\nimport io\nfrom pathlib import Path\n\n# ===================== 配置 =====================\nIMAGE_PATH = Path(__file__).parent / \"截屏2026-02-03 08.44.28.png\"\nAPI_KEY = \"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\"\nBASE_URL = \"https://openrouter.ai/api/v1\"\nMODEL = \"openai/google/gemini-3-flash-preview\"\nMAX_DIM = 1568\nJPEG_QUALITY = 85\n\n\ndef load_and_compress_image(image_path: Path) -> tuple:\n    \"\"\"读取图片并压缩，返回 (data_uri, info_str)\"\"\"\n    from PIL import Image\n\n    img = Image.open(image_path)\n    original_size = img.size\n    original_format = img.format\n\n    # 转换色彩模式\n    if img.mode in ('RGBA', 'P', 'LA'):\n        background = Image.new('RGB', img.size, (255, 255, 255))\n        if img.mode == 'P':\n            img = img.convert('RGBA')\n        background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)\n        img = background\n    elif img.mode != 'RGB':\n        img = img.convert('RGB')\n\n    # 缩放\n    width, height = img.size\n    resized = False\n    if width > MAX_DIM or height > MAX_DIM:\n        if width > height:\n            new_width = MAX_DIM\n            new_height = int(height * MAX_DIM / width)\n        else:\n            new_height = MAX_DIM\n            new_width = int(width * MAX_DIM / height)\n        img = img.resize((new_width, new_height), Image.LANCZOS)\n        resized = True\n\n    # 编码为 JPEG\n    buffer = io.BytesIO()\n    img.save(buffer, format='JPEG', quality=JPEG_QUALITY, optimize=True)\n    image_data = buffer.getvalue()\n\n    image_base64 = base64.b64encode(image_data).decode('utf-8')\n    data_uri = f\"data:image/jpeg;base64,{image_base64}\"\n\n    final_size = img.size\n    size_kb = len(image_data) / 1024\n    info = (\n        f\"原始: {original_size} ({original_format}), \"\n        f\"压缩后: {final_size} (JPEG q={JPEG_QUALITY}), \"\n        f\"大小: {size_kb:.1f}KB, \"\n        f\"base64长度: {len(image_base64)} 字符, \"\n        f\"缩放: {'是' if resized else '否'}\"\n    )\n    return data_uri, info\n\n\ndef build_messages(data_uri: str, query: str) -> list:\n    \"\"\"\n    构建模拟 image_read 后的完整 messages 结构（方案二）\n    \"\"\"\n    messages = [\n        # system prompt（简化版）\n        {\n            \"role\": \"system\",\n            \"content\": \"你是一个AI助手，请分析用户提供的图片并回答问题。\"\n        },\n        # 初始 user 消息\n        {\n            \"role\": \"user\",\n            \"content\": \"请根据当前任务和上下文，执行下一步操作。\"\n        },\n        # assistant 调用 image_read 工具\n        {\n            \"role\": \"assistant\",\n            \"content\": None,\n            \"tool_calls\": [\n                {\n                    \"id\": \"call_test_001\",\n                    \"type\": \"function\",\n                    \"function\": {\n                        \"name\": \"image_read\",\n                        \"arguments\": json.dumps({\n                            \"image_path\": \"tests/截屏2026-02-03 08.44.28.png\",\n                            \"query\": query\n                        }, ensure_ascii=False)\n                    }\n                }\n            ]\n        },\n        # tool result（方案二：纯文字）\n        {\n            \"role\": \"tool\",\n            \"tool_call_id\": \"call_test_001\",\n            \"content\": \"Image loaded successfully. See below.\"\n        },\n        # 跟随的 user 消息（方案二：嵌入图片）\n        {\n            \"role\": \"user\",\n            \"content\": [\n                {\n                    \"type\": \"image_url\",\n                    \"image_url\": {\"url\": data_uri}\n                },\n                {\n                    \"type\": \"text\",\n                    \"text\": f\"上面是 image_read 获取的图片。Agent 的问题是: {query}\"\n                }\n            ]\n        }\n    ]\n    return messages\n\n\ndef print_messages_structure(messages: list):\n    \"\"\"打印 messages 结构（隐藏 base64 数据避免刷屏）\"\"\"\n    print(\"\\n\" + \"=\" * 70)\n    print(\"📋 Messages JSON 结构（base64 数据已截断显示）\")\n    print(\"=\" * 70)\n\n    for i, msg in enumerate(messages):\n        print(f\"\\n--- messages[{i}] ---\")\n        # 深拷贝并截断 base64\n        display_msg = json.loads(json.dumps(msg))\n        if isinstance(display_msg.get(\"content\"), list):\n            for part in display_msg[\"content\"]:\n                if isinstance(part, dict) and part.get(\"type\") == \"image_url\":\n                    url = part[\"image_url\"][\"url\"]\n                    if url.startswith(\"data:\"):\n                        # 只显示前80字符 + 长度\n                        part[\"image_url\"][\"url\"] = url[:80] + f\"...({len(url)} chars total)\"\n        elif isinstance(display_msg.get(\"content\"), str) and len(display_msg[\"content\"]) > 200:\n            display_msg[\"content\"] = display_msg[\"content\"][:200] + \"...\"\n\n        print(json.dumps(display_msg, indent=2, ensure_ascii=False))\n\n\ndef call_llm(messages: list):\n    \"\"\"使用 litellm 调用 LLM\"\"\"\n    import litellm\n    litellm.set_verbose = False\n    litellm.drop_params = True\n\n    print(\"\\n\" + \"=\" * 70)\n    print(f\"🚀 调用 LLM: {MODEL}\")\n    print(f\"   Base URL: {BASE_URL}\")\n    print(f\"   Messages 数量: {len(messages)}\")\n    print(\"=\" * 70)\n\n    from litellm import completion\n\n    response = completion(\n        model=MODEL,\n        messages=messages,\n        api_key=API_KEY,\n        api_base=BASE_URL,\n        temperature=0,\n        stream=False\n    )\n\n    content = response.choices[0].message.content\n    print(f\"\\n✅ LLM 响应:\\n\")\n    print(content)\n    print(f\"\\n📊 Token 使用: {response.usage}\")\n    return content\n\n\nif __name__ == \"__main__\":\n    print(\"=\" * 70)\n    print(\"🧪 测试 image_read 消息结构\")\n    print(\"=\" * 70)\n\n    # 1. 检查图片文件\n    if not IMAGE_PATH.exists():\n        print(f\"❌ 图片文件不存在: {IMAGE_PATH}\")\n        exit(1)\n    print(f\"📷 图片路径: {IMAGE_PATH}\")\n    print(f\"   文件大小: {IMAGE_PATH.stat().st_size / 1024:.1f}KB\")\n\n    # 2. 读取并压缩图片\n    print(\"\\n📦 处理图片...\")\n    data_uri, info = load_and_compress_image(IMAGE_PATH)\n    print(f\"   {info}\")\n\n    # 3. 构建 messages\n    query = \"请描述这张截图中的内容，包括界面元素和文字信息。\"\n    messages = build_messages(data_uri, query)\n\n    # 4. 打印 messages 结构\n    print_messages_structure(messages)\n\n    # 5. 调用 LLM\n    print(\"\\n\" + \"=\" * 70)\n    print(\"📡 发送到 LLM...\")\n    print(\"=\" * 70)\n    try:\n        result = call_llm(messages)\n    except Exception as e:\n        print(f\"\\n❌ LLM 调用失败: {e}\")\n        import traceback\n        traceback.print_exc()\n"
  },
  {
    "path": "tests/test_kimi_stream_compat.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom types import SimpleNamespace\nfrom unittest.mock import patch\n\nfrom services.llm_client import SimpleLLMClient, _EmbeddedToolCallStreamState\n\n\nclass KimiStreamCompatTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.original_user_data_root = os.environ.get(\"MLA_USER_DATA_ROOT\")\n        os.environ[\"MLA_USER_DATA_ROOT\"] = self.temp_dir.name\n        self.addCleanup(self._restore_user_data_root)\n\n        llm_config_path = Path(__file__).parent / \"llm_config_dummy.yaml\"\n        self.client = SimpleLLMClient(llm_config_path=str(llm_config_path))\n\n    def _restore_user_data_root(self):\n        if self.original_user_data_root is None:\n            os.environ.pop(\"MLA_USER_DATA_ROOT\", None)\n        else:\n            os.environ[\"MLA_USER_DATA_ROOT\"] = self.original_user_data_root\n\n    def test_embedded_tool_call_sections_are_hidden_from_visible_text(self):\n        state = _EmbeddedToolCallStreamState()\n        visible_parts = []\n        chunks = [\n            \"我先检查目录\",\n            \"<|tool_calls_section_begin|><|tool_call_begin|>functions.dir_list:0\",\n            \"<|tool_call_argument_begin|>{\\\"path\\\": \\\".\\\"}<|tool_call_end|><|tool_calls_section_end|>\",\n        ]\n        for chunk in chunks:\n            visible_parts.append(state.feed(chunk))\n        tail, raw_markup = state.finish()\n        visible_parts.append(tail)\n\n        self.assertEqual(\"\".join(visible_parts), \"我先检查目录\")\n\n        tool_calls = self.client._parse_embedded_tool_calls(raw_markup)\n        self.assertEqual(len(tool_calls), 1)\n        self.assertEqual(tool_calls[0].id, \"functions.dir_list:0\")\n        self.assertEqual(tool_calls[0].name, \"dir_list\")\n        self.assertEqual(tool_calls[0].arguments, {\"path\": \".\"})\n\n    def test_kimi_raw_marker_stream_falls_back_to_non_stream_and_parses_tool(self):\n        model_name = \"openrouter/moonshotai/kimi-k2.5\"\n        calls = []\n\n        def fake_completion(**kwargs):\n            calls.append(bool(kwargs.get(\"stream\", False)))\n            if kwargs.get(\"stream\", False):\n                chunk = SimpleNamespace(\n                    model=model_name,\n                    choices=[\n                        SimpleNamespace(\n                            delta=SimpleNamespace(\n                                content=(\n                                    \"我先检查目录\"\n                                    \"<|tool_calls_section_begin|>\"\n                                    \"<|tool_call_begin|>functions.dir_list:0\"\n                                    \"<|tool_call_argument_begin|>{\\\"path\\\": \\\".\\\"}\"\n                                ),\n                                reasoning_content=\"\",\n                                tool_calls=[],\n                            ),\n                            finish_reason=\"stop\",\n                        )\n                    ],\n                )\n                return iter([chunk])\n\n            response = SimpleNamespace(\n                model=model_name,\n                choices=[\n                    SimpleNamespace(\n                        message=SimpleNamespace(\n                            content=(\n                                \"我先检查目录\"\n                                \"<|tool_calls_section_begin|>\"\n                                \"<|tool_call_begin|>functions.dir_list:0\"\n                                \"<|tool_call_argument_begin|>{\\\"path\\\": \\\".\\\"}\"\n                                \"<|tool_call_end|><|tool_calls_section_end|>\"\n                            ),\n                            reasoning_content=\"\",\n                            tool_calls=[],\n                        ),\n                        finish_reason=\"stop\",\n                    )\n                ],\n            )\n            return response\n\n        with patch(\"services.llm_client.completion\", side_effect=fake_completion):\n            with patch.object(self.client, \"_append_debug_record\", lambda **kwargs: None):\n                with patch.object(self.client, \"_build_tools_definition\", lambda tool_list: [{\"type\": \"function\"}]):\n                    response = self.client._chat_internal(\n                        history=[],\n                        model=model_name,\n                        system_prompt=\"system\",\n                        tool_list=[\"dir_list\"],\n                        tool_choice=\"required\",\n                        temperature=0,\n                        max_tokens=0,\n                    )\n\n        self.assertEqual(calls, [True, False])\n        self.assertEqual(response.status, \"success\")\n        self.assertEqual(response.output, \"我先检查目录\")\n        self.assertEqual(len(response.tool_calls), 1)\n        self.assertEqual(response.tool_calls[0].id, \"functions.dir_list:0\")\n        self.assertEqual(response.tool_calls[0].name, \"dir_list\")\n        self.assertEqual(response.tool_calls[0].arguments, {\"path\": \".\"})\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_llm_client_lite_openrouter.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport unittest\n\nfrom tool_server_lite.llm_client_lite import LLMClientLite\n\n\nclass LLMClientLiteOpenRouterTests(unittest.TestCase):\n    def test_openrouter_model_name_is_normalized(self):\n        self.assertEqual(\n            LLMClientLite._normalize_openrouter_model_name(\n                \"google/gemini-3-pro-image-preview\",\n                \"https://openrouter.ai/api/v1\",\n            ),\n            \"openrouter/google/gemini-3-pro-image-preview\",\n        )\n\n    def test_prefixed_openrouter_model_name_is_left_unchanged(self):\n        self.assertEqual(\n            LLMClientLite._normalize_openrouter_model_name(\n                \"openrouter/google/gemini-3-pro-image-preview\",\n                \"https://openrouter.ai/api/v1\",\n            ),\n            \"openrouter/google/gemini-3-pro-image-preview\",\n        )\n\n    def test_non_openrouter_base_url_does_not_change_model_name(self):\n        self.assertEqual(\n            LLMClientLite._normalize_openrouter_model_name(\n                \"google/gemini-3-pro-image-preview\",\n                \"https://generativelanguage.googleapis.com\",\n            ),\n            \"google/gemini-3-pro-image-preview\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_llm_client_resilience.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport tempfile\nimport time\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import patch\n\nfrom services.llm_client import LLMResponse, SimpleLLMClient\n\n\nclass LLMClientResilienceTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.original_user_data_root = os.environ.get(\"MLA_USER_DATA_ROOT\")\n        os.environ[\"MLA_USER_DATA_ROOT\"] = self.temp_dir.name\n        self.addCleanup(self._restore_user_data_root)\n\n        llm_config_path = Path(__file__).parent / \"llm_config_dummy.yaml\"\n        self.client = SimpleLLMClient(llm_config_path=str(llm_config_path))\n\n    def _restore_user_data_root(self):\n        if self.original_user_data_root is None:\n            os.environ.pop(\"MLA_USER_DATA_ROOT\", None)\n        else:\n            os.environ[\"MLA_USER_DATA_ROOT\"] = self.original_user_data_root\n\n    def test_first_chunk_timeout_returns_quickly_without_waiting_for_worker(self):\n        self.client.first_chunk_timeout = 0.05\n        self.client.timeout = 1\n        self.client.stream_timeout = 1\n\n        def slow_completion(**kwargs):\n            time.sleep(0.30)\n            return iter(())\n\n        started_at = time.perf_counter()\n        with patch(\"services.llm_client.completion\", side_effect=slow_completion):\n            with patch.object(self.client, \"_append_debug_record\", lambda **kwargs: None):\n                response = self.client._chat_internal(\n                    history=[],\n                    model=\"openai/gpt-4o-mini\",\n                    system_prompt=\"system\",\n                    tool_list=[],\n                    tool_choice=None,\n                    temperature=0,\n                    max_tokens=0,\n                )\n        elapsed = time.perf_counter() - started_at\n\n        self.assertEqual(response.status, \"error\")\n        self.assertEqual(response.finish_reason, \"timeout\")\n        self.assertLess(elapsed, 0.20)\n\n    def test_non_retriable_error_stops_retry_loop_early(self):\n        attempts = []\n\n        def fake_chat_internal(*args):\n            attempts.append(args[-1])\n            return LLMResponse(\n                status=\"error\",\n                output=\"\",\n                tool_calls=[],\n                model=\"openai/gpt-4o-mini\",\n                finish_reason=\"error\",\n                error_information=\"Invalid API key provided by upstream\",\n            )\n\n        with patch.object(self.client, \"_chat_internal\", side_effect=fake_chat_internal):\n            with patch(\"services.llm_client.time.sleep\", lambda *_: None):\n                with self.assertRaises(Exception) as ctx:\n                    self.client.chat(\n                        history=[],\n                        model=\"openai/gpt-4o-mini\",\n                        system_prompt=\"system\",\n                        tool_list=[],\n                        tool_choice=None,\n                        max_retries=3,\n                    )\n\n        self.assertEqual(attempts, [1])\n        self.assertIn(\"不可重试\", str(ctx.exception))\n\n    def test_retry_emits_stream_reset_before_second_attempt(self):\n        streamed = []\n\n        def fake_chat_internal(*args):\n            stream_callback = args[-2]\n            attempt_index = args[-1]\n            if attempt_index == 1:\n                stream_callback({\n                    \"kind\": \"content\",\n                    \"text\": \"partial\",\n                    \"model\": \"demo-model\",\n                    \"debug_label\": \"execution\",\n                    \"attempt\": attempt_index,\n                })\n                return LLMResponse(\n                    status=\"error\",\n                    output=\"\",\n                    tool_calls=[],\n                    model=\"demo-model\",\n                    finish_reason=\"timeout\",\n                    error_information=\"request timed out\",\n                )\n\n            stream_callback({\n                \"kind\": \"content\",\n                \"text\": \"final\",\n                \"model\": \"demo-model\",\n                \"debug_label\": \"execution\",\n                \"attempt\": attempt_index,\n            })\n            return LLMResponse(\n                status=\"success\",\n                output=\"done\",\n                tool_calls=[],\n                model=\"demo-model\",\n                finish_reason=\"stop\",\n            )\n\n        with patch.object(self.client, \"_chat_internal\", side_effect=fake_chat_internal):\n            with patch(\"services.llm_client.time.sleep\", lambda *_: None):\n                response = self.client.chat(\n                    history=[],\n                    model=\"openai/gpt-4o-mini\",\n                    system_prompt=\"system\",\n                    tool_list=[],\n                    tool_choice=None,\n                    max_retries=1,\n                    stream_callback=streamed.append,\n                )\n\n        self.assertEqual(response.status, \"success\")\n        self.assertEqual(streamed[0][\"kind\"], \"content\")\n        self.assertEqual(streamed[0][\"attempt\"], 1)\n        self.assertEqual(streamed[1][\"kind\"], \"reset\")\n        self.assertEqual(streamed[1][\"attempt\"], 2)\n        self.assertEqual(streamed[1][\"reason\"], \"retry\")\n        self.assertEqual(streamed[2][\"kind\"], \"content\")\n        self.assertEqual(streamed[2][\"attempt\"], 2)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_llm_config_builder.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nimport yaml\n\nfrom infiagent import infiagent\nfrom utils.llm_config_builder import build_llm_config_from_profiles\n\n\nclass LlmConfigBuilderTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.root = Path(self.temp_dir.name).resolve()\n\n    def test_unified_profile_builds_all_model_slots(self):\n        config = build_llm_config_from_profiles(\n            {\n                \"mode\": \"unified\",\n                \"unified\": {\n                    \"provider\": \"openai_official\",\n                    \"model\": \"gpt-4.1-mini\",\n                    \"api_key\": \"sk-demo\",\n                },\n                \"temperature\": 0.2,\n            }\n        )\n\n        self.assertEqual(config[\"temperature\"], 0.2)\n        self.assertEqual(config[\"models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n        self.assertEqual(config[\"figure_models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n        self.assertEqual(config[\"compressor_models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n        self.assertEqual(config[\"read_figure_models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n        self.assertEqual(config[\"thinking_models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n\n    def test_split_profiles_support_local_model_without_api_key(self):\n        config = build_llm_config_from_profiles(\n            {\n                \"mode\": \"split\",\n                \"main\": {\n                    \"provider\": \"local_openai_compatible\",\n                    \"model\": \"qwen2.5:14b\",\n                    \"base_url\": \"http://localhost:11434/v1\",\n                    \"api_key\": \"\",\n                },\n                \"thinking\": {\n                    \"provider\": \"google_official\",\n                    \"model\": \"gemini-2.5-flash\",\n                    \"api_key\": \"google-demo\",\n                },\n            }\n        )\n\n        self.assertEqual(config[\"models\"][0][\"name\"], \"openai/qwen2.5:14b\")\n        self.assertEqual(config[\"models\"][0][\"base_url\"], \"http://localhost:11434/v1\")\n        self.assertNotIn(\"api_key\", config[\"models\"][0])\n        self.assertEqual(config[\"thinking_models\"][0][\"name\"], \"google/gemini-2.5-flash\")\n\n    def test_sdk_materializes_model_profiles_to_runtime_yaml(self):\n        agent = infiagent(\n            user_data_root=str(self.root),\n            model_profiles={\n                \"mode\": \"unified\",\n                \"unified\": {\n                    \"provider\": \"openrouter\",\n                    \"model\": \"openai/gpt-4.1-mini\",\n                    \"api_key\": \"sk-or-demo\",\n                    \"base_url\": \"https://openrouter.ai/api/v1\",\n                },\n            },\n        )\n\n        self.assertTrue(agent.llm_config_path)\n        cfg_path = Path(agent.llm_config_path)\n        self.assertTrue(cfg_path.exists())\n\n        parsed = yaml.safe_load(cfg_path.read_text(encoding=\"utf-8\"))\n        self.assertEqual(parsed[\"models\"][0][\"name\"], \"openai/gpt-4.1-mini\")\n        self.assertEqual(parsed[\"models\"][0][\"api_key\"], \"sk-or-demo\")\n        self.assertEqual(parsed[\"models\"][0][\"base_url\"], \"https://openrouter.ai/api/v1\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_llm_debug_output.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport json\nimport os\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom services.llm_client import SimpleLLMClient\nfrom utils.user_paths import get_task_file_prefix\n\n\nclass LlmDebugOutputTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.original_user_data_root = os.environ.get(\"MLA_USER_DATA_ROOT\")\n        os.environ[\"MLA_USER_DATA_ROOT\"] = self.temp_dir.name\n        self.addCleanup(self._restore_user_data_root)\n\n        llm_config_path = Path(__file__).parent / \"llm_config_dummy.yaml\"\n        self.client = SimpleLLMClient(llm_config_path=str(llm_config_path))\n\n    def _restore_user_data_root(self):\n        if self.original_user_data_root is None:\n            os.environ.pop(\"MLA_USER_DATA_ROOT\", None)\n        else:\n            os.environ[\"MLA_USER_DATA_ROOT\"] = self.original_user_data_root\n\n    def test_task_scoped_debug_records_append_to_conversation_jsonl(self):\n        task_id = str(Path(self.temp_dir.name) / \"workspace\" / \"demo-task\")\n        messages = [\n            {\"role\": \"system\", \"content\": \"system prompt\"},\n            {\"role\": \"user\", \"content\": \"hello\"},\n        ]\n\n        self.client._append_debug_record(\n            messages=messages,\n            model=\"openai/gpt-4o-mini\",\n            debug_task_id=task_id,\n            debug_label=\"execution\",\n            tool_choice=\"required\",\n            tool_count=1,\n            emit_tokens=\"token\",\n        )\n        self.client._append_debug_record(\n            messages=messages,\n            model=\"openai/gpt-4o-mini\",\n            debug_task_id=task_id,\n            debug_label=\"thinking\",\n            tool_choice=\"none\",\n            tool_count=0,\n            emit_tokens=\"thinking\",\n        )\n\n        debug_file = Path(self.temp_dir.name) / \"conversations\" / f\"{get_task_file_prefix(task_id)}_llm_debug.jsonl\"\n        self.assertTrue(debug_file.exists())\n\n        lines = debug_file.read_text(encoding=\"utf-8\").splitlines()\n        self.assertEqual(len(lines), 2)\n\n        first_record = json.loads(lines[0])\n        second_record = json.loads(lines[1])\n        self.assertEqual(first_record[\"task_id\"], task_id)\n        self.assertEqual(first_record[\"debug_label\"], \"execution\")\n        self.assertEqual(second_record[\"debug_label\"], \"thinking\")\n\n    def test_debug_records_without_task_fall_back_to_runtime_debug_dir(self):\n        self.client._append_debug_record(\n            messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n            model=\"openai/gpt-4o-mini\",\n            debug_label=\"context_builder\",\n        )\n\n        debug_file = Path(self.temp_dir.name) / \"runtime\" / \"debug\" / \"llm_debug.jsonl\"\n        self.assertTrue(debug_file.exists())\n\n        lines = debug_file.read_text(encoding=\"utf-8\").splitlines()\n        self.assertEqual(len(lines), 1)\n        record = json.loads(lines[0])\n        self.assertIsNone(record[\"task_id\"])\n        self.assertEqual(record[\"debug_label\"], \"context_builder\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_reasoning_modes.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport unittest\n\nfrom core.agent_executor import AgentExecutor\nfrom services.llm_client import LLMResponse\n\n\nclass _DummyEmitter:\n    def dispatch(self, _event):\n        return None\n\n\nclass ReasoningModeTests(unittest.TestCase):\n    def _bare_executor(self):\n        executor = AgentExecutor.__new__(AgentExecutor)\n        executor.agent_name = \"alpha_agent\"\n        executor.execution_model = \"demo-model\"\n        executor.available_tools = [\"file_write\", \"task_history_search\"]\n        executor.action_history = []\n        executor.action_history_fact = []\n        executor.execution_traces = []\n        executor.thinking_traces = []\n        executor.llm_turn_counter = 0\n        executor.event_emitter = _DummyEmitter()\n        return executor\n\n    def test_build_messages_includes_react_reflection_and_text_only_turns(self):\n        executor = self._bare_executor()\n        executor.action_history = [\n            {\n                \"_turn\": 0,\n                \"tool_name\": \"_react_reflection\",\n                \"arguments\": {},\n                \"result\": {\"status\": \"success\", \"output\": \"先检查目标文件是否存在\"},\n                \"assistant_content\": \"先检查目标文件是否存在\",\n                \"reasoning_content\": \"\",\n                \"_has_image\": False,\n                \"_image_base64\": None,\n            },\n            {\n                \"_turn\": 1,\n                \"tool_name\": \"_assistant_text\",\n                \"arguments\": {},\n                \"result\": {\"status\": \"success\", \"output\": \"我已经知道下一步要写入目标文件\"},\n                \"assistant_content\": \"我已经知道下一步要写入目标文件\",\n                \"reasoning_content\": \"\",\n                \"_has_image\": False,\n                \"_image_base64\": None,\n            },\n            {\n                \"_turn\": 2,\n                \"tool_call_id\": \"call_2_0\",\n                \"tool_name\": \"file_write\",\n                \"arguments\": {\"path\": \"a.txt\", \"content\": \"hello\"},\n                \"result\": {\"status\": \"success\", \"output\": \"ok\"},\n                \"assistant_content\": \"现在开始写文件\",\n                \"reasoning_content\": \"\",\n                \"_has_image\": False,\n                \"_image_base64\": None,\n            },\n        ]\n\n        messages = executor._build_messages_from_action_history()\n        assistant_texts = [msg.get(\"content\") for msg in messages if msg.get(\"role\") == \"assistant\"]\n\n        self.assertIn(\"先检查目标文件是否存在\", assistant_texts)\n        self.assertIn(\"我已经知道下一步要写入目标文件\", assistant_texts)\n        self.assertIn(\"现在开始写文件\", assistant_texts)\n\n    def test_run_react_reflection_persists_text_to_action_history(self):\n        executor = self._bare_executor()\n        saved = {\"count\": 0}\n\n        def fake_execute_llm_call(*args, **kwargs):\n            return LLMResponse(\n                status=\"success\",\n                output=\"先检查最近一次生成的文档并确认需要补写的部分\",\n                tool_calls=[],\n                model=\"demo-model\",\n                finish_reason=\"stop\",\n                reasoning_content=\"\",\n            )\n\n        def fake_save_state(*args, **kwargs):\n            saved[\"count\"] += 1\n\n        executor._execute_llm_call = fake_execute_llm_call\n        executor._save_state = fake_save_state\n\n        executor._run_react_reflection(\n            task_id=\"/tmp/demo-task\",\n            task_input=\"continue task\",\n            system_prompt=\"demo prompt\",\n            messages=[{\"role\": \"user\", \"content\": \"请继续\"}],\n            turn=0,\n        )\n\n        self.assertEqual(executor.llm_turn_counter, 1)\n        self.assertEqual(saved[\"count\"], 1)\n        self.assertEqual(executor.action_history[-1][\"tool_name\"], \"_react_reflection\")\n        self.assertIn(\"先检查最近一次生成的文档\", executor.action_history[-1][\"assistant_content\"])\n\n    def test_model_output_payload_prefers_last_execution_turn_over_react_reflection(self):\n        executor = self._bare_executor()\n        executor.execution_traces = [\n            {\"debug_label\": \"execution\", \"content\": \"real tool-driving output\", \"model\": \"m1\"},\n            {\"debug_label\": \"react_reflection\", \"content\": \"reflection text\", \"model\": \"m1\"},\n        ]\n        executor.thinking_traces = []\n\n        payload = executor._build_model_outputs_payload()\n\n        self.assertEqual(payload[\"last_execution\"][\"content\"], \"real tool-driving output\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_sdk_observability.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport json\nimport os\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import patch\n\nfrom core.agent_executor import AgentExecutor\nfrom core.events import AgentStartEvent, ThinkingEndEvent, ToolCallEndEvent, ToolCallStartEvent\nfrom core.runtime_exceptions import InfiAgentRunError\nfrom infiagent import infiagent\nfrom utils.user_paths import get_task_file_prefix\n\n\nclass _FakeEventEmitter:\n    def __init__(self):\n        self.events = []\n\n    def dispatch(self, event):\n        self.events.append(event)\n\n\nclass _FakeAgentExecutor:\n    instances = []\n    result_payload = {\"status\": \"success\", \"output\": \"done\"}\n\n    def __init__(\n        self,\n        agent_name,\n        agent_config,\n        config_loader,\n        hierarchy_manager,\n        direct_tools=False,\n        extra_event_handlers=None,\n        exit_on_error=True,\n        raise_on_error=False,\n        stream_llm_tokens=False,\n    ):\n        self.agent_name = agent_name\n        self.extra_event_handlers = list(extra_event_handlers or [])\n        self.exit_on_error = exit_on_error\n        self.raise_on_error = raise_on_error\n        self.stream_llm_tokens = stream_llm_tokens\n        self.__class__.instances.append(self)\n\n    def run(self, task_id, user_input):\n        if self.stream_llm_tokens:\n            token_events = [\n                {\n                    \"event_type\": \"run.thinking.token\",\n                    \"phase\": \"run\",\n                    \"domain\": \"thinking\",\n                    \"action\": \"token\",\n                    \"payload\": {\n                        \"agent_name\": self.agent_name,\n                        \"model\": \"demo-thinking-model\",\n                        \"text\": \"thinking chunk\",\n                        \"token_kind\": \"content\",\n                        \"is_initial\": True,\n                        \"is_forced\": False,\n                    },\n                },\n                {\n                    \"event_type\": \"run.llm.token\",\n                    \"phase\": \"run\",\n                    \"domain\": \"llm\",\n                    \"action\": \"token\",\n                    \"payload\": {\n                        \"agent_name\": self.agent_name,\n                        \"model\": \"demo-execution-model\",\n                        \"text\": \"execution chunk\",\n                        \"token_kind\": \"content\",\n                    },\n                },\n            ]\n            for handler in self.extra_event_handlers:\n                emitter = getattr(handler, \"emit\", None)\n                if callable(emitter):\n                    for event in token_events:\n                        emitter(event)\n\n        event_sequence = [\n            AgentStartEvent(agent_name=self.agent_name, task_input=user_input),\n            ThinkingEndEvent(agent_name=self.agent_name, is_initial=True, result=\"plan ready\"),\n            ToolCallStartEvent(tool_name=\"demo_tool\", arguments={\"x\": 1}),\n            ToolCallEndEvent(tool_name=\"demo_tool\", status=\"success\", result={\"status\": \"success\", \"output\": \"ok\"}),\n        ]\n        for event in event_sequence:\n            for handler in self.extra_event_handlers:\n                handler.handle(event)\n        payload = dict(self.__class__.result_payload)\n        payload.setdefault(\"task_id\", task_id)\n        payload.setdefault(\"observed_max_turns\", os.environ.get(\"MLA_MAX_TURNS\", \"\"))\n        return payload\n\n\nclass SDKObservabilityTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.base = Path(self.temp_dir.name)\n\n    def test_run_can_collect_structured_events_and_callback(self):\n        root = (self.base / \"sdk_root\").resolve()\n        task_id = str((self.base / \"task_with_events\").resolve())\n        agent = infiagent(user_data_root=str(root))\n        callback_events = []\n\n        _FakeAgentExecutor.instances.clear()\n        _FakeAgentExecutor.result_payload = {\"status\": \"success\", \"output\": \"done\"}\n\n        with patch(\"infiagent.sdk.AgentExecutor\", _FakeAgentExecutor):\n            result = agent.run(\n                \"hello from sdk\",\n                task_id=task_id,\n                collect_events=True,\n                on_event=callback_events.append,\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertEqual(len(result[\"events\"]), 4)\n        self.assertEqual(result[\"events\"][0][\"event_type\"], \"agent.start\")\n        self.assertEqual(result[\"events\"][1][\"event_type\"], \"run.thinking.end\")\n        self.assertEqual(result[\"events\"][2][\"payload\"][\"arguments\"], {\"x\": 1})\n        self.assertEqual(callback_events, result[\"events\"])\n\n        instance = _FakeAgentExecutor.instances[-1]\n        self.assertFalse(instance.exit_on_error)\n        self.assertFalse(instance.raise_on_error)\n        self.assertFalse(instance.stream_llm_tokens)\n\n    def test_run_can_optionally_collect_stream_token_events(self):\n        root = (self.base / \"sdk_stream_root\").resolve()\n        task_id = str((self.base / \"task_with_stream\").resolve())\n        agent = infiagent(user_data_root=str(root))\n        callback_events = []\n\n        _FakeAgentExecutor.instances.clear()\n        _FakeAgentExecutor.result_payload = {\"status\": \"success\", \"output\": \"done\"}\n\n        with patch(\"infiagent.sdk.AgentExecutor\", _FakeAgentExecutor):\n            result = agent.run(\n                \"stream me\",\n                task_id=task_id,\n                collect_events=True,\n                on_event=callback_events.append,\n                stream_llm_tokens=True,\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertEqual(result[\"events\"][0][\"event_type\"], \"run.thinking.token\")\n        self.assertEqual(result[\"events\"][1][\"event_type\"], \"run.llm.token\")\n        self.assertEqual(result[\"events\"][0][\"payload\"][\"text\"], \"thinking chunk\")\n        self.assertEqual(result[\"events\"][1][\"payload\"][\"text\"], \"execution chunk\")\n        self.assertEqual(callback_events, result[\"events\"])\n        instance = _FakeAgentExecutor.instances[-1]\n        self.assertTrue(instance.stream_llm_tokens)\n\n    def test_llm_stream_callback_maps_reset_events_and_attempts(self):\n        agent = object.__new__(AgentExecutor)\n        emitted = []\n        agent._emit_sdk_stream_event = lambda event_type, payload: emitted.append({\n            \"event_type\": event_type,\n            \"payload\": payload,\n        })\n\n        callback = AgentExecutor._build_llm_stream_callback(\n            agent,\n            stream_group=\"llm\",\n            agent_name=\"alpha_agent\",\n            model=\"demo-model\",\n        )\n        callback({\n            \"kind\": \"reset\",\n            \"model\": \"demo-model\",\n            \"attempt\": 2,\n            \"reason\": \"retry\",\n        })\n        callback({\n            \"kind\": \"content\",\n            \"model\": \"demo-model\",\n            \"attempt\": 2,\n            \"text\": \"hello\",\n        })\n\n        self.assertEqual(emitted[0][\"event_type\"], \"run.llm.reset\")\n        self.assertEqual(emitted[0][\"payload\"][\"attempt\"], 2)\n        self.assertEqual(emitted[0][\"payload\"][\"reason\"], \"retry\")\n        self.assertEqual(emitted[1][\"event_type\"], \"run.llm.token\")\n        self.assertEqual(emitted[1][\"payload\"][\"attempt\"], 2)\n\n    def test_run_can_override_max_turns_via_sdk_parameter(self):\n        root = (self.base / \"sdk_max_turns_root\").resolve()\n        task_id = str((self.base / \"task_with_max_turns\").resolve())\n        agent = infiagent(user_data_root=str(root))\n\n        _FakeAgentExecutor.instances.clear()\n        _FakeAgentExecutor.result_payload = {\"status\": \"success\", \"output\": \"done\"}\n\n        with patch(\"infiagent.sdk.AgentExecutor\", _FakeAgentExecutor):\n            result = agent.run(\n                \"max turns please\",\n                task_id=task_id,\n                max_turns=77,\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertEqual(result[\"observed_max_turns\"], \"77\")\n\n    def test_run_raise_on_error_turns_error_result_into_exception(self):\n        root = (self.base / \"sdk_error_root\").resolve()\n        task_id = str((self.base / \"task_with_error\").resolve())\n        agent = infiagent(user_data_root=str(root))\n\n        _FakeAgentExecutor.instances.clear()\n        _FakeAgentExecutor.result_payload = {\n            \"status\": \"error\",\n            \"output\": \"\",\n            \"error_information\": \"demo failure\",\n        }\n\n        with patch(\"infiagent.sdk.AgentExecutor\", _FakeAgentExecutor):\n            with self.assertRaises(InfiAgentRunError) as ctx:\n                agent.run(\n                    \"please fail\",\n                    task_id=task_id,\n                    collect_events=True,\n                    include_trace=True,\n                    raise_on_error=True,\n                )\n\n        exc = ctx.exception\n        self.assertEqual(exc.result[\"status\"], \"error\")\n        self.assertEqual(exc.result[\"error_information\"], \"demo failure\")\n        self.assertEqual(len(exc.events), 4)\n        self.assertIsNotNone(exc.trace)\n        self.assertEqual(exc.trace[\"status\"], \"success\")\n\n    def test_task_trace_reads_agent_action_files(self):\n        root = (self.base / \"trace_root\").resolve()\n        task_id = str((self.base / \"trace_task\").resolve())\n        agent = infiagent(user_data_root=str(root))\n\n        with agent._runtime_scope():\n            conversations_dir = root / \"conversations\"\n            conversations_dir.mkdir(parents=True, exist_ok=True)\n            prefix = get_task_file_prefix(task_id)\n            trace_path = conversations_dir / f\"{prefix}_demo_agent_001_actions.json\"\n            trace_path.write_text(json.dumps({\n                \"task_id\": task_id,\n                \"agent_id\": \"demo_agent_001\",\n                \"agent_name\": \"demo_agent\",\n                \"task_input\": \"trace me\",\n                \"current_turn\": 3,\n                \"tool_call_counter\": 2,\n                \"llm_turn_counter\": 1,\n                \"latest_thinking\": \"latest plan\",\n                \"pending_tools\": [{\"name\": \"demo_tool\"}],\n                \"action_history_fact\": [{\n                    \"tool_name\": \"demo_tool\",\n                    \"arguments\": {\"path\": \"demo.txt\"},\n                    \"result\": {\"status\": \"success\", \"output\": \"ok\"},\n                }],\n                \"action_history\": [{\"tool_name\": \"demo_tool\"}],\n                \"system_prompt\": \"hidden unless requested\",\n                \"last_updated\": \"2026-03-20T12:00:00+08:00\",\n            }, ensure_ascii=False), encoding=\"utf-8\")\n            debug_path = conversations_dir / f\"{prefix}_llm_debug.jsonl\"\n            debug_path.write_text('{\"demo\": true}\\n', encoding=\"utf-8\")\n\n        trace = agent.task_trace(task_id=task_id)\n        self.assertEqual(trace[\"status\"], \"success\")\n        self.assertEqual(trace[\"agent_trace_count\"], 1)\n        self.assertEqual(trace[\"llm_debug_path\"], str(debug_path))\n        item = trace[\"agent_traces\"][0]\n        self.assertEqual(item[\"agent_name\"], \"demo_agent\")\n        self.assertEqual(item[\"latest_thinking\"], \"latest plan\")\n        self.assertEqual(item[\"action_history_fact\"][0][\"tool_name\"], \"demo_tool\")\n        self.assertNotIn(\"action_history\", item)\n        self.assertNotIn(\"system_prompt\", item)\n\n        trace_with_full_fields = agent.task_trace(\n            task_id=task_id,\n            include_render_history=True,\n            include_system_prompt=True,\n        )\n        full_item = trace_with_full_fields[\"agent_traces\"][0]\n        self.assertIn(\"action_history\", full_item)\n        self.assertIn(\"system_prompt\", full_item)\n\n    def test_agent_executor_returns_error_result_in_library_mode(self):\n        executor = AgentExecutor.__new__(AgentExecutor)\n        executor.latest_thinking = \"partial progress\"\n        executor.event_emitter = _FakeEventEmitter()\n        executor.raise_on_error = False\n        executor.exit_on_error = False\n        executor.current_task_id = \"/tmp/demo-task\"\n        executor.agent_name = \"alpha_agent\"\n\n        try:\n            raise RuntimeError(\"boom\")\n        except RuntimeError as err:\n            result = executor._handle_execution_error(err)\n\n        self.assertEqual(result[\"status\"], \"error\")\n        self.assertEqual(result[\"error_type\"], \"RuntimeError\")\n        self.assertEqual(result[\"agent_name\"], \"alpha_agent\")\n        self.assertTrue(result[\"error_information\"])\n        self.assertEqual(len(executor.event_emitter.events), 2)\n\n    def test_agent_executor_can_raise_catchable_exception_in_library_mode(self):\n        executor = AgentExecutor.__new__(AgentExecutor)\n        executor.latest_thinking = \"\"\n        executor.event_emitter = _FakeEventEmitter()\n        executor.raise_on_error = True\n        executor.exit_on_error = False\n        executor.current_task_id = \"/tmp/demo-task\"\n        executor.agent_name = \"alpha_agent\"\n\n        with self.assertRaises(InfiAgentRunError) as ctx:\n            try:\n                raise RuntimeError(\"boom again\")\n            except RuntimeError as err:\n                executor._handle_execution_error(err)\n\n        exc = ctx.exception\n        self.assertEqual(exc.task_id, \"/tmp/demo-task\")\n        self.assertEqual(exc.agent_name, \"alpha_agent\")\n        self.assertEqual(exc.result[\"error_type\"], \"RuntimeError\")\n\n    def test_agent_executor_result_enrichment_exposes_raw_model_outputs(self):\n        executor = AgentExecutor.__new__(AgentExecutor)\n        executor.execution_traces = [{\n            \"turn_index\": 2,\n            \"model\": \"demo-exec-model\",\n            \"content\": \"assistant plain output\",\n            \"reasoning_content\": \"assistant reasoning\",\n            \"finish_reason\": \"tool_calls\",\n            \"tool_calls\": [{\"name\": \"demo_tool\"}],\n            \"status\": \"success\",\n        }]\n        executor.thinking_traces = [{\n            \"model\": \"demo-thinking-model\",\n            \"content\": \"thinking plain output\",\n            \"reasoning_content\": \"thinking reasoning\",\n            \"formatted_result\": \"[🤖 初始规划]\\n\\nthinking plain output\",\n            \"finish_reason\": \"stop\",\n            \"status\": \"success\",\n            \"is_initial\": True,\n            \"is_forced\": False,\n        }]\n\n        result = executor._with_model_outputs({\"status\": \"success\", \"output\": \"final output\"})\n        self.assertEqual(result[\"last_execution_output\"], \"assistant plain output\")\n        self.assertEqual(result[\"last_execution_reasoning_content\"], \"assistant reasoning\")\n        self.assertEqual(result[\"last_execution_model\"], \"demo-exec-model\")\n        self.assertEqual(result[\"last_thinking_output\"], \"thinking plain output\")\n        self.assertEqual(result[\"last_thinking_reasoning_content\"], \"thinking reasoning\")\n        self.assertEqual(result[\"last_thinking_model\"], \"demo-thinking-model\")\n        self.assertEqual(result[\"model_outputs\"][\"last_execution\"][\"finish_reason\"], \"tool_calls\")\n        self.assertEqual(result[\"model_outputs\"][\"last_thinking\"][\"formatted_result\"], \"[🤖 初始规划]\\n\\nthinking plain output\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_sdk_runtime_paths.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport signal\nimport json\nimport tempfile\nimport time\nimport unittest\nimport warnings\nfrom pathlib import Path\nfrom unittest.mock import patch\n\nfrom infiagent import infiagent\nfrom core.hierarchy_manager import get_hierarchy_manager\nfrom tool_server_lite.tools.skill_tools import FreshTool\nfrom tool_server_lite.tools.task_tools import AddMessageTool, ListTaskIdsTool, TaskShareContextPathTool\nfrom utils.config_loader import ConfigLoader\nfrom utils.runtime_control import pop_fresh_request, register_running_task, unregister_running_task\nfrom utils.task_runtime import append_task_message\nfrom utils.user_paths import get_context_settings, get_runtime_settings, runtime_env_scope\n\n\nclass SDKRuntimePathTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.base = Path(self.temp_dir.name)\n\n    def test_default_root_semantics_follow_current_env(self):\n        root = (self.base / \"default_root\").resolve()\n        task_id = str((self.base / \"default_task\").resolve())\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(root)}):\n            agent = infiagent()\n            result = agent.add_message(\"default root message\", task_id=task_id)\n            self.assertEqual(result[\"status\"], \"success\")\n            self.assertTrue(result[\"share_context_path\"].startswith(str(root / \"conversations\")))\n\n            listed = agent.list_task_ids()\n            self.assertTrue(any(item[\"task_id\"] == task_id for item in listed[\"tasks\"]))\n\n            share_paths = agent.task_share_context_path(task_id=task_id)\n            self.assertTrue(share_paths[\"share_context_path\"].startswith(str(root / \"conversations\")))\n            self.assertTrue(share_paths[\"stack_path\"].startswith(str(root / \"conversations\")))\n            self.assertTrue((root / \"config\" / \"app_config.json\").exists())\n\n    def test_custom_user_data_root_applies_to_sdk_and_runtime_control(self):\n        root = (self.base / \"custom_root\").resolve()\n        task_id = str((self.base / \"custom_task\").resolve())\n        agent = infiagent(user_data_root=str(root))\n\n        result = agent.add_message(\"sdk scoped message\", task_id=task_id)\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertTrue(result[\"share_context_path\"].startswith(str(root / \"conversations\")))\n\n        with agent._runtime_scope():\n            register_running_task(task_id, \"alpha_agent\", \"hello\", \"OpenCowork\")\n            try:\n                fresh_result = agent.fresh(task_id=task_id, reason=\"sdk-test-fresh\")\n                self.assertEqual(fresh_result[\"status\"], \"success\")\n                runtime_root = root / \"runtime\"\n                self.assertTrue((runtime_root / \"running_tasks\").exists())\n                self.assertEqual(pop_fresh_request(task_id), \"sdk-test-fresh\")\n            finally:\n                unregister_running_task(task_id)\n\n    def test_task_tools_follow_custom_user_data_root(self):\n        root = (self.base / \"tool_root\").resolve()\n        task_id = str((self.base / \"tool_task\").resolve())\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(root)}):\n            add_tool = AddMessageTool()\n            add_result = add_tool.execute(task_id, {\"message\": \"tool message\", \"source\": \"agent\"})\n            self.assertEqual(add_result[\"status\"], \"success\")\n            self.assertTrue(add_result[\"share_context_path\"].startswith(str(root / \"conversations\")))\n\n            path_tool = TaskShareContextPathTool()\n            path_result = path_tool.execute(task_id, {})\n            self.assertEqual(path_result[\"status\"], \"success\")\n            self.assertTrue(path_result[\"share_context_path\"].startswith(str(root / \"conversations\")))\n\n            list_tool = ListTaskIdsTool()\n            list_result = list_tool.execute(task_id, {})\n            self.assertEqual(list_result[\"status\"], \"success\")\n            self.assertTrue(any(item[\"task_id\"] == task_id for item in list_result[\"tasks\"]))\n\n            fresh_tool = FreshTool()\n            fresh_signal = fresh_tool.execute(task_id, {})\n            self.assertEqual(fresh_signal[\"status\"], \"success\")\n            self.assertEqual(fresh_signal[\"_fresh_task_id\"], task_id)\n\n    def test_user_data_root_alone_is_enough_for_agent_library_loading(self):\n        root = (self.base / \"config_root\").resolve()\n        agent = infiagent(user_data_root=str(root))\n\n        with agent._runtime_scope():\n            loader = ConfigLoader(\"OpenCowork\")\n            config = loader.get_tool_config(\"alpha_agent\")\n            for tool_name in [\n                \"fresh\",\n                \"add_message\",\n                \"start_background_task\",\n                \"task_share_context_path\",\n                \"list_task_ids\",\n                \"task_history_search\",\n            ]:\n                self.assertIn(tool_name, loader.all_tools)\n\n        self.assertEqual(config.get(\"type\"), \"llm_call_agent\")\n        self.assertTrue((root / \"agent_library\" / \"OpenCowork\").exists())\n\n    def test_sdk_requires_explicit_task_id(self):\n        agent = infiagent()\n        with self.assertRaises(ValueError):\n            agent.run(\"missing task id\", task_id=\"\")\n\n    def test_runtime_settings_support_new_reasoning_fields(self):\n        root = (self.base / \"runtime_settings_root\").resolve()\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(root)}):\n            app_config_path = root / \"config\" / \"app_config.json\"\n            payload = {\n                \"runtime\": {\n                    \"thinking_enabled\": False,\n                    \"thinking_steps\": 12,\n                    \"no_tool_retry_limit\": 9,\n                    \"action_window_steps\": 30,\n                    \"thinking_interval\": 30,\n                    \"max_turns\": 321,\n                },\n                \"context\": {\n                    \"user_history_recent_items\": 11,\n                    \"user_history_compress_threshold_tokens\": 1700,\n                },\n            }\n            app_config_path.parent.mkdir(parents=True, exist_ok=True)\n            app_config_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n\n            for key in [\n                \"MLA_THINKING_ENABLED\",\n                \"MLA_THINKING_STEPS\",\n                \"MLA_NO_TOOL_RETRY_LIMIT\",\n                \"MLA_MAX_TURNS\",\n                \"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\",\n                \"MLA_USER_HISTORY_RECENT_ITEMS\",\n            ]:\n                os.environ.pop(key, None)\n\n            runtime = get_runtime_settings()\n            context = get_context_settings()\n\n            self.assertFalse(runtime[\"thinking_enabled\"])\n            self.assertEqual(runtime[\"thinking_steps\"], 12)\n            self.assertEqual(runtime[\"no_tool_retry_limit\"], 9)\n            self.assertEqual(runtime[\"max_turns\"], 321)\n            self.assertEqual(context[\"user_history_recent_items\"], 11)\n            self.assertEqual(context[\"user_history_compress_threshold_tokens\"], 1700)\n\n    def test_sdk_build_launch_config_includes_visible_skills_and_reasoning_fields(self):\n        root = (self.base / \"sdk_reasoning_root\").resolve()\n        agent = infiagent(\n            user_data_root=str(root),\n            thinking_enabled=False,\n            thinking_steps=8,\n            no_tool_retry_limit=6,\n            user_history_recent_items=5,\n            visible_skills=[\"skill_a\", \"skill_b\"],\n        )\n\n        launch_config = agent._build_launch_config()\n        self.assertFalse(launch_config[\"thinking_enabled\"])\n        self.assertEqual(launch_config[\"thinking_steps\"], 8)\n        self.assertEqual(launch_config[\"no_tool_retry_limit\"], 6)\n        self.assertEqual(launch_config[\"user_history_recent_items\"], 5)\n        self.assertEqual(launch_config[\"visible_skills\"], [\"skill_a\", \"skill_b\"])\n\n    def test_run_explicit_reasoning_overrides_take_priority(self):\n        root = (self.base / \"run_override_root\").resolve()\n        task_id = str((self.base / \"run_override_task\").resolve())\n        captured = {}\n\n        class DummyManager:\n            def _load_context(self):\n                return {\"current\": {}, \"history\": []}\n\n            def _save_context(self, _context):\n                return None\n\n            def _save_stack(self, _stack):\n                return None\n\n            def start_new_instruction(self, _instruction):\n                return \"instruction_demo\"\n\n        class DummyLoader:\n            def __init__(self, _system):\n                self.agent_system_name = \"OpenCowork\"\n\n            def get_tool_config(self, _agent_name):\n                return {\"type\": \"llm_call_agent\", \"available_tools\": []}\n\n        class DummyExecutor:\n            def __init__(self, **kwargs):\n                captured[\"runtime\"] = get_runtime_settings()\n                captured[\"context\"] = get_context_settings()\n                captured[\"agent_name\"] = kwargs.get(\"agent_name\")\n\n            def run(self, _task_id, _user_input):\n                return {\"status\": \"success\", \"output\": \"ok\"}\n\n        agent = infiagent(\n            user_data_root=str(root),\n            thinking_enabled=True,\n            thinking_steps=30,\n            no_tool_retry_limit=7,\n            user_history_recent_items=0,\n        )\n\n        with patch(\"infiagent.sdk.is_task_running\", return_value=False), \\\n             patch(\"infiagent.sdk.clean_before_start\", return_value=None), \\\n             patch(\"infiagent.sdk.ConfigLoader\", DummyLoader), \\\n             patch(\"infiagent.sdk.get_hierarchy_manager\", return_value=DummyManager()), \\\n             patch(\"infiagent.sdk.AgentExecutor\", DummyExecutor):\n            result = agent.run(\n                \"override demo\",\n                task_id=task_id,\n                thinking_enabled=False,\n                thinking_steps=4,\n                no_tool_retry_limit=9,\n                user_history_recent_items=2,\n            )\n\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertEqual(captured[\"agent_name\"], \"alpha_agent\")\n        self.assertFalse(captured[\"runtime\"][\"thinking_enabled\"])\n        self.assertEqual(captured[\"runtime\"][\"thinking_steps\"], 4)\n        self.assertEqual(captured[\"runtime\"][\"no_tool_retry_limit\"], 9)\n        self.assertEqual(captured[\"context\"][\"user_history_recent_items\"], 2)\n\n    def test_sdk_instances_do_not_leak_user_data_roots(self):\n        root_a = (self.base / \"root_a\").resolve()\n        root_b = (self.base / \"root_b\").resolve()\n        task_a = str((self.base / \"task_a\").resolve())\n        task_b = str((self.base / \"task_b\").resolve())\n\n        agent_a = infiagent(user_data_root=str(root_a))\n        agent_b = infiagent(user_data_root=str(root_b))\n\n        result_a = agent_a.add_message(\"message for a\", task_id=task_a)\n        result_b = agent_b.add_message(\"message for b\", task_id=task_b)\n\n        self.assertTrue(result_a[\"share_context_path\"].startswith(str(root_a / \"conversations\")))\n        self.assertTrue(result_b[\"share_context_path\"].startswith(str(root_b / \"conversations\")))\n\n        list_a = agent_a.list_task_ids()\n        list_b = agent_b.list_task_ids()\n\n        self.assertTrue(any(item[\"task_id\"] == task_a for item in list_a[\"tasks\"]))\n        self.assertFalse(any(item[\"task_id\"] == task_b for item in list_a[\"tasks\"]))\n        self.assertTrue(any(item[\"task_id\"] == task_b for item in list_b[\"tasks\"]))\n        self.assertFalse(any(item[\"task_id\"] == task_a for item in list_b[\"tasks\"]))\n\n    def test_run_returns_busy_when_task_already_running(self):\n        root = (self.base / \"busy_root\").resolve()\n        task_id = str((self.base / \"busy_task\").resolve())\n        agent = infiagent(user_data_root=str(root))\n        with agent._runtime_scope():\n            register_running_task(task_id, \"alpha_agent\", \"hello\", \"OpenCowork\")\n            try:\n                result = agent.run(\"new request\", task_id=task_id)\n            finally:\n                unregister_running_task(task_id)\n        self.assertEqual(result[\"status\"], \"busy\")\n        self.assertEqual(result[\"task_id\"], task_id)\n\n    def test_background_task_launch_uses_user_data_root(self):\n        root = (self.base / \"launch_root\").resolve()\n        task_id = str((self.base / \"launch_task\").resolve())\n        llm_config = str((Path(__file__).resolve().parent / \"llm_config_dummy.yaml\").resolve())\n        agent = infiagent(user_data_root=str(root), llm_config_path=llm_config)\n\n        with warnings.catch_warnings():\n            warnings.simplefilter(\"ignore\", ResourceWarning)\n            result = agent.start_background_task(\n                task_id=task_id,\n                user_input=\"background launch smoke test\",\n                force_new=True,\n            )\n        self.assertEqual(result[\"status\"], \"success\")\n        self.assertTrue(result[\"log_path\"].startswith(str(root / \"runtime\" / \"launched_tasks\")))\n\n        pid = result.get(\"pid\")\n        self.assertIsInstance(pid, int)\n        time.sleep(0.5)\n        try:\n            os.kill(pid, signal.SIGTERM)\n        except ProcessLookupError:\n            pass\n        else:\n            for _ in range(20):\n                try:\n                    waited_pid, _ = os.waitpid(pid, os.WNOHANG)\n                except ChildProcessError:\n                    break\n                if waited_pid == pid:\n                    break\n                time.sleep(0.1)\n\n    def test_task_snapshot_falls_back_to_history_final_output(self):\n        root = (self.base / \"history_root\").resolve()\n        task_id = str((self.base / \"history_task\").resolve())\n        agent = infiagent(user_data_root=str(root))\n\n        with agent._runtime_scope():\n            manager = get_hierarchy_manager(task_id)\n            context = manager._load_context()\n            context[\"history\"] = [{\n                \"instructions\": [],\n                \"hierarchy\": {\"worker_agent_demo\": {\"parent\": None, \"children\": [], \"level\": 0}},\n                \"agents_status\": {\n                    \"worker_agent_demo\": {\n                        \"agent_name\": \"worker_agent\",\n                        \"status\": \"completed\",\n                        \"thinking_updated_at\": \"2026-03-10T10:00:00+08:00\",\n                        \"latest_thinking\": \"done thinking\",\n                        \"final_output\": \"done output\",\n                        \"end_time\": \"2026-03-10T10:05:00+08:00\",\n                    }\n                },\n                \"start_time\": \"2026-03-10T10:00:00+08:00\",\n                \"completion_time\": \"2026-03-10T10:05:00+08:00\",\n            }]\n            context[\"current\"] = {\n                \"instructions\": [],\n                \"hierarchy\": {},\n                \"agents_status\": {},\n                \"start_time\": \"2026-03-10T10:06:00+08:00\",\n                \"last_updated\": \"2026-03-10T10:06:00+08:00\",\n            }\n            manager._save_context(context)\n\n        snapshot = agent.task_snapshot(task_id=task_id)\n        self.assertEqual(snapshot[\"status\"], \"success\")\n        self.assertEqual(snapshot[\"last_final_output\"], \"done output\")\n        self.assertEqual(snapshot[\"last_final_output_at\"], \"2026-03-10T10:05:00+08:00\")\n        self.assertEqual(snapshot[\"latest_thinking\"], \"done thinking\")\n\n    def test_tool_hooks_are_exposed_in_launch_config(self):\n        callback = str((self.base / \"hook.py\").resolve()) + \":on_tool_event\"\n        hooks = [{\n            \"name\": \"demo\",\n            \"when\": \"after\",\n            \"tool_names\": [\"final_output\"],\n            \"callback\": callback,\n            \"result_filters\": {\"status\": \"success\"},\n        }]\n        agent = infiagent(user_data_root=str((self.base / \"hook_root\").resolve()), tool_hooks=hooks)\n        launch_config = agent._build_launch_config()\n        self.assertEqual(launch_config[\"tool_hooks\"], hooks)\n\n    def test_context_hooks_are_exposed_in_launch_config(self):\n        callback = str((self.base / \"ctx_hook.py\").resolve()) + \":on_context\"\n        hooks = [{\n            \"name\": \"ctx-demo\",\n            \"when\": \"after_build\",\n            \"callback\": callback,\n        }]\n        agent = infiagent(user_data_root=str((self.base / \"ctx_hook_root\").resolve()), context_hooks=hooks)\n        launch_config = agent._build_launch_config()\n        self.assertEqual(launch_config[\"context_hooks\"], hooks)\n        self.assertTrue(launch_config[\"seed_builtin_resources\"])\n\n    def test_max_turns_is_exposed_in_launch_config(self):\n        agent = infiagent(\n            user_data_root=str((self.base / \"max_turns_root\").resolve()),\n            max_turns=321,\n        )\n        launch_config = agent._build_launch_config()\n        self.assertEqual(launch_config[\"max_turns\"], 321)\n        runtime = agent.describe_runtime()\n        self.assertEqual(runtime[\"max_turns\"], 321)\n\n    def test_add_message_resume_if_needed_uses_resume_when_stack_exists(self):\n        root = (self.base / \"resume_root\").resolve()\n        task_id = str((self.base / \"resume_task\").resolve())\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(root)}):\n            manager = get_hierarchy_manager(task_id)\n            manager.set_runtime_metadata(\n                agent_system=\"OpenCowork\",\n                agent_name=\"alpha_agent\",\n                user_input=\"previous input\",\n            )\n            manager._save_stack([{\n                \"agent_id\": \"alpha_agent_demo\",\n                \"agent_name\": \"alpha_agent\",\n                \"parent_id\": None,\n                \"level\": 0,\n                \"user_input\": \"previous input\",\n                \"start_time\": \"2026-03-25T10:00:00+08:00\",\n            }])\n\n            with patch(\"utils.task_runtime.resume_task_with_fresh\", return_value=(True, \"resumed\")) as resume_mock:\n                with patch(\"utils.task_runtime.launch_task_process\") as launch_mock:\n                    ok, payload = append_task_message(\n                        task_id=task_id,\n                        message=\"resume me\",\n                        source=\"user\",\n                        resume_if_needed=True,\n                        fallback_agent_system=\"OpenCowork\",\n                    )\n\n        self.assertTrue(ok)\n        self.assertTrue(payload[\"resumed\"])\n        self.assertFalse(payload[\"launched\"])\n        resume_mock.assert_called_once()\n        launch_mock.assert_not_called()\n\n    def test_add_message_resume_if_needed_launches_new_task_when_stack_empty(self):\n        root = (self.base / \"launch_after_add_root\").resolve()\n        task_id = str((self.base / \"launch_after_add_task\").resolve())\n\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(root), \"MLA_MAX_TURNS\": \"77\"}):\n            manager = get_hierarchy_manager(task_id)\n            manager.set_runtime_metadata(\n                agent_system=\"OpenCowork\",\n                agent_name=\"alpha_agent\",\n                user_input=\"previous input\",\n            )\n            manager._save_stack([])\n\n            with patch(\"utils.task_runtime.launch_task_process\", return_value=(True, {\n                \"message\": f\"已在后台启动任务: {task_id}\",\n                \"task_id\": task_id,\n                \"pid\": 4321,\n                \"log_path\": str(root / \"runtime\" / \"launched_tasks\" / \"demo.log\"),\n                \"agent_system\": \"OpenCowork\",\n                \"agent_name\": \"alpha_agent\",\n            })) as launch_mock:\n                ok, payload = append_task_message(\n                    task_id=task_id,\n                    message=\"please continue\",\n                    source=\"user\",\n                    resume_if_needed=True,\n                    fallback_agent_system=\"OpenCowork\",\n                    env_overrides={\"MLA_USER_DATA_ROOT\": str(root), \"MLA_MAX_TURNS\": \"77\"},\n                )\n\n        self.assertTrue(ok)\n        self.assertFalse(payload[\"resumed\"])\n        self.assertTrue(payload[\"launched\"])\n        launch_mock.assert_called_once()\n        kwargs = launch_mock.call_args.kwargs\n        self.assertEqual(kwargs[\"task_id\"], task_id)\n        self.assertEqual(kwargs[\"user_input\"], \"please continue\")\n        self.assertEqual(kwargs[\"agent_system\"], \"OpenCowork\")\n        self.assertEqual(kwargs[\"agent_name\"], \"alpha_agent\")\n        self.assertEqual(kwargs[\"config\"][\"user_data_root\"], str(root))\n        self.assertEqual(kwargs[\"config\"][\"max_turns\"], 77)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_task_history_index.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport json\nimport os\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom core.context_builder import ContextBuilder\nfrom tool_server_lite.tools.task_tools import TaskHistorySearchTool\nfrom utils.task_history_index import search_task_history_records, search_task_history_sql, sync_task_history_from_context\nfrom utils.user_paths import runtime_env_scope\n\n\nclass _DummyHierarchyManager:\n    def __init__(self, context):\n        self._context = context\n\n    def get_context(self):\n        return self._context\n\n    def _save_context(self, context):\n        self._context = context\n\n\nclass _DummyConfigLoader:\n    agent_system_name = \"OpenCowork\"\n    agent_config_dir = \"\"\n\n\nclass TaskHistoryIndexTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.root = Path(self.temp_dir.name).resolve()\n\n    def _sample_context(self, task_id: str):\n        return {\n            \"runtime\": {\n                \"agent_system\": \"OpenCowork\",\n                \"agent_name\": \"alpha_agent\",\n            },\n            \"current\": {\n                \"instructions\": [],\n                \"hierarchy\": {},\n                \"agents_status\": {},\n            },\n            \"history\": [\n                {\n                    \"instructions\": [\n                        {\"instruction\": \"继续完善季度总结文档\"},\n                        {\"instruction\": \"检查上次生成的结论是否需要更新\"},\n                    ],\n                    \"start_time\": \"2026-03-01T10:00:00+08:00\",\n                    \"completion_time\": \"2026-03-01T10:05:00+08:00\",\n                    \"hierarchy\": {\n                        \"alpha_agent_1\": {\"parent\": None, \"children\": [], \"level\": 0},\n                    },\n                    \"agents_status\": {\n                        \"alpha_agent_1\": {\n                            \"agent_name\": \"alpha_agent\",\n                            \"status\": \"completed\",\n                            \"final_output\": \"季度总结文档已生成在 summary.md\",\n                            \"latest_thinking\": \"下一次应优先复用 summary.md 的既有结构。\",\n                        }\n                    },\n                }\n            ],\n        }\n\n    def test_sync_and_sql_search_return_instruction_bundle(self):\n        task_id = str((self.root / \"task_a\").resolve())\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            context = self._sample_context(task_id)\n            inserted = sync_task_history_from_context(task_id, context)\n            self.assertGreater(inserted, 0)\n\n            results = search_task_history_sql(query=\"summary\", limit=5)\n            self.assertTrue(results)\n            self.assertIn(\"继续完善季度总结文档\", results[0][\"text\"])\n            self.assertIn(\"summary.md\", results[0][\"text\"])\n\n    def test_task_history_search_tool_reads_index(self):\n        task_id = str((self.root / \"task_b\").resolve())\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            context = self._sample_context(task_id)\n            sync_task_history_from_context(task_id, context)\n\n            tool = TaskHistorySearchTool()\n            result = tool.execute(task_id, {\"keyword\": \"summary\"})\n            self.assertEqual(result[\"status\"], \"success\")\n            self.assertTrue(result[\"results\"])\n            self.assertIn(\"summary.md\", result[\"output\"])\n\n    def test_task_history_records_default_returns_all_entries_for_task(self):\n        task_id = str((self.root / \"task_c\").resolve())\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            context = self._sample_context(task_id)\n            sync_task_history_from_context(task_id, context)\n\n            payload = search_task_history_records(task_id=task_id)\n            self.assertEqual(len(payload[\"results\"]), 1)\n            self.assertEqual(payload[\"results\"][0][\"round\"], 1)\n\n    def test_task_history_records_support_start_round(self):\n        task_id = str((self.root / \"task_d\").resolve())\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            context = self._sample_context(task_id)\n            context[\"history\"].append(\n                {\n                    \"instructions\": [{\"instruction\": \"第二轮：继续补充文档\"}],\n                    \"start_time\": \"2026-03-02T10:00:00+08:00\",\n                    \"completion_time\": \"2026-03-02T10:05:00+08:00\",\n                    \"hierarchy\": {\"alpha_agent_2\": {\"parent\": None, \"children\": [], \"level\": 0}},\n                    \"agents_status\": {\n                        \"alpha_agent_2\": {\n                            \"agent_name\": \"alpha_agent\",\n                            \"status\": \"completed\",\n                            \"final_output\": \"第二轮输出写入 summary_v2.md\",\n                            \"latest_thinking\": \"继续补充结论部分。\",\n                        }\n                    },\n                }\n            )\n            sync_task_history_from_context(task_id, context)\n\n            payload = search_task_history_records(task_id=task_id, start_round=2)\n            self.assertEqual(len(payload[\"results\"]), 1)\n            self.assertIn(\"第二轮：继续补充文档\", payload[\"results\"][0][\"instructions\"][0])\n\n    def test_recent_history_selection_uses_new_setting(self):\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": str(self.root)}):\n            app_config_path = self.root / \"config\" / \"app_config.json\"\n            app_config_path.parent.mkdir(parents=True, exist_ok=True)\n            app_config_path.write_text(\n                json.dumps(\n                    {\n                        \"context\": {\n                            \"user_history_recent_items\": 1,\n                            \"user_history_compress_threshold_tokens\": 99999,\n                        }\n                    },\n                    ensure_ascii=False,\n                    indent=2,\n                ),\n                encoding=\"utf-8\",\n            )\n            for key in [\n                \"MLA_ACTION_WINDOW_STEPS\",\n                \"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\",\n                \"MLA_USER_HISTORY_RECENT_ITEMS\",\n            ]:\n                os.environ.pop(key, None)\n            hierarchy = _DummyHierarchyManager({\"history\": [{\"a\": 1}, {\"b\": 2}, {\"c\": 3}], \"current\": {}, \"runtime\": {}})\n            builder = ContextBuilder(hierarchy, {}, _DummyConfigLoader(), llm_client=None)\n            selected, visible_count, total_count = builder._select_user_history_entries(hierarchy.get_context()[\"history\"])\n\n            self.assertEqual(visible_count, 1)\n            self.assertEqual(total_count, 3)\n            self.assertEqual(selected, [{\"c\": 3}])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_thinking_prompt_contract.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\n\nfrom services.llm_client import LLMResponse\nfrom services.thinking_agent import ThinkingAgent\n\n\nclass _StubThinkingLLMClient:\n    def resolve_model(self, category, preferred_model=None):\n        return preferred_model or \"demo-model\"\n\n    def resolve_tool_choice(self, category, model):\n        return \"none\"\n\n    def chat(self, **kwargs):\n        return LLMResponse(\n            status=\"success\",\n            output=\"ok\",\n            tool_calls=[],\n            model=\"demo-model\",\n            finish_reason=\"stop\",\n        )\n\n\nclass ThinkingPromptContractTests(unittest.TestCase):\n    def setUp(self):\n        self.temp_dir = tempfile.TemporaryDirectory()\n        self.addCleanup(self.temp_dir.cleanup)\n        self.original_user_data_root = os.environ.get(\"MLA_USER_DATA_ROOT\")\n        os.environ[\"MLA_USER_DATA_ROOT\"] = self.temp_dir.name\n        self.addCleanup(self._restore_user_data_root)\n\n    def _restore_user_data_root(self):\n        if self.original_user_data_root is None:\n            os.environ.pop(\"MLA_USER_DATA_ROOT\", None)\n        else:\n            os.environ[\"MLA_USER_DATA_ROOT\"] = self.original_user_data_root\n\n    def test_thinking_system_prompt_requires_inner_content_only(self):\n        with patch(\"services.thinking_agent.SimpleLLMClient\", return_value=_StubThinkingLLMClient()):\n            agent = ThinkingAgent()\n        prompt = agent.system_prompt\n\n        self.assertIn(\"写入<当前进度思考>标签内部的正文内容\", prompt)\n        self.assertIn(\"不要输出<当前进度思考>外层标签本身\", prompt)\n        self.assertNotIn(\"首次进行构造，你的输出不需要包含<当前进度思考>标签\", prompt)\n\n    def test_initial_analysis_request_requires_inner_content_only(self):\n        with patch(\"services.thinking_agent.SimpleLLMClient\", return_value=_StubThinkingLLMClient()):\n            agent = ThinkingAgent()\n        captured = {}\n\n        def fake_chat(**kwargs):\n            captured[\"history\"] = kwargs[\"history\"]\n            return LLMResponse(\n                status=\"success\",\n                output=\"ok\",\n                tool_calls=[],\n                model=\"demo-model\",\n                finish_reason=\"stop\",\n            )\n\n        with patch.object(agent.llm_client, \"chat\", side_effect=fake_chat):\n            agent.analyze_first_thinking_detail(\n                task_description=\"hello\",\n                agent_system_prompt=\"dummy prompt\",\n                available_tools=[\"file_write\"],\n                tools_config={},\n            )\n\n        history = captured[\"history\"]\n        self.assertEqual(len(history), 1)\n        request_text = history[0].content\n        self.assertIn(\"只输出标签内部内容\", request_text)\n        self.assertIn(\"不要输出<当前进度思考>外层标签\", request_text)\n        self.assertNotIn(\"只需要输出<当前进度思考>内的内容即可\", request_text)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_tool_hooks.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport json\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom core.tool_executor import ToolExecutor\nfrom utils.config_loader import ConfigLoader\nfrom utils.user_paths import runtime_env_scope\nfrom core.hierarchy_manager import get_hierarchy_manager\n\n\nclass ToolHooksTests(unittest.TestCase):\n    def test_after_hook_triggers_with_result_filter(self):\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp = Path(temp_dir)\n            callback_file = temp / \"hook_callback.py\"\n            sink = temp / \"events.jsonl\"\n            callback_file.write_text(\n                \"\\n\".join([\n                    \"import json\",\n                    f\"SINK = {str(sink)!r}\",\n                    \"def on_tool_event(payload):\",\n                    \"    with open(SINK, 'a', encoding='utf-8') as fh:\",\n                    \"        fh.write(json.dumps(payload, ensure_ascii=False) + '\\\\n')\",\n                ]),\n                encoding=\"utf-8\",\n            )\n\n            hooks = [{\n                \"name\": \"final-only\",\n                \"when\": \"after\",\n                \"tool_names\": [\"final_output\"],\n                \"callback\": f\"{callback_file}:on_tool_event\",\n                \"result_filters\": {\"status\": \"success\"},\n            }]\n            root = temp / \"root\"\n            task_id = str((temp / \"task\").resolve())\n            with runtime_env_scope({\n                \"MLA_USER_DATA_ROOT\": str(root),\n                \"MLA_TOOL_HOOKS_JSON\": json.dumps(hooks, ensure_ascii=False),\n            }):\n                executor = ToolExecutor(ConfigLoader(\"OpenCowork\"), get_hierarchy_manager(task_id))\n                executor.set_agent_context(agent_id=\"agent_demo\", agent_name=\"alpha_agent\")\n                result = executor.execute(\"final_output\", {\"status\": \"success\", \"output\": \"ok\"}, task_id)\n\n            self.assertEqual(result[\"status\"], \"success\")\n            lines = sink.read_text(encoding=\"utf-8\").strip().splitlines()\n            self.assertEqual(len(lines), 1)\n            payload = json.loads(lines[0])\n            self.assertEqual(payload[\"tool_name\"], \"final_output\")\n            self.assertEqual(payload[\"when\"], \"after\")\n            self.assertEqual(payload[\"result\"][\"output\"], \"ok\")\n            self.assertEqual(payload[\"agent_id\"], \"agent_demo\")\n            self.assertEqual(payload[\"agent_level\"], 0)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/test_web_ui_config_api.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom __future__ import annotations\n\nimport importlib.util\nimport os\nimport sys\nfrom pathlib import Path\n\n\nSERVER_PATH = Path(__file__).resolve().parents[1] / \"web_ui\" / \"server\" / \"server.py\"\n\n\ndef _load_web_server(tmp_path):\n    os.environ[\"WEB_UI_USER_DATA_ROOT\"] = str(tmp_path)\n    for key in [\"user_runtime\", \"server\", \"mla_web_ui_server_test\"]:\n        sys.modules.pop(key, None)\n    spec = importlib.util.spec_from_file_location(\"mla_web_ui_server_test\", SERVER_PATH)\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\ndef _auth_client(app):\n    client = app.test_client()\n    with client.session_transaction() as session:\n        session[\"logged_in\"] = True\n        session[\"username\"] = \"tester\"\n        session[\"role\"] = \"admin\"\n    return client\n\n\ndef test_guided_config_roundtrip_and_run_env_list(tmp_path):\n    module = _load_web_server(tmp_path)\n    client = _auth_client(module.app)\n\n    list_resp = client.get(\"/api/config/list?type=run_env\")\n    assert list_resp.status_code == 200\n    names = [item[\"name\"] for item in list_resp.get_json()[\"files\"]]\n    assert \"llm_config.yaml\" in names\n    assert \"app_config.json\" in names\n\n    guided_resp = client.get(\"/api/config/guided\")\n    assert guided_resp.status_code == 200\n    payload = guided_resp.get_json()\n    assert \"llm_config\" in payload\n    assert \"app_config\" in payload\n\n    payload[\"llm_config\"][\"base_url\"] = \"https://openrouter.ai/api/v1\"\n    payload[\"llm_config\"][\"models\"] = [\n        {\"name\": \"openrouter/google/gemini-3-flash-preview\", \"tool_choice\": \"required\"}\n    ]\n    payload[\"app_config\"].setdefault(\"runtime\", {})[\"thinking_enabled\"] = False\n    payload[\"app_config\"].setdefault(\"runtime\", {})[\"thinking_steps\"] = 9\n    payload[\"app_config\"].setdefault(\"context\", {})[\"user_history_recent_items\"] = 4\n\n    save_resp = client.post(\n        \"/api/config/guided\",\n        json={\n            \"llm_config\": payload[\"llm_config\"],\n            \"app_config\": payload[\"app_config\"],\n        },\n    )\n    assert save_resp.status_code == 200\n    assert save_resp.get_json()[\"success\"] is True\n\n    app_cfg_resp = client.get(\"/api/config/read?file=app_config.json&type=run_env\")\n    assert app_cfg_resp.status_code == 200\n    app_cfg_text = app_cfg_resp.get_json()[\"content\"]\n    assert '\"thinking_enabled\": false' in app_cfg_text\n    assert '\"user_history_recent_items\": 4' in app_cfg_text\n\n    llm_cfg_resp = client.get(\"/api/config/read?file=llm_config.yaml&type=run_env\")\n    assert llm_cfg_resp.status_code == 200\n    llm_cfg_text = llm_cfg_resp.get_json()[\"content\"]\n    assert \"openrouter/google/gemini-3-flash-preview\" in llm_cfg_text\n"
  },
  {
    "path": "tool_server_lite/__init__.py",
    "content": "\"\"\"Runtime tools package for MLA direct-tools execution.\"\"\"\n\n__version__ = \"1.0.0\"\n\n"
  },
  {
    "path": "tool_server_lite/llm_client_lite.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n轻量级多模态LLM客户端 - 专供tool_server使用\n支持：文本、图片、音频等多模态输入\n\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport yaml\nimport base64\nfrom pathlib import Path\nfrom typing import Optional\nfrom litellm import completion\nimport litellm\n\nfrom utils.user_paths import ensure_user_llm_config_exists\n\n# 尝试导入 transcribe，如果不支持则使用替代方案\ntry:\n    from litellm import transcribe\n    HAS_TRANSCRIBE = True\nexcept ImportError:\n    HAS_TRANSCRIBE = False\n    # 如果没有transcribe，需要使用openai直接调用\n    try:\n        import openai\n        HAS_OPENAI = True\n    except ImportError:\n        HAS_OPENAI = False\n\n\nclass LLMClientLite:\n    \"\"\"轻量级多模态LLM客户端 - 供tool_server工具使用\"\"\"\n    \n    def __init__(self, llm_config_path: str = None):\n        \"\"\"\n        初始化LLM客户端\n        \n        Args:\n            llm_config_path: LLM配置文件路径，默认读取项目配置\n        \"\"\"\n        # 加载LLM配置\n        if llm_config_path is None:\n            llm_config_path = str(ensure_user_llm_config_exists())\n        \n        if not os.path.exists(llm_config_path):\n            raise FileNotFoundError(f\"LLM配置文件不存在: {llm_config_path}\")\n        \n        # 保存配置文件路径（用于后续可能的重载）\n        self.config_path = llm_config_path\n        \n        with open(llm_config_path, 'r', encoding='utf-8') as f:\n            self.config = yaml.safe_load(f)\n        \n        # 读取配置\n        self.base_url = self.config.get(\"base_url\", \"\")\n        self.api_key = self.config.get(\"api_key\", \"\")\n        self.temperature = self.config.get(\"temperature\", 0)\n        self.max_tokens = self.config.get(\"max_tokens\", 0)\n        \n        # 解析模型配置（支持字符串和对象格式，对象格式可覆盖 api_key/base_url）\n        self.model_configs = {}  # 模型名称 -> {api_key?, base_url?, ...}\n        self.default_models = {}\n        self.models = []\n        self.figure_models = []\n        self.compressor_models = []\n        self.read_figure_models = []\n        self._parse_models(self.config.get(\"models\", []), self.models, \"execution\")\n        self._parse_models(self.config.get(\"figure_models\", []), self.figure_models, \"image_generation\")\n        self._parse_models(self.config.get(\"compressor_models\", []), self.compressor_models, \"compressor\")\n        self._parse_models(self.config.get(\"read_figure_models\", []), self.read_figure_models, \"read_figure\")\n        \n        # 回退逻辑：未配置的模型类别回退到 models\n        if not self.figure_models:\n            self.figure_models = list(self.models)\n        if not self.compressor_models:\n            self.compressor_models = list(self.models)\n        if not self.read_figure_models:\n            self.read_figure_models = list(self.models)\n        self.default_models.setdefault(\"execution\", self.models[0] if self.models else \"\")\n        self.default_models.setdefault(\"image_generation\", self.figure_models[0] if self.figure_models else \"\")\n        self.default_models.setdefault(\"compressor\", self.compressor_models[0] if self.compressor_models else \"\")\n        self.default_models.setdefault(\"read_figure\", self.read_figure_models[0] if self.read_figure_models else \"\")\n        \n        if not self.api_key:\n            raise ValueError(\"未配置API密钥\")\n        \n        if not self.models:\n            raise ValueError(\"未配置可用模型列表\")\n        \n        # 配置LiteLLM\n        litellm.set_verbose = False\n        litellm.drop_params = True\n        \n        print(f\"✅ LLM客户端配置已加载: {llm_config_path}\")\n    \n    def _parse_models(self, models_config: list, target_list: list, category: str):\n        \"\"\"解析模型配置，支持字符串和对象格式\"\"\"\n        default_name = \"\"\n        for item in models_config:\n            if isinstance(item, str):\n                target_list.append(item)\n                if item not in self.model_configs:\n                    self.model_configs[item] = {}\n                if not default_name:\n                    default_name = item\n            elif isinstance(item, dict):\n                name = item.get(\"name\")\n                if name:\n                    target_list.append(name)\n                    self.model_configs[name] = {k: v for k, v in item.items() if k != \"name\"}\n                    if self.model_configs[name].get(\"default\") is True:\n                        default_name = name\n                    elif not default_name:\n                        default_name = name\n        if default_name:\n            self.default_models[category] = default_name\n\n    def resolve_model(self, category: str = \"execution\", preferred: Optional[str] = None) -> str:\n        model_groups = {\n            \"execution\": self.models,\n            \"image_generation\": self.figure_models or self.models,\n            \"compressor\": self.compressor_models or self.models,\n            \"read_figure\": self.read_figure_models or self.models,\n        }\n        candidates = model_groups.get(category, self.models) or self.models\n        preferred_name = str(preferred or \"\").strip()\n        if preferred_name and preferred_name in candidates:\n            return preferred_name\n        default_name = str(self.default_models.get(category) or \"\").strip()\n        if default_name and default_name in candidates:\n            return default_name\n        return candidates[0] if candidates else preferred_name\n    \n    def _get_model_api_key(self, model: str) -> str:\n        \"\"\"获取模型的 api_key（优先模型级别，回退全局）\"\"\"\n        return self.model_configs.get(model, {}).get(\"api_key\", self.api_key)\n    \n    def _get_model_base_url(self, model: str) -> str:\n        \"\"\"获取模型的 base_url（优先模型级别，回退全局）\"\"\"\n        return self.model_configs.get(model, {}).get(\"base_url\", self.base_url)\n\n    @staticmethod\n    def _is_openrouter_base_url(base_url: Optional[str]) -> bool:\n        return bool(base_url and 'openrouter' in str(base_url).lower())\n\n    @staticmethod\n    def _normalize_openrouter_model_name(model: str, base_url: Optional[str]) -> str:\n        normalized = str(model or \"\").strip()\n        if not normalized:\n            return normalized\n        if not LLMClientLite._is_openrouter_base_url(base_url):\n            return normalized\n        if normalized.startswith(\"openrouter/\"):\n            return normalized\n        return f\"openrouter/{normalized}\"\n\n    @staticmethod\n    def _extract_image_urls_from_completion_message(message) -> list[str]:\n        results: list[str] = []\n        if message is None:\n            return results\n\n        if hasattr(message, 'images') and message.images:\n            for image in message.images:\n                if isinstance(image, dict):\n                    image_url = image.get('image_url', {}).get('url')\n                    if image_url:\n                        results.append(image_url)\n                elif hasattr(image, 'image_url'):\n                    url = getattr(image.image_url, 'url', None)\n                    if url:\n                        results.append(url)\n\n        if not results and hasattr(message, 'content') and isinstance(message.content, list):\n            for part in message.content:\n                if isinstance(part, dict) and part.get('type') == 'image_url':\n                    url = part.get('image_url', {}).get('url')\n                    if url:\n                        results.append(url)\n\n        return results\n\n    def _create_image_via_litellm_completion(\n        self,\n        prompt: str,\n        model: str,\n        reference_images: Optional[list[str]] = None,\n        size: str = \"1024x1024\",\n    ) -> str | list[str]:\n        has_reference = reference_images and len(reference_images) > 0\n\n        content = [{\"type\": \"text\", \"text\": prompt}] if has_reference else prompt\n        if has_reference:\n            for img_path_str in reference_images:\n                img_path = Path(img_path_str)\n                with open(img_path, \"rb\") as image_file:\n                    image_data = base64.b64encode(image_file.read()).decode('utf-8')\n\n                suffix = img_path.suffix.lower()\n                mime_type_map = {\n                    '.jpg': 'image/jpeg',\n                    '.jpeg': 'image/jpeg',\n                    '.png': 'image/png',\n                    '.gif': 'image/gif',\n                    '.webp': 'image/webp'\n                }\n                mime_type = mime_type_map.get(suffix, 'image/jpeg')\n                content.append({\n                    \"type\": \"image_url\",\n                    \"image_url\": {\n                        \"url\": f\"data:{mime_type};base64,{image_data}\"\n                    }\n                })\n\n        model_api_key = self._get_model_api_key(model)\n        model_base_url = self._get_model_base_url(model)\n        normalized_model = self._normalize_openrouter_model_name(model, model_base_url)\n\n        kwargs = {\n            \"model\": normalized_model,\n            \"messages\": [{\"role\": \"user\", \"content\": content}],\n            \"api_key\": model_api_key,\n            \"timeout\": 300,\n            \"modalities\": [\"image\", \"text\"]\n        }\n\n        if model_base_url and model_base_url.strip():\n            kwargs[\"api_base\"] = model_base_url\n\n        if size and \"x\" in size:\n            width, height = map(int, size.split(\"x\"))\n            from math import gcd\n            g = gcd(width, height)\n            ratio_w, ratio_h = width // g, height // g\n            aspect_ratio = f\"{ratio_w}:{ratio_h}\"\n            if aspect_ratio in [\"1:1\", \"2:3\", \"3:2\", \"3:4\", \"4:3\", \"4:5\", \"5:4\", \"9:16\", \"16:9\", \"21:9\"]:\n                kwargs[\"extra_body\"] = {\"image_config\": {\"aspect_ratio\": aspect_ratio}}\n\n        response = completion(**kwargs)\n        if not getattr(response, 'choices', None):\n            raise Exception(\"响应格式异常\")\n\n        message = response.choices[0].message\n        results = self._extract_image_urls_from_completion_message(message)\n        if results:\n            print(f\"[INFO] LiteLLM 成功生成 {len(results)} 张图片\")\n            return results[0] if len(results) == 1 else results\n\n        raise Exception(\n            f\"LiteLLM completion 未在响应中找到图片。\"\n            f\" model={getattr(response, 'model', 'unknown')}, \"\n            f\"content_type={type(getattr(message, 'content', None)).__name__}\"\n        )\n\n    def _create_image_via_openrouter_sdk(\n        self,\n        prompt: str,\n        model: str,\n        reference_images: Optional[list[str]] = None,\n        size: str = \"1024x1024\",\n        n: int = 1,\n    ) -> str | list[str]:\n        has_reference = reference_images and len(reference_images) > 0\n\n        from openai import OpenAI\n\n        client = OpenAI(\n            base_url=self._get_model_base_url(model),\n            api_key=self._get_model_api_key(model),\n        )\n\n        if has_reference:\n            content = [{\"type\": \"text\", \"text\": prompt}]\n\n            for img_path_str in reference_images:\n                img_path = Path(img_path_str)\n                if not img_path.exists():\n                    raise FileNotFoundError(f\"参考图片不存在: {img_path_str}\")\n\n                with open(img_path, \"rb\") as image_file:\n                    image_data = base64.b64encode(image_file.read()).decode('utf-8')\n\n                suffix = img_path.suffix.lower()\n                mime_type_map = {\n                    '.jpg': 'image/jpeg',\n                    '.jpeg': 'image/jpeg',\n                    '.png': 'image/png',\n                    '.gif': 'image/gif',\n                    '.webp': 'image/webp'\n                }\n                mime_type = mime_type_map.get(suffix, 'image/jpeg')\n\n                content.append({\n                    \"type\": \"image_url\",\n                    \"image_url\": {\n                        \"url\": f\"data:{mime_type};base64,{image_data}\"\n                    }\n                })\n        else:\n            content = prompt\n\n        extra_body = {\"modalities\": [\"image\", \"text\"]}\n\n        if size and \"x\" in size:\n            width, height = map(int, size.split(\"x\"))\n            from math import gcd\n            g = gcd(width, height)\n            ratio_w, ratio_h = width // g, height // g\n            aspect_ratio = f\"{ratio_w}:{ratio_h}\"\n            if aspect_ratio in [\"1:1\", \"2:3\", \"3:2\", \"3:4\", \"4:3\", \"4:5\", \"5:4\", \"9:16\", \"16:9\", \"21:9\"]:\n                extra_body[\"image_config\"] = {\"aspect_ratio\": aspect_ratio}\n\n        response = client.chat.completions.create(\n            model=model,\n            messages=[{\"role\": \"user\", \"content\": content}],\n            extra_body=extra_body\n        )\n\n        message = response.choices[0].message\n        results = []\n        if hasattr(message, 'images') and message.images:\n            for image in message.images:\n                if isinstance(image, dict):\n                    image_url = image.get('image_url', {}).get('url')\n                    if image_url:\n                        results.append(image_url)\n                elif hasattr(image, 'image_url'):\n                    url = getattr(image.image_url, 'url', None)\n                    if url:\n                        results.append(url)\n\n        if results:\n            print(f\"[INFO] OpenRouter SDK 成功生成 {len(results)} 张图片\")\n            return results[0] if n == 1 else results\n\n        raise Exception(f\"响应中没有 images 字段。Message 属性: {dir(message)}\")\n    \n    def reload_config(self):\n        \"\"\"\n        重新加载配置文件\n        \n        用于在运行时更新配置而无需重启服务\n        \"\"\"\n        print(f\"🔄 重新加载配置文件: {self.config_path}\")\n        \n        if not os.path.exists(self.config_path):\n            raise FileNotFoundError(f\"配置文件不存在: {self.config_path}\")\n        \n        with open(self.config_path, 'r', encoding='utf-8') as f:\n            self.config = yaml.safe_load(f)\n        \n        # 更新配置\n        self.base_url = self.config.get(\"base_url\", \"\")\n        self.api_key = self.config.get(\"api_key\", \"\")\n        self.temperature = self.config.get(\"temperature\", 0)\n        self.max_tokens = self.config.get(\"max_tokens\", 0)\n        \n        # 重新解析模型配置\n        self.model_configs = {}\n        self.models = []\n        self.figure_models = []\n        self.compressor_models = []\n        self.read_figure_models = []\n        self.default_models = {}\n        self._parse_models(self.config.get(\"models\", []), self.models, \"execution\")\n        self._parse_models(self.config.get(\"figure_models\", []), self.figure_models, \"image_generation\")\n        self._parse_models(self.config.get(\"compressor_models\", []), self.compressor_models, \"compressor\")\n        self._parse_models(self.config.get(\"read_figure_models\", []), self.read_figure_models, \"read_figure\")\n        \n        if not self.api_key:\n            raise ValueError(\"未配置API密钥\")\n        \n        if not self.models:\n            raise ValueError(\"未配置可用模型列表\")\n        \n        print(f\"✅ 配置已重新加载\")\n    \n    def vision_query(\n        self,\n        image_path: str,\n        question: str = \"请描述这张图片的内容\",\n        model: Optional[str] = None\n    ) -> str:\n        \"\"\"\n        调用Vision模型分析图片\n        \n        Args:\n            image_path: 图片文件路径（绝对路径）\n            question: 要问的问题\n            model: 模型名称，默认使用配置中的第一个可用模型\n            \n        Returns:\n            LLM的响应文本\n            \n        Raises:\n            FileNotFoundError: 图片文件不存在\n            Exception: LLM调用失败\n        \"\"\"\n        # 检查图片文件\n        img_path = Path(image_path)\n        if not img_path.exists():\n            raise FileNotFoundError(f\"图片文件不存在: {image_path}\")\n        \n        # 读取并编码图片\n        with open(img_path, \"rb\") as image_file:\n            image_data = base64.b64encode(image_file.read()).decode('utf-8')\n        \n        # 判断图片格式\n        suffix = img_path.suffix.lower()\n        mime_type_map = {\n            '.jpg': 'image/jpeg',\n            '.jpeg': 'image/jpeg',\n            '.png': 'image/png',\n            '.gif': 'image/gif',\n            '.webp': 'image/webp'\n        }\n        mime_type = mime_type_map.get(suffix, 'image/jpeg')\n        \n        # 构建Vision消息\n        messages = [{\n            \"role\": \"user\",\n            \"content\": [\n                {\n                    \"type\": \"text\",\n                    \"text\": question\n                },\n                {\n                    \"type\": \"image_url\",\n                    \"image_url\": {\n                        \"url\": f\"data:{mime_type};base64,{image_data}\"\n                    }\n                }\n            ]\n        }]\n        \n        # 选择模型\n        if model is None:\n            model = self.resolve_model(\"read_figure\")\n        \n        # 调用LLM\n        try:\n            response = completion(\n                model=model,\n                messages=messages,\n                temperature=self.temperature,\n                api_key=self._get_model_api_key(model),\n                api_base=self._get_model_base_url(model),\n                timeout=300  # 5分钟超时保护\n            )\n            \n            # 提取响应\n            if response.choices and len(response.choices) > 0:\n                return response.choices[0].message.content\n            else:\n                raise Exception(\"LLM响应格式异常：缺少choices字段\")\n                \n        except Exception as e:\n            raise Exception(f\"调用LLM Vision API失败: {str(e)}\")\n\n    def create_image(\n        self,\n        prompt: str,\n        model: Optional[str] = None,\n        reference_images: Optional[list[str]] = None,\n        size: str = \"1024x1024\",\n        n: int = 1,\n        response_format: str = \"b64_json\"\n    ) -> str | list[str]:\n        \"\"\"\n        调用模型生成图片（支持参考图）\n        \n        Args:\n            prompt: 提示词\n            model: 模型名称，默认使用 figure_models 中的第一个\n            reference_images: 参考图片路径列表（可选），用于图片编辑/风格迁移\n            size: 图片尺寸，默认 \"1024x1024\"\n            n: 生成图片数量，默认 1\n            response_format: 返回格式 \"b64_json\" 或 \"url\"，默认 \"b64_json\"\n            \n        Returns:\n            单图时返回一个 base64 数据 URL 或 HTTP URL\n            多图时返回 URL 列表\n            \n        Note:\n            - OpenRouter: 使用 chat.completions + modalities (+ 参考图)\n            - 其他 API: 使用 litellm.image_generation() (纯生成) 或 litellm.image_edit() (有参考图)\n        \"\"\"\n        if model is None:\n            if self.figure_models:\n                model = self.resolve_model(\"image_generation\")\n            else:\n                model = \"dall-e-3\"\n        \n        try:\n            has_reference = reference_images and len(reference_images) > 0\n            print(f\"[INFO] 调用图片生成 API: {model}\")\n            if has_reference:\n                print(f\"[INFO] 参考图片数量: {len(reference_images)}\")\n            if self.base_url:\n                print(f\"[INFO] 使用自定义端点: {self.base_url}\")\n            \n            # 判断是否是 OpenRouter\n            model_base_url = self._get_model_base_url(model)\n            is_openrouter = self._is_openrouter_base_url(model_base_url)\n            \n            if is_openrouter:\n                # OpenRouter: 优先用 LiteLLM completion 统一处理；若当前运行环境/返回结构不稳定，再回退原生 SDK。\n                print(f\"[INFO] 使用 OpenRouter 方式（LiteLLM 优先，SDK 兜底）\")\n                try:\n                    return self._create_image_via_litellm_completion(\n                        prompt=prompt,\n                        model=model,\n                        reference_images=reference_images,\n                        size=size,\n                    )\n                except Exception as litellm_error:\n                    print(f\"[WARN] LiteLLM OpenRouter 图片生成失败，回退 SDK: {litellm_error}\")\n                    return self._create_image_via_openrouter_sdk(\n                        prompt=prompt,\n                        model=model,\n                        reference_images=reference_images,\n                        size=size,\n                        n=n,\n                    )\n            \n            else:\n                # 其他供应商（Gemini等）：统一使用 litellm.completion()\n                print(f\"[INFO] 使用 litellm.completion() 方式\")\n                return self._create_image_via_litellm_completion(\n                    prompt=prompt,\n                    model=model,\n                    reference_images=reference_images,\n                    size=size,\n                )\n                \n        except Exception as e:\n            raise Exception(f\"生成图片失败: {str(e)}\")\n    \n    def audio_query(\n        self,\n        audio_path: str,\n        question: str = \"请描述这段音频的内容\",\n        model: Optional[str] = None\n    ) -> str:\n        \"\"\"\n        调用Audio模型分析音频\n        \n        Args:\n            audio_path: 音频文件路径（绝对路径）\n            question: 要问的问题\n            model: 模型名称，默认使用配置中的第一个可用模型\n            \n        Returns:\n            LLM的响应文本（包含转录内容和分析结果）\n            \n        Raises:\n            FileNotFoundError: 音频文件不存在\n            Exception: LLM调用失败\n        \n        流程:\n        1. 使用 Whisper API 将音频转录为文本\n        2. 根据问题分析转录内容并返回结果\n        \"\"\"\n        # 检查音频文件\n        audio_file = Path(audio_path)\n        if not audio_file.exists():\n            raise FileNotFoundError(f\"音频文件不存在: {audio_path}\")\n        \n        # 判断音频格式\n        suffix = audio_file.suffix.lower()\n        supported_formats = {\n            '.mp3': 'audio/mpeg',\n            '.mp4': 'audio/mp4',\n            '.mpeg': 'audio/mpeg',\n            '.mpga': 'audio/mpeg',\n            '.m4a': 'audio/mp4',\n            '.wav': 'audio/wav',\n            '.webm': 'audio/webm'\n        }\n        \n        if suffix not in supported_formats:\n            raise ValueError(f\"不支持的音频格式: {suffix}。支持的格式: {', '.join(supported_formats.keys())}\")\n        \n        # 选择模型\n        if model is None:\n            model = self.models[0]\n        \n        try:\n            # 步骤1: 转录音频为文本\n            print(f\"📝 正在转录音频: {audio_path}\")\n            \n            transcript_text = \"\"\n            \n            if HAS_TRANSCRIBE:\n                # 使用 litellm 的 transcribe 功能\n                transcript = litellm.transcribe(\n                    model=\"whisper-1\",\n                    file=str(audio_file),\n                    api_key=self.api_key,\n                    api_base=self.base_url,\n                    timeout=300  # 5分钟超时保护\n                )\n                \n                # 提取转录文本\n                if isinstance(transcript, dict) and 'text' in transcript:\n                    transcript_text = transcript['text']\n                elif isinstance(transcript, str):\n                    transcript_text = transcript\n                else:\n                    transcript_text = str(transcript)\n            \n            elif HAS_OPENAI:\n                # 使用 OpenAI 直接调用\n                with open(audio_file, \"rb\") as f:\n                    transcript = openai.Audio.transcribe(\n                        \"whisper-1\",\n                        f,\n                        api_key=self.api_key,\n                        api_base=self.base_url if self.base_url else None\n                    )\n                    transcript_text = transcript['text']\n            \n            else:\n                raise Exception(\"未安装必要的库（litellm 或 openai）\")\n            \n            print(f\"✅ 转录完成，文本长度: {len(transcript_text)} 字符\")\n            \n            # 步骤2: 对转录内容进行分析\n            messages = [{\n                \"role\": \"user\",\n                \"content\": f\"以下是音频转录内容：\\n\\n{transcript_text}\\n\\n请回答以下问题：{question}\"\n            }]\n            \n            response = completion(\n                model=model,\n                messages=messages,\n                temperature=self.temperature,\n                api_key=self._get_model_api_key(model),\n                api_base=self._get_model_base_url(model),\n                timeout=300  # 5分钟超时保护\n            )\n            \n            # 提取响应\n            if response.choices and len(response.choices) > 0:\n                analysis_result = response.choices[0].message.content\n                \n                # 返回包含转录和分析的完整结果\n                return f\"【音频转录】\\n{transcript_text}\\n\\n【分析结果】\\n{analysis_result}\"\n            else:\n                raise Exception(\"LLM响应格式异常：缺少choices字段\")\n                \n        except Exception as e:\n            raise Exception(f\"调用音频分析API失败: {str(e)}\")\n    \n    def text_query(\n        self,\n        text: str,\n        question: str,\n        model: Optional[str] = None\n    ) -> str:\n        \"\"\"\n        通用文本分析（适用于论文、文档等长文本）\n        \n        Args:\n            text: 要分析的文本内容\n            question: 问题或指令\n            model: 模型名称，默认使用配置中的第一个可用模型\n            \n        Returns:\n            LLM的响应文本\n            \n        Raises:\n            Exception: LLM调用失败\n        \"\"\"\n        # 构建消息\n        messages = [{\n            \"role\": \"user\",\n            \"content\": f\"以下是内容：\\n\\n{text}\\n\\n{question}\"\n        }]\n        \n        # 选择模型\n        if model is None:\n            model = self.models[0]\n        \n        # 调用LLM\n        try:\n            response = completion(\n                model=model,\n                messages=messages,\n                temperature=self.temperature,\n                api_key=self._get_model_api_key(model),\n                api_base=self._get_model_base_url(model),\n                timeout=300  # 5分钟超时保护\n            )\n            \n            # 提取响应\n            if response.choices and len(response.choices) > 0:\n                return response.choices[0].message.content\n            else:\n                raise Exception(\"LLM响应格式异常：缺少choices字段\")\n                \n        except Exception as e:\n            raise Exception(f\"调用LLM文本分析API失败: {str(e)}\")\n\n\n# 全局单例（延迟初始化，支持配置文件热重载）\n_client_instance: Optional[LLMClientLite] = None\n_config_file_path: Optional[str] = None\n_config_file_mtime: Optional[float] = None\n\n\ndef get_llm_client(force_reload: bool = False) -> LLMClientLite:\n    \"\"\"\n    获取LLM客户端单例（支持配置文件热重载）\n    \n    Args:\n        force_reload: 是否强制重新加载配置\n    \n    Returns:\n        LLMClientLite实例\n        \n    Note:\n        - 自动检测配置文件修改时间，如果配置文件被修改，会自动重新加载\n        - 也可以通过 force_reload=True 强制重新加载\n    \"\"\"\n    global _client_instance, _config_file_path, _config_file_mtime\n    \n    # 确定配置文件路径\n    if _config_file_path is None:\n        _config_file_path = str(ensure_user_llm_config_exists())\n    \n    # 检查配置文件是否存在\n    if not os.path.exists(_config_file_path):\n        if _client_instance is None:\n            raise FileNotFoundError(f\"配置文件不存在: {_config_file_path}\")\n        # 配置文件不存在但已有实例，返回现有实例\n        return _client_instance\n    \n    # 获取当前配置文件的修改时间\n    current_mtime = os.path.getmtime(_config_file_path)\n    \n    # 判断是否需要重新加载\n    need_reload = (\n        force_reload or \n        _client_instance is None or \n        _config_file_mtime is None or \n        current_mtime != _config_file_mtime\n    )\n    \n    if need_reload:\n        if _config_file_mtime is not None and current_mtime != _config_file_mtime:\n            print(f\"🔄 检测到配置文件变化，重新加载配置...\")\n        \n        _client_instance = LLMClientLite()\n        _config_file_mtime = current_mtime\n    \n    return _client_instance\n\n\ndef reload_llm_client() -> LLMClientLite:\n    \"\"\"\n    强制重新加载LLM客户端配置\n    \n    Returns:\n        重新加载后的LLMClientLite实例\n    \"\"\"\n    return get_llm_client(force_reload=True)\n\n\nif __name__ == \"__main__\":\n    # 测试LLM客户端 - 图片编辑功能\n    try:\n        client = get_llm_client()\n        print(f\"✅ LLM客户端初始化成功\")\n        print(f\"   可用模型: {client.models}\")\n        print(f\"   图片生成模型: {client.figure_models}\")\n        print(f\"   Base URL: {client.base_url}\")\n        print(\"\\n\" + \"=\"*60)\n        \n        # 测试图片生成（带参考图）：融合两张图\n        print(\"\\n🎨 测试图片生成功能（带参考图）：融合两张图表...\")\n        \n        image1_path = \"/Users/chenglin/Desktop/research/agent_framwork/vscode_version/web-use/test_image/7.1.png\"\n        image2_path = \"/Users/chenglin/Desktop/research/agent_framwork/vscode_version/web-use/test_image/7.2.png\"\n        \n        prompt = \"\"\"\n        请将这两张数据可视化图表融合成一张综合图表。\n        \n        要求：\n        1. 保留两张图的核心信息和数据点\n        2. 使用统一的配色方案\n        3. 合理布局，上下或左右排列\n        4. 添加清晰的标题说明这是算法性能对比分析\n        5. 确保图例和坐标轴标签清晰可读\n        \"\"\"\n        \n        output_path = \"/Users/chenglin/Desktop/research/agent_framwork/vscode_version/web-use/test_image/7_merged.png\"\n        \n        print(f\"📷 参考图片1: {image1_path}\")\n        print(f\"📷 参考图片2: {image2_path}\")\n        print(f\"💾 输出路径: {output_path}\")\n        print(f\"📝 提示词: {prompt.strip()[:100]}...\")\n        \n        result = client.create_image(\n            prompt=prompt,\n            reference_images=[image1_path, image2_path],\n            size=\"1792x1024\",  # 16:9 比例，适合宽屏展示\n            n=1,\n            response_format=\"b64_json\"\n        )\n        \n        # 保存结果\n        import base64\n        if isinstance(result, str):\n            # 单个结果\n            if result.startswith(\"data:\"):\n                # base64 格式\n                image_data = result.split(\",\")[1]\n            else:\n                image_data = result\n            \n            image_bytes = base64.b64decode(image_data)\n            with open(output_path, 'wb') as f:\n                f.write(image_bytes)\n            \n            print(f\"\\n✅ 图片编辑成功！\")\n            print(f\"   保存位置: {output_path}\")\n            print(f\"   文件大小: {len(image_bytes) / 1024:.2f} KB\")\n        else:\n            # 多个结果\n            print(f\"\\n✅ 生成了 {len(result)} 张图片\")\n            for idx, img_data in enumerate(result):\n                save_path = output_path.replace(\".png\", f\"_{idx}.png\")\n                if img_data.startswith(\"data:\"):\n                    img_data = img_data.split(\",\")[1]\n                image_bytes = base64.b64decode(img_data)\n                with open(save_path, 'wb') as f:\n                    f.write(image_bytes)\n                print(f\"   图片 {idx+1}: {save_path}\")\n        \n    except Exception as e:\n        print(f\"\\n❌ 测试失败: {e}\")\n        import traceback\n        traceback.print_exc()\n"
  },
  {
    "path": "tool_server_lite/registry.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n统一工具运行时注册中心。\n\n职责：\n1. 提供 built-in 工具注册表（single source of truth）\n2. 扫描用户目录中的自定义 Python 工具并尝试加载\n3. 为 direct-tools 与 legacy HTTP tool server 提供同一份运行时注册表\n\"\"\"\n\nfrom __future__ import annotations\n\nimport importlib.util\nimport inspect\nimport traceback\nimport types\nimport uuid\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, List, Tuple\n\nfrom utils.user_paths import get_user_tools_library_root\nfrom tool_server_lite.tools.file_tools import BaseTool\n\n\nToolFactory = Callable[[], Any]\n\n\ndef _build_builtin_factories() -> Dict[str, ToolFactory]:\n    from tool_server_lite.tools import (\n        FileReadTool,\n        FileWriteTool,\n        DirListTool,\n        DirCreateTool,\n        FileMoveTool,\n        FileDeleteTool,\n        WebSearchTool,\n        GoogleScholarSearchTool,\n        ArxivSearchTool,\n        CrawlPageTool,\n        FileDownloadTool,\n        ParseDocumentTool,\n        VisionTool,\n        ImageReadTool,\n        CreateImageTool,\n        AudioTool,\n        PaperAnalyzeTool,\n        MarkdownToPdfTool,\n        MarkdownToDocxTool,\n        TexToPdfTool,\n        HumanInLoopTool,\n        ExecuteCommandTool,\n        GrepTool,\n        ReferenceListTool,\n        ReferenceAddTool,\n        ReferenceDeleteTool,\n        ImagesToPptTool,\n        LoadSkillTool,\n        OffloadSkillTool,\n        FreshTool,\n        AddMessageTool,\n        StartBackgroundTaskTool,\n        TaskShareContextPathTool,\n        ListTaskIdsTool,\n        TaskHistorySearchTool,\n    )\n\n    factories: Dict[str, ToolFactory] = {\n        \"file_read\": FileReadTool,\n        \"file_write\": FileWriteTool,\n        \"dir_list\": DirListTool,\n        \"dir_create\": DirCreateTool,\n        \"file_move\": FileMoveTool,\n        \"file_delete\": FileDeleteTool,\n        \"web_search\": WebSearchTool,\n        \"google_scholar_search\": GoogleScholarSearchTool,\n        \"arxiv_search\": ArxivSearchTool,\n        \"crawl_page\": CrawlPageTool,\n        \"file_download\": FileDownloadTool,\n        \"parse_document\": ParseDocumentTool,\n        \"vision_tool\": VisionTool,\n        \"image_read\": ImageReadTool,\n        \"create_image\": CreateImageTool,\n        \"audio_tool\": AudioTool,\n        \"paper_analyze_tool\": PaperAnalyzeTool,\n        \"md_to_pdf\": MarkdownToPdfTool,\n        \"md_to_docx\": MarkdownToDocxTool,\n        \"tex_to_pdf\": TexToPdfTool,\n        \"human_in_loop\": HumanInLoopTool,\n        \"execute_command\": ExecuteCommandTool,\n        \"grep\": GrepTool,\n        \"reference_list\": ReferenceListTool,\n        \"reference_add\": ReferenceAddTool,\n        \"reference_delete\": ReferenceDeleteTool,\n        \"images_to_ppt\": ImagesToPptTool,\n        \"load_skill\": LoadSkillTool,\n        \"offload_skill\": OffloadSkillTool,\n        \"fresh\": FreshTool,\n        \"add_message\": AddMessageTool,\n        \"start_background_task\": StartBackgroundTaskTool,\n        \"task_share_context_path\": TaskShareContextPathTool,\n        \"list_task_ids\": ListTaskIdsTool,\n        \"task_history_search\": TaskHistorySearchTool,\n    }\n\n    try:\n        from tool_server_lite.tools import (\n            BrowserLaunchTool,\n            BrowserCloseTool,\n            BrowserNewPageTool,\n            BrowserSwitchPageTool,\n            BrowserClosePageTool,\n            BrowserListPagesTool,\n            BrowserNavigateTool,\n            BrowserSnapshotTool,\n            BrowserExecuteJsTool,\n            BrowserClickTool,\n            BrowserTypeTool,\n            BrowserWaitTool,\n            BrowserMouseMoveTool,\n            BrowserMouseClickCoordsTool,\n            BrowserDragAndDropTool,\n            BrowserHoverTool,\n            BrowserScrollTool,\n        )\n\n        factories.update({\n            \"browser_launch\": BrowserLaunchTool,\n            \"browser_close\": BrowserCloseTool,\n            \"browser_new_page\": BrowserNewPageTool,\n            \"browser_switch_page\": BrowserSwitchPageTool,\n            \"browser_close_page\": BrowserClosePageTool,\n            \"browser_list_pages\": BrowserListPagesTool,\n            \"browser_navigate\": BrowserNavigateTool,\n            \"browser_snapshot\": BrowserSnapshotTool,\n            \"browser_execute_js\": BrowserExecuteJsTool,\n            \"browser_click\": BrowserClickTool,\n            \"browser_type\": BrowserTypeTool,\n            \"browser_wait\": BrowserWaitTool,\n            \"browser_mouse_move\": BrowserMouseMoveTool,\n            \"browser_mouse_click_coords\": BrowserMouseClickCoordsTool,\n            \"browser_drag_and_drop\": BrowserDragAndDropTool,\n            \"browser_hover\": BrowserHoverTool,\n            \"browser_scroll\": BrowserScrollTool,\n        })\n    except ImportError:\n        pass\n\n    return factories\n\n\ndef get_builtin_tool_factories() -> Dict[str, ToolFactory]:\n    return dict(_build_builtin_factories())\n\n\ndef _load_module_from_path(file_path: Path) -> types.ModuleType:\n    module_name = f\"mla_custom_tool_{file_path.stem}_{uuid.uuid4().hex}\"\n    spec = importlib.util.spec_from_file_location(module_name, str(file_path))\n    if spec is None or spec.loader is None:\n        raise ImportError(f\"无法为 {file_path.name} 创建模块规范\")\n    module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(module)\n    return module\n\n\ndef _is_valid_custom_tool_class(obj: Any, module_name: str) -> bool:\n    if not inspect.isclass(obj):\n        return False\n    if obj.__module__ != module_name:\n        return False\n    if obj is BaseTool:\n        return False\n    if obj.__name__.startswith(\"_\"):\n        return False\n    if not (hasattr(obj, \"execute\") or hasattr(obj, \"execute_async\")):\n        return False\n    return True\n\n\ndef _discover_custom_tool_class(module: types.ModuleType) -> type:\n    candidates = [\n        obj for _, obj in inspect.getmembers(module)\n        if _is_valid_custom_tool_class(obj, module.__name__)\n    ]\n    if not candidates:\n        raise ValueError(\"未找到符合约定的工具类（需要公开类并实现 execute 或 execute_async）\")\n    if len(candidates) > 1:\n        raise ValueError(\"检测到多个候选工具类，请保证每个文件只定义一个公开工具类\")\n    return candidates[0]\n\n\ndef _instantiate_custom_tool(file_path: Path) -> Tuple[str, Any, Dict[str, Any]]:\n    module = _load_module_from_path(file_path)\n    tool_cls = _discover_custom_tool_class(module)\n    tool = tool_cls()\n\n    tool_name = getattr(tool, \"name\", None) or getattr(tool_cls, \"name\", None) or file_path.stem\n    tool_name = str(tool_name).strip()\n    if not tool_name:\n        raise ValueError(\"工具名称为空，请设置类属性 name 或使用合法文件名\")\n\n    metadata = {\n        \"name\": tool_name,\n        \"source\": \"custom\",\n        \"path\": str(file_path),\n        \"class_name\": tool_cls.__name__,\n        \"status\": \"loaded\",\n        \"error\": \"\",\n    }\n    return tool_name, tool, metadata\n\n\n_registry_cache: Dict[str, Any] | None = None\n_registry_metadata_cache: Dict[str, Dict[str, Any]] | None = None\n_registry_failures_cache: List[Dict[str, Any]] | None = None\n\n\ndef build_runtime_registry() -> Tuple[Dict[str, Any], Dict[str, Dict[str, Any]], List[Dict[str, Any]]]:\n    registry: Dict[str, Any] = {}\n    metadata: Dict[str, Dict[str, Any]] = {}\n    failures: List[Dict[str, Any]] = []\n\n    for name, factory in get_builtin_tool_factories().items():\n        try:\n            registry[name] = factory()\n            metadata[name] = {\n                \"name\": name,\n                \"source\": \"builtin\",\n                \"path\": \"\",\n                \"class_name\": type(registry[name]).__name__,\n                \"status\": \"loaded\",\n                \"error\": \"\",\n            }\n        except Exception as exc:\n            failures.append({\n                \"name\": name,\n                \"source\": \"builtin\",\n                \"path\": \"\",\n                \"status\": \"error\",\n                \"error\": str(exc),\n                \"traceback\": traceback.format_exc(),\n            })\n\n    custom_root = get_user_tools_library_root()\n    custom_root.mkdir(parents=True, exist_ok=True)\n    for tool_dir in sorted(custom_root.iterdir()):\n        if not tool_dir.is_dir() or tool_dir.name.startswith(\".\"):\n            continue\n        py_files = [p for p in sorted(tool_dir.glob(\"*.py\")) if p.is_file()]\n        if not py_files:\n            failures.append({\n                \"name\": tool_dir.name,\n                \"source\": \"custom\",\n                \"path\": str(tool_dir),\n                \"status\": \"error\",\n                \"error\": \"工具目录中未找到 Python 文件\",\n                \"traceback\": \"\",\n            })\n            continue\n\n        if len(py_files) > 1:\n            failures.append({\n                \"name\": tool_dir.name,\n                \"source\": \"custom\",\n                \"path\": str(tool_dir),\n                \"status\": \"error\",\n                \"error\": \"工具目录中存在多个 Python 文件，请保持每个工具目录仅包含一个主工具文件\",\n                \"traceback\": \"\",\n            })\n            continue\n\n        file_path = py_files[0]\n        try:\n            tool_name, tool, tool_meta = _instantiate_custom_tool(file_path)\n            if tool_name in registry:\n                raise ValueError(f\"工具名冲突: {tool_name}\")\n            registry[tool_name] = tool\n            metadata[tool_name] = tool_meta\n        except Exception as exc:\n            failures.append({\n                \"name\": tool_dir.name,\n                \"source\": \"custom\",\n                \"path\": str(file_path),\n                \"status\": \"error\",\n                \"error\": str(exc),\n                \"traceback\": traceback.format_exc(),\n            })\n\n    return registry, metadata, failures\n\n\ndef reload_runtime_registry() -> Tuple[Dict[str, Any], Dict[str, Dict[str, Any]], List[Dict[str, Any]]]:\n    global _registry_cache, _registry_metadata_cache, _registry_failures_cache\n    _registry_cache, _registry_metadata_cache, _registry_failures_cache = build_runtime_registry()\n    return _registry_cache, _registry_metadata_cache, _registry_failures_cache\n\n\ndef get_runtime_registry(force_reload: bool = False) -> Dict[str, Any]:\n    global _registry_cache\n    if force_reload or _registry_cache is None:\n        reload_runtime_registry()\n    return dict(_registry_cache or {})\n\n\ndef get_runtime_registry_metadata(force_reload: bool = False) -> Dict[str, Dict[str, Any]]:\n    global _registry_metadata_cache\n    if force_reload or _registry_metadata_cache is None:\n        reload_runtime_registry()\n    return dict(_registry_metadata_cache or {})\n\n\ndef get_runtime_registry_failures(force_reload: bool = False) -> List[Dict[str, Any]]:\n    global _registry_failures_cache\n    if force_reload or _registry_failures_cache is None:\n        reload_runtime_registry()\n    return list(_registry_failures_cache or [])\n"
  },
  {
    "path": "tool_server_lite/requirements.txt",
    "content": "# 核心依赖\nlitellm==1.82.6          # 统一的LLM接口（与桌面后端打包版本保持一致）\npyyaml>=6.0             # YAML配置文件解析\ntiktoken>=0.5.0\nvirtualenv>=20.0.0      # 虚拟环境（兼容 Anaconda）\n\nfastapi>=0.104.0\nuvicorn[standard]>=0.24.0\npydantic>=2.0.0\nrequests>=2.31.0\nbeautifulsoup4>=4.12.0\nchardet>=5.2.0\npdfplumber>=0.10.0\npython-docx>=1.1.0\npython-pptx>=0.6.21\ncrawl4ai>=0.3.0\nddgs>=1.0.0\npyyaml>=6.0.0\narxiv>=2.0.0\nprompt_toolkit>=3.0.0\nrich>=13.0.0\npsutil>=5.9.0 \n\nplaywright>=1.40.0\n"
  },
  {
    "path": "tool_server_lite/tools/BROWSER_IMPROVEMENTS.md",
    "content": "# 浏览器工具反检测与人类行为模拟改进\n\n## 改进概述\n\n本次改进全面增强了浏览器工具的反检测能力和人类行为模拟，使其更难被网站的人机验证系统识别。\n\n---\n\n## 一、反检测改进（BrowserLaunchTool）\n\n### 1. 启动参数优化\n```python\n# 添加的反检测启动参数\n'--disable-blink-features=AutomationControlled'  # 禁用自动化控制特征\n'--disable-features=IsolateOrigins,site-per-process'\n'--disable-web-security'\n'--no-sandbox'\n'--disable-setuid-sandbox'\n# ... 等更多参数\n```\n\n### 2. 浏览器指纹伪装\n- **User-Agent**: 随机选择真实的浏览器 UA\n- **语言设置**: zh-CN, zh, en\n- **时区**: Asia/Shanghai\n- **权限**: geolocation, notifications\n\n### 3. JavaScript 注入反检测\n```javascript\n// 覆盖 navigator.webdriver（最关键）\nObject.defineProperty(navigator, 'webdriver', {\n    get: () => undefined\n});\n\n// 添加 Chrome 对象\nwindow.chrome = { runtime: {} };\n\n// 伪装 plugins、languages 等\n```\n\n**效果**: 浏览器看起来像普通用户的浏览器，而不是自动化工具。\n\n---\n\n## 二、人类行为模拟函数\n\n### 1. `_random_delay(min_ms, max_ms)`\n生成随机延迟，模拟人类操作的自然停顿。\n\n### 2. `_generate_bezier_curve(start, end, steps)`\n生成贝塞尔曲线路径，模拟真实的鼠标移动轨迹。\n\n**特点**:\n- 使用三次贝塞尔曲线\n- 添加随机控制点\n- 路径自然弯曲，不是直线\n\n### 3. `_human_like_mouse_move(page, target_x, target_y)`\n沿贝塞尔曲线移动鼠标到目标位置。\n\n### 4. `_human_like_click(page, selector/x/y, button, delay_ms)`\n模拟人类点击：\n1. 移动鼠标到目标（带随机偏移）\n2. 按下鼠标\n3. 随机延迟 50-150ms\n4. 释放鼠标\n5. 点击后随机延迟\n\n### 5. `_human_like_type(page, selector, text, delay_range)`\n模拟人类输入：\n- 逐字符输入\n- 每个字符间随机延迟\n- 10% 概率有更长停顿（模拟思考）\n\n---\n\n## 三、新增工具类\n\n### 1. BrowserMouseMoveTool\n**功能**: 鼠标移动到指定坐标\n\n**参数**:\n- `browser_id`: 浏览器会话ID\n- `x`, `y`: 目标坐标\n- `human_like`: 是否使用贝塞尔曲线移动（默认 True）\n\n**使用场景**: \n- 悬停触发菜单\n- 移动到特定位置准备点击\n\n---\n\n### 2. BrowserMouseClickCoordsTool\n**功能**: 在指定坐标位置点击\n\n**参数**:\n- `browser_id`: 浏览器会话ID\n- `x`, `y`: 点击坐标\n- `button`: 鼠标按钮 (\"left\", \"right\", \"middle\")\n- `click_count`: 点击次数（双击用2）\n- `human_like`: 是否使用人类化点击（默认 True）\n\n**使用场景**:\n- 点击动态生成的元素（无法用选择器定位）\n- 点击 Canvas 或 SVG 内的特定位置\n- 右键菜单操作\n\n---\n\n### 3. BrowserDragAndDropTool\n**功能**: 鼠标拖拽操作\n\n**参数**:\n- `browser_id`: 浏览器会话ID\n- `from_x`, `from_y`: 起始坐标\n- `to_x`, `to_y`: 目标坐标\n- `human_like`: 是否使用人类化拖拽（默认 True）\n\n**使用场景**:\n- 滑动验证码（如滑块验证）\n- 拖拽排序\n- 拖拽文件上传\n- 地图缩放/平移\n\n**人类化拖拽流程**:\n1. 移动到起点（贝塞尔曲线）\n2. 随机延迟 100-200ms\n3. 按下鼠标\n4. 沿贝塞尔曲线移动到终点\n5. 随机延迟 50-100ms\n6. 释放鼠标\n\n---\n\n### 4. BrowserHoverTool\n**功能**: 鼠标悬停操作\n\n**参数**:\n- `browser_id`: 浏览器会话ID\n- `selector` 或 `(x, y)`: 悬停位置\n- `duration_ms`: 悬停持续时间（默认 1000ms）\n- `human_like`: 是否使用人类化移动（默认 True）\n\n**使用场景**:\n- 触发悬停菜单\n- 查看 tooltip\n- 触发延迟加载内容\n\n---\n\n## 四、改进现有工具\n\n### 1. BrowserClickTool（改进）\n**新增参数**:\n- `human_like`: 是否使用人类化点击（默认 True）\n- `button`: 鼠标按钮选择\n\n**改进**:\n- 点击前移动鼠标（贝塞尔曲线）\n- 在元素中心附近随机偏移（±30%）\n- 随机按下/释放延迟\n- 点击后随机延迟\n\n---\n\n### 2. BrowserTypeTool（改进）\n**新增参数**:\n- `human_like`: 是否使用人类化输入（默认 True）\n- `delay_range`: 字符间延迟范围（默认 50-150ms）\n\n**改进**:\n- 逐字符输入（而非直接填充）\n- 每个字符间随机延迟\n- 偶尔有更长停顿（模拟思考）\n\n---\n\n## 五、使用示例\n\n### 示例1：处理滑块验证码\n```python\n# 1. 启动浏览器（自动反检测）\nbrowser_launch(headless=False)\n\n# 2. 导航到页面\nbrowser_navigate(browser_id=\"xxx\", url=\"https://example.com\")\n\n# 3. 拖动滑块（人类化拖拽）\nbrowser_drag_and_drop(\n    browser_id=\"xxx\",\n    from_x=100, from_y=200,  # 滑块起始位置\n    to_x=300, to_y=200,      # 滑块目标位置\n    human_like=True           # 使用贝塞尔曲线\n)\n```\n\n### 示例2：人类化登录\n```python\n# 1. 点击用户名输入框（人类化点击）\nbrowser_click(\n    browser_id=\"xxx\",\n    selector=\"#username\",\n    human_like=True\n)\n\n# 2. 输入用户名（逐字符，随机延迟）\nbrowser_type(\n    browser_id=\"xxx\",\n    selector=\"#username\",\n    text=\"myusername\",\n    human_like=True,\n    delay_range=(80, 200)  # 每个字符间延迟 80-200ms\n)\n\n# 3. 点击密码输入框\nbrowser_click(\n    browser_id=\"xxx\",\n    selector=\"#password\",\n    human_like=True\n)\n\n# 4. 输入密码\nbrowser_type(\n    browser_id=\"xxx\",\n    selector=\"#password\",\n    text=\"mypassword\",\n    human_like=True\n)\n\n# 5. 点击登录按钮\nbrowser_click(\n    browser_id=\"xxx\",\n    selector=\"button[type='submit']\",\n    human_like=True\n)\n```\n\n### 示例3：悬停菜单\n```python\n# 悬停在菜单上触发下拉菜单\nbrowser_hover(\n    browser_id=\"xxx\",\n    selector=\"#menu-item\",\n    duration_ms=1500,\n    human_like=True\n)\n\n# 点击子菜单项\nbrowser_click(\n    browser_id=\"xxx\",\n    selector=\"#submenu-item\",\n    human_like=True\n)\n```\n\n---\n\n## 六、反检测效果对比\n\n### 改进前\n```javascript\nnavigator.webdriver  // true ❌ 会被检测\nwindow.chrome        // undefined ❌ 会被检测\nnavigator.plugins    // [] ❌ 会被检测\n```\n\n### 改进后\n```javascript\nnavigator.webdriver  // undefined ✅ 正常浏览器\nwindow.chrome        // {runtime: {}} ✅ 正常浏览器\nnavigator.plugins    // [1,2,3,4,5] ✅ 正常浏览器\n```\n\n### 行为对比\n\n| 操作 | 改进前 | 改进后 |\n|------|--------|--------|\n| 鼠标移动 | 直线瞬移 ❌ | 贝塞尔曲线 ✅ |\n| 点击位置 | 元素中心 ❌ | 中心附近随机 ✅ |\n| 点击速度 | 瞬间按下释放 ❌ | 50-150ms延迟 ✅ |\n| 输入速度 | 瞬间填充 ❌ | 逐字符+随机延迟 ✅ |\n| 操作间隔 | 固定延迟 ❌ | 随机延迟 ✅ |\n\n---\n\n## 七、注意事项\n\n1. **性能权衡**: 人类化操作会增加执行时间，如果不需要反检测，可以设置 `human_like=False`\n\n2. **参数调整**: 可以根据需要调整延迟范围，例如：\n   - 快速操作: `delay_range=(30, 80)`\n   - 谨慎操作: `delay_range=(100, 300)`\n\n3. **组合使用**: 对于高风险操作（如登录、支付），建议：\n   - 使用 `human_like=True`\n   - 在操作间添加额外的 `browser_wait` 延迟\n   - 模拟真实用户的浏览行为（滚动、悬停等）\n\n4. **检测升级**: 如果网站升级了检测机制，可能需要进一步调整：\n   - 增加更多浏览器指纹伪装\n   - 调整行为参数（延迟、路径等）\n   - 添加更多随机性\n\n---\n\n## 八、技术细节\n\n### 贝塞尔曲线算法\n使用三次贝塞尔曲线公式：\n```\nB(t) = (1-t)³P₀ + 3(1-t)²tP₁ + 3(1-t)t²P₂ + t³P₃\n```\n其中：\n- P₀: 起点\n- P₁, P₂: 控制点（动态生成，添加随机性）\n- P₃: 终点\n- t: 0到1的参数\n\n### 随机性来源\n1. **路径随机**: 控制点位置随机偏移\n2. **速度随机**: 每个路径点间的延迟随机\n3. **位置随机**: 点击位置在元素内随机偏移\n4. **时间随机**: 所有延迟都有随机范围\n\n---\n\n## 九、未来改进方向\n\n1. **更多浏览器指纹**:\n   - Canvas 指纹\n   - WebGL 指纹\n   - 字体指纹\n\n2. **更复杂的行为模拟**:\n   - 滚动行为（加速度、惯性）\n   - 页面停留时间模拟\n   - 阅读行为模拟\n\n3. **机器学习轨迹**:\n   - 收集真实用户的鼠标轨迹\n   - 训练模型生成更逼真的轨迹\n\n4. **验证码专用工具**:\n   - 图片验证码识别\n   - 滑块验证码自动求解\n   - 点选验证码处理\n\n---\n\n## 十、总结\n\n本次改进显著提升了浏览器工具的反检测能力：\n\n✅ **反检测**: 隐藏自动化特征，伪装成真实浏览器  \n✅ **人类化**: 模拟真实的鼠标轨迹和操作节奏  \n✅ **灵活性**: 可选择是否启用人类化（性能 vs 安全）  \n✅ **功能完整**: 支持点击、输入、拖拽、悬停等所有常见操作  \n\n现在的浏览器工具可以更好地应对各种人机验证系统！\n\n"
  },
  {
    "path": "tool_server_lite/tools/FILE_READ_USAGE.md",
    "content": "# file_read 工具使用说明\n\n## 功能概述\n\n`file_read` 工具现在支持两种模式：\n1. **单文件模式**：读取单个文件的内容\n2. **多文件模式**：一次性读取多个文件的内容\n\n## 单文件模式\n\n### 基本用法\n\n```json\n{\n  \"path\": \"data/config.json\"\n}\n```\n\n### 指定行范围\n\n```json\n{\n  \"path\": \"src/main.py\",\n  \"start_line\": 10,\n  \"end_line\": 50\n}\n```\n\n### 自定义选项\n\n```json\n{\n  \"path\": \"docs/readme.txt\",\n  \"encoding\": \"utf-8\",\n  \"show_line_numbers\": false\n}\n```\n\n### 返回格式（带行号）\n\n```json\n[\n  {\n    \"line\": 1,\n    \"content\": \"# Configuration File\"\n  },\n  {\n    \"line\": 2,\n    \"content\": \"version: 1.0\"\n  }\n]\n```\n\n## 多文件模式\n\n### 基本用法\n\n```json\n{\n  \"path\": [\n    \"src/main.py\",\n    \"src/utils.py\",\n    \"data/config.json\"\n  ]\n}\n```\n\n### 返回格式\n\n```json\n{\n  \"total_files\": 3,\n  \"success_count\": 3,\n  \"error_count\": 0,\n  \"files\": {\n    \"src/main.py\": {\n      \"status\": \"success\",\n      \"content\": [\n        {\"line\": 1, \"content\": \"import os\"},\n        {\"line\": 2, \"content\": \"import sys\"}\n      ],\n      \"total_lines\": 100\n    },\n    \"src/utils.py\": {\n      \"status\": \"success\",\n      \"content\": [\n        {\"line\": 1, \"content\": \"def helper():\"},\n        {\"line\": 2, \"content\": \"    pass\"}\n      ],\n      \"total_lines\": 50\n    },\n    \"data/config.json\": {\n      \"status\": \"success\",\n      \"content\": [\n        {\"line\": 1, \"content\": \"{\"},\n        {\"line\": 2, \"content\": \"  \\\"version\\\": \\\"1.0\\\"\"},\n        {\"line\": 3, \"content\": \"}\"}\n      ],\n      \"total_lines\": 3\n    }\n  }\n}\n```\n\n### 部分文件失败的情况\n\n如果某些文件不存在或无法读取：\n\n```json\n{\n  \"total_files\": 3,\n  \"success_count\": 2,\n  \"error_count\": 1,\n  \"files\": {\n    \"src/main.py\": {\n      \"status\": \"success\",\n      \"content\": [...],\n      \"total_lines\": 100\n    },\n    \"src/missing.py\": {\n      \"status\": \"error\",\n      \"error\": \"File not found: src/missing.py\"\n    },\n    \"src/utils.py\": {\n      \"status\": \"success\",\n      \"content\": [...],\n      \"total_lines\": 50\n    }\n  },\n  \"errors\": [\n    \"File not found: src/missing.py\"\n  ]\n}\n```\n\n## 参数说明\n\n| 参数 | 类型 | 必需 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `path` 或 `file_path` | string \\| array | ✅ | - | 单个文件路径或文件路径数组 |\n| `start_line` | integer | ❌ | - | 起始行号（从1开始），多文件模式下应用于所有文件 |\n| `end_line` | integer | ❌ | - | 结束行号（包含），多文件模式下应用于所有文件 |\n| `encoding` | string | ❌ | auto-detect | 文件编码（如 utf-8、gbk） |\n| `show_line_numbers` | boolean | ❌ | true | 是否显示行号（JSON格式） |\n\n## 使用场景\n\n### 场景 1：对比多个配置文件\n\n```json\n{\n  \"path\": [\n    \"config/dev.yaml\",\n    \"config/prod.yaml\",\n    \"config/test.yaml\"\n  ]\n}\n```\n\n### 场景 2：读取项目的所有主要文件\n\n```json\n{\n  \"path\": [\n    \"README.md\",\n    \"package.json\",\n    \"src/index.ts\",\n    \"src/config.ts\"\n  ],\n  \"show_line_numbers\": false\n}\n```\n\n### 场景 3：批量读取代码文件的特定部分\n\n```json\n{\n  \"path\": [\n    \"src/module1.py\",\n    \"src/module2.py\",\n    \"src/module3.py\"\n  ],\n  \"start_line\": 1,\n  \"end_line\": 20\n}\n```\n\n## 注意事项\n\n1. **不要读取二进制文件**：如 PDF、Word、图片等，会返回错误\n2. **编码自动检测**：如果不指定 encoding，系统会自动检测文件编码\n3. **多文件模式**：即使某些文件读取失败，其他文件仍会正常返回\n4. **性能考虑**：一次读取大量大文件可能会比较慢，建议合理控制文件数量\n5. **参数兼容性**：支持 `path` 和 `file_path` 两种参数名（不同配置文件可能使用不同的参数名）\n\n## LLM 调用示例\n\n作为 LLM Agent，你可以这样调用：\n\n**读取单个文件：**\n```json\n{\n  \"tool_name\": \"file_read\",\n  \"parameters\": {\n    \"path\": \"data/results.json\"\n  }\n}\n```\n\n**同时读取多个相关文件：**\n```json\n{\n  \"tool_name\": \"file_read\",\n  \"parameters\": {\n    \"path\": [\n      \"experiments/exp1/results.json\",\n      \"experiments/exp2/results.json\",\n      \"experiments/exp3/results.json\"\n    ]\n  }\n}\n```\n\n这样可以一次性获取所有需要的文件内容，提高效率！\n\n"
  },
  {
    "path": "tool_server_lite/tools/__init__.py",
    "content": "\"\"\"轻量化工具集合\"\"\"\n\nfrom .file_tools import (\n    FileReadTool,\n    FileWriteTool,\n    DirListTool,\n    DirCreateTool,\n    FileMoveTool,\n    FileDeleteTool\n)\n\nfrom .web_tools import (\n    WebSearchTool,\n    GoogleScholarSearchTool,\n    CrawlPageTool,\n    FileDownloadTool\n)\n\nfrom .arxiv_tools import ArxivSearchTool\n\nfrom .document_tools import ParseDocumentTool\n\nfrom .vision_tools import VisionTool, ImageReadTool, CreateImageTool\n\nfrom .audio_tools import AudioTool\n\nfrom .paper_tools import PaperAnalyzeTool\n\nfrom .human_tools import HumanInLoopTool\n\nfrom .convert_tools import (\n    MarkdownToPdfTool,\n    MarkdownToDocxTool,\n    TexToPdfTool\n)\n\nfrom .code_tools import (\n    ExecuteCodeTool,\n    PipInstallTool,\n    ExecuteCommandTool,\n    GrepTool,\n    CodeProcessManagerTool\n)\n\nfrom .reference_tools import (\n    ReferenceListTool,\n    ReferenceAddTool,\n    ReferenceDeleteTool\n)\n\nfrom .powerpoint_tools import ImagesToPptTool\n\nfrom .skill_tools import LoadSkillTool, OffloadSkillTool, FreshTool\nfrom .task_tools import AddMessageTool, StartBackgroundTaskTool, TaskShareContextPathTool, ListTaskIdsTool, TaskHistorySearchTool\n\nfrom .browser_tools import (\n    BrowserLaunchTool,\n    BrowserCloseTool,\n    BrowserNewPageTool,\n    BrowserSwitchPageTool,\n    BrowserClosePageTool,\n    BrowserListPagesTool,\n    BrowserNavigateTool,\n    BrowserSnapshotTool,\n    BrowserExecuteJsTool,\n    BrowserClickTool,\n    BrowserTypeTool,\n    BrowserWaitTool,\n    BrowserMouseMoveTool,\n    BrowserMouseClickCoordsTool,\n    BrowserDragAndDropTool,\n    BrowserHoverTool,\n    BrowserScrollTool\n)\n\n__all__ = [\n    \"FileReadTool\",\n    \"FileWriteTool\",\n    \"DirListTool\",\n    \"DirCreateTool\",\n    \"FileMoveTool\",\n    \"FileDeleteTool\",\n    \"WebSearchTool\",\n    \"GoogleScholarSearchTool\",\n    \"ArxivSearchTool\",\n    \"CrawlPageTool\",\n    \"FileDownloadTool\",\n    \"ParseDocumentTool\",\n    \"VisionTool\",\n    \"ImageReadTool\",\n    \"CreateImageTool\",\n    \"AudioTool\",\n    \"PaperAnalyzeTool\",\n    \"MarkdownToPdfTool\",\n    \"MarkdownToDocxTool\",\n    \"TexToPdfTool\",\n    \"HumanInLoopTool\",\n    \"ExecuteCodeTool\",\n    \"PipInstallTool\",\n    \"ExecuteCommandTool\",\n    \"GrepTool\",\n    \"CodeProcessManagerTool\",\n    \"ReferenceListTool\",\n    \"ReferenceAddTool\",\n    \"ReferenceDeleteTool\",\n    \"ImagesToPptTool\",\n    \"BrowserLaunchTool\",\n    \"BrowserCloseTool\",\n    \"BrowserNewPageTool\",\n    \"BrowserSwitchPageTool\",\n    \"BrowserClosePageTool\",\n    \"BrowserListPagesTool\",\n    \"BrowserNavigateTool\",\n    \"BrowserSnapshotTool\",\n    \"BrowserExecuteJsTool\",\n    \"BrowserClickTool\",\n    \"BrowserTypeTool\",\n    \"BrowserWaitTool\",\n    \"BrowserMouseMoveTool\",\n    \"BrowserMouseClickCoordsTool\",\n    \"BrowserDragAndDropTool\",\n    \"BrowserHoverTool\",\n    \"BrowserScrollTool\",\n    \"LoadSkillTool\",\n    \"OffloadSkillTool\",\n    \"FreshTool\",\n    \"AddMessageTool\",\n    \"StartBackgroundTaskTool\",\n    \"TaskShareContextPathTool\",\n    \"ListTaskIdsTool\",\n    \"TaskHistorySearchTool\",\n]\n"
  },
  {
    "path": "tool_server_lite/tools/arxiv_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\narXiv 搜索工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\nimport re\nfrom .file_tools import BaseTool, get_abs_path\n\n# arXiv 导入\ntry:\n    import arxiv\n    ARXIV_AVAILABLE = True\nexcept ImportError:\n    ARXIV_AVAILABLE = False\n\n\nclass ArxivSearchTool(BaseTool):\n    \"\"\"arXiv 搜索工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        搜索 arXiv 论文\n        \n        Parameters:\n            query (str): 搜索关键词\n            max_results (int, optional): 最大结果数，默认10\n            sort_by (str, optional): 排序方式，默认 \"relevance\"\n                - \"relevance\": 相关性\n                - \"lastUpdatedDate\": 更新时间\n                - \"submittedDate\": 提交时间\n            sort_order (str, optional): 排序顺序，默认 \"descending\"\n                - \"descending\": 降序\n                - \"ascending\": 升序\n            save_path (str, optional): 保存结果的相对路径（.md文件）\n        \"\"\"\n        try:\n            if not ARXIV_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"arxiv not installed. Run: pip install arxiv\"\n                }\n            \n            query = parameters.get(\"query\")\n            max_results = parameters.get(\"max_results\", 10)\n            sort_by_str = parameters.get(\"sort_by\", \"relevance\")\n            sort_order_str = parameters.get(\"sort_order\", \"descending\")\n            save_path = parameters.get(\"save_path\")\n            \n            if not query:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"query is required\"\n                }\n            \n            # 转换排序参数\n            sort_by_map = {\n                \"relevance\": arxiv.SortCriterion.Relevance,\n                \"lastUpdatedDate\": arxiv.SortCriterion.LastUpdatedDate,\n                \"submittedDate\": arxiv.SortCriterion.SubmittedDate\n            }\n            sort_order_map = {\n                \"descending\": arxiv.SortOrder.Descending,\n                \"ascending\": arxiv.SortOrder.Ascending\n            }\n            \n            sort_by = sort_by_map.get(sort_by_str, arxiv.SortCriterion.Relevance)\n            sort_order = sort_order_map.get(sort_order_str, arxiv.SortOrder.Descending)\n            \n            # 搜索 arXiv\n            client = arxiv.Client()\n            search = arxiv.Search(\n                query=query,\n                max_results=max_results,\n                sort_by=sort_by,\n                sort_order=sort_order\n            )\n            \n            results = list(client.results(search))\n            \n            # 格式化为 Markdown\n            results_md = []\n            results_md.append(f\"# arXiv Search Results: {query}\\n\")\n            results_md.append(f\"**Total**: {len(results)} papers\\n\")\n            results_md.append(f\"**Sort By**: {sort_by_str}\\n\")\n            results_md.append(f\"**Sort Order**: {sort_order_str}\\n\")\n            \n            for i, paper in enumerate(results, 1):\n                results_md.append(f\"\\n---\\n\")\n                results_md.append(f\"## {i}. {paper.title}\\n\")\n                results_md.append(f\"**Authors**: {', '.join([author.name for author in paper.authors])}\\n\")\n                results_md.append(f\"**Published**: {paper.published.strftime('%Y-%m-%d')}\\n\")\n                results_md.append(f\"**Updated**: {paper.updated.strftime('%Y-%m-%d')}\\n\")\n                results_md.append(f\"**arXiv ID**: {paper.entry_id.split('/')[-1]}\\n\")\n                results_md.append(f\"**PDF URL**: {paper.pdf_url}\\n\")\n                \n                # 分类\n                if paper.categories:\n                    results_md.append(f\"**Categories**: {', '.join(paper.categories)}\\n\")\n                \n                # 摘要\n                results_md.append(f\"\\n**Abstract**:\\n\")\n                # 清理摘要中的多余空白\n                abstract = re.sub(r'\\s+', ' ', paper.summary).strip()\n                results_md.append(f\"{abstract}\\n\")\n            \n            results_text = '\\n'.join(results_md)\n            \n            # 保存到文件\n            if save_path:\n                # 生成包含搜索参数的文件名\n                save_path_obj = Path(save_path)\n                safe_query = re.sub(r'[^\\w\\s-]', '', query).strip()\n                safe_query = re.sub(r'[-\\s]+', '_', safe_query)[:50]\n                \n                new_filename = f\"{save_path_obj.stem}_{safe_query}_n{max_results}{save_path_obj.suffix}\"\n                final_save_path = str(save_path_obj.parent / new_filename)\n                \n                abs_save_path = get_abs_path(task_id, final_save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                \n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(results_text)\n                \n                output = f\"结果保存在 {final_save_path}\"\n            else:\n                output = results_text\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n"
  },
  {
    "path": "tool_server_lite/tools/audio_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nAudio分析工具 - 音频内容分析\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\n\nfrom .file_tools import BaseTool, get_abs_path\n\n# NOTE: 统一使用包内绝对导入，避免 direct-tools / PyInstaller 下找不到顶层模块。\nfrom tool_server_lite.llm_client_lite import get_llm_client\n\n\nclass AudioTool(BaseTool):\n    \"\"\"音频分析工具 - 调用LLM分析音频内容\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行Audio分析\n        \n        Parameters:\n            audio_path (str): 音频文件相对路径（相对于任务目录）\n            question (str, optional): 要问的问题，默认\"请描述这段音频的内容\"\n            model (str, optional): 模型名称，默认使用配置中的模型\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 分析结果文本\n            error: 错误信息（如有）\n        \"\"\"\n        try:\n            # 获取参数\n            audio_path = parameters.get(\"audio_path\")\n            question = parameters.get(\"question\", \"请描述这段音频的内容\")\n            model = parameters.get(\"model\")\n            \n            if not audio_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: audio_path\"\n                }\n            \n            # 转换为绝对路径\n            abs_audio_path = get_abs_path(task_id, audio_path)\n            \n            # 调用LLM客户端\n            llm_client = get_llm_client()\n            \n            try:\n                result = llm_client.audio_query(\n                    audio_path=str(abs_audio_path),\n                    question=question,\n                    model=model\n                )\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": result,\n                    \"error\": \"\"\n                }\n                \n            except NotImplementedError as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"音频分析功能尚未实现，请等待开发完成。\"\n                }\n            except FileNotFoundError as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"音频文件不存在: {str(e)}\"\n                }\n            except Exception as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Audio分析失败: {str(e)}\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行失败: {str(e)}\"\n            }\n\n"
  },
  {
    "path": "tool_server_lite/tools/browser_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n浏览器操作工具 - 基于 Playwright\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any, Optional, Tuple, List\nimport asyncio\nimport json\nimport uuid\nimport random\nimport math\nfrom datetime import datetime\nfrom .file_tools import BaseTool, get_abs_path\n\ntry:\n    from playwright.async_api import async_playwright, Browser, Page, BrowserContext\n    PLAYWRIGHT_AVAILABLE = True\nexcept ImportError:\n    PLAYWRIGHT_AVAILABLE = False\n\n# 全局浏览器会话管理\n# 格式: {browser_id: {browser, context, pages: {page_id: page}, active_page_id, task_id, created_at, auto_snapshot_task}}\nBROWSER_SESSIONS = {}\n\n\n# ============== 人类行为模拟函数 ==============\n\ndef _random_delay(min_ms: int = 50, max_ms: int = 150) -> float:\n    \"\"\"生成随机延迟（秒）\"\"\"\n    return random.randint(min_ms, max_ms) / 1000.0\n\n\ndef _generate_bezier_curve(start: Tuple[float, float], end: Tuple[float, float], \n                          steps: int = 20) -> List[Tuple[float, float]]:\n    \"\"\"\n    生成贝塞尔曲线路径，模拟真实的鼠标移动轨迹\n    \n    Args:\n        start: 起始坐标 (x, y)\n        end: 结束坐标 (x, y)\n        steps: 路径点数量\n    \n    Returns:\n        路径点列表 [(x1, y1), (x2, y2), ...]\n    \"\"\"\n    x0, y0 = start\n    x3, y3 = end\n    \n    # 生成两个控制点（添加随机性使轨迹更自然）\n    dx = x3 - x0\n    dy = y3 - y0\n    distance = math.sqrt(dx**2 + dy**2)\n    \n    # 控制点偏移（相对于直线路径）\n    offset_ratio = random.uniform(0.2, 0.4)\n    perpendicular_angle = math.atan2(dy, dx) + math.pi / 2\n    \n    # 控制点1（靠近起点）\n    t1 = 0.33\n    x1 = x0 + dx * t1 + math.cos(perpendicular_angle) * distance * offset_ratio * random.choice([-1, 1])\n    y1 = y0 + dy * t1 + math.sin(perpendicular_angle) * distance * offset_ratio * random.choice([-1, 1])\n    \n    # 控制点2（靠近终点）\n    t2 = 0.67\n    x2 = x0 + dx * t2 + math.cos(perpendicular_angle) * distance * offset_ratio * random.choice([-1, 1])\n    y2 = y0 + dy * t2 + math.sin(perpendicular_angle) * distance * offset_ratio * random.choice([-1, 1])\n    \n    # 生成贝塞尔曲线上的点\n    points = []\n    for i in range(steps + 1):\n        t = i / steps\n        # 三次贝塞尔曲线公式\n        x = ((1-t)**3 * x0 + \n             3 * (1-t)**2 * t * x1 + \n             3 * (1-t) * t**2 * x2 + \n             t**3 * x3)\n        y = ((1-t)**3 * y0 + \n             3 * (1-t)**2 * t * y1 + \n             3 * (1-t) * t**2 * y2 + \n             t**3 * y3)\n        points.append((round(x, 2), round(y, 2)))\n    \n    return points\n\n\nasync def _human_like_mouse_move(page: Page, target_x: float, target_y: float):\n    \"\"\"\n    模拟人类鼠标移动到目标位置\n    \n    Args:\n        page: Playwright 页面对象\n        target_x: 目标 x 坐标\n        target_y: 目标 y 坐标\n    \"\"\"\n    # 获取当前鼠标位置（假设从随机起点开始）\n    viewport = page.viewport_size\n    start_x = random.randint(0, viewport['width'] // 2)\n    start_y = random.randint(0, viewport['height'] // 2)\n    \n    # 生成贝塞尔曲线路径\n    path = _generate_bezier_curve((start_x, start_y), (target_x, target_y), steps=random.randint(15, 25))\n    \n    # 沿路径移动鼠标\n    for x, y in path:\n        await page.mouse.move(x, y)\n        # 随机延迟，模拟人类移动速度\n        await asyncio.sleep(random.uniform(0.001, 0.005))\n    \n    # 到达目标后稍微停顿\n    await asyncio.sleep(_random_delay(50, 100))\n\n\nasync def _human_like_click(page: Page, selector: str = None, x: float = None, y: float = None, \n                            button: str = \"left\", delay_ms: int = None):\n    \"\"\"\n    模拟人类点击行为\n    \n    Args:\n        page: Playwright 页面对象\n        selector: CSS 选择器（如果提供，则点击元素）\n        x, y: 坐标位置（如果提供，则点击坐标）\n        button: 鼠标按钮 (\"left\", \"right\", \"middle\")\n        delay_ms: 按下和释放之间的延迟（毫秒）\n    \"\"\"\n    if delay_ms is None:\n        delay_ms = random.randint(50, 150)\n    \n    if selector:\n        # 先移动到元素位置（带随机偏移）\n        element = page.locator(selector).first\n        box = await element.bounding_box()\n        if box:\n            # 在元素中心附近随机偏移\n            offset_x = random.uniform(-box['width'] * 0.3, box['width'] * 0.3)\n            offset_y = random.uniform(-box['height'] * 0.3, box['height'] * 0.3)\n            target_x = box['x'] + box['width'] / 2 + offset_x\n            target_y = box['y'] + box['height'] / 2 + offset_y\n        else:\n            raise Exception(f\"元素不可见或不存在: {selector}\")\n    elif x is not None and y is not None:\n        target_x, target_y = x, y\n    else:\n        raise Exception(\"必须提供 selector 或 (x, y) 坐标\")\n    \n    # 移动鼠标到目标位置\n    await _human_like_mouse_move(page, target_x, target_y)\n    \n    # 模拟按下、延迟、释放\n    await page.mouse.down(button=button)\n    await asyncio.sleep(delay_ms / 1000.0)\n    await page.mouse.up(button=button)\n    \n    # 点击后随机延迟\n    await asyncio.sleep(_random_delay(100, 300))\n\n\nasync def _human_like_type(page: Page, selector: str, text: str, delay_range: Tuple[int, int] = (50, 150)):\n    \"\"\"\n    模拟人类输入文本（逐字符输入，带随机延迟）\n    \n    Args:\n        page: Playwright 页面对象\n        selector: 输入框选择器\n        text: 要输入的文本\n        delay_range: 每个字符之间的延迟范围（毫秒）\n    \"\"\"\n    # 先点击输入框\n    await _human_like_click(page, selector=selector)\n    \n    # 逐字符输入\n    for char in text:\n        await page.keyboard.type(char)\n        # 随机延迟\n        delay = random.randint(*delay_range)\n        await asyncio.sleep(delay / 1000.0)\n        \n        # 偶尔有更长的停顿（模拟思考）\n        if random.random() < 0.1:  # 10% 概率\n            await asyncio.sleep(random.uniform(0.3, 0.8))\n\n\nasync def _auto_snapshot_loop(browser_id: str, task_id: str, interval_seconds: int):\n    \"\"\"定期快照循环\"\"\"\n    print(f\"[INFO] 启动自动快照循环: 每 {interval_seconds} 秒\")\n    \n    while browser_id in BROWSER_SESSIONS:\n        try:\n            await asyncio.sleep(interval_seconds)\n            \n            # 检查会话是否还存在\n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                break\n            \n            # 获取活跃页面\n            active_page_id = session[\"active_page_id\"]\n            page = session[\"pages\"][active_page_id]\n            \n            # 保存快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            print(f\"[INFO] 自动快照完成 ({browser_id}/{active_page_id})\")\n            \n        except Exception as e:\n            print(f\"[WARN] 自动快照失败: {e}\")\n            continue\n\n\ndef _get_browser_dir(task_id: str, browser_id: str) -> Path:\n    \"\"\"获取浏览器会话目录\"\"\"\n    workspace = Path(task_id)\n    browser_dir = workspace / \"temp\" / \"browser\" / browser_id\n    browser_dir.mkdir(parents=True, exist_ok=True)\n    return browser_dir\n\n\nasync def _save_screenshot(page: Page, browser_id: str, task_id: str):\n    \"\"\"保存当前页面截图\"\"\"\n    browser_dir = _get_browser_dir(task_id, browser_id)\n    screenshot_path = browser_dir / \"current.png\"\n    await page.screenshot(path=str(screenshot_path), full_page=True)\n    print(f\"[INFO] 截图已保存: {screenshot_path}\")\n\n\nasync def _save_page_snapshot(page: Page, browser_id: str, task_id: str):\n    \"\"\"保存完整的页面快照（截图 + 内容 + 元素信息）\"\"\"\n    await _save_screenshot(page, browser_id, task_id)\n    await _save_page_content(page, browser_id, task_id)\n    await _save_accessibility_tree(page, browser_id, task_id)\n\n\nasync def _save_page_content(page: Page, browser_id: str, task_id: str):\n    \"\"\"保存当前页面内容\"\"\"\n    browser_dir = _get_browser_dir(task_id, browser_id)\n    content_path = browser_dir / \"page_content.md\"\n    \n    # 提取页面文本内容\n    text_content = await page.evaluate(\"() => document.body.innerText\")\n    \n    with open(content_path, 'w', encoding='utf-8') as f:\n        f.write(f\"# {await page.title()}\\n\\n\")\n        f.write(f\"URL: {page.url}\\n\\n\")\n        f.write(f\"---\\n\\n\")\n        f.write(text_content)\n    \n    print(f\"[INFO] 页面内容已保存: {content_path}\")\n\n\nasync def _save_accessibility_tree(page: Page, browser_id: str, task_id: str):\n    \"\"\"保存可访问性树（包含可交互元素信息）\"\"\"\n    browser_dir = _get_browser_dir(task_id, browser_id)\n    elements_path = browser_dir / \"current_elements.json\"\n    \n    try:\n        # 方案1：使用 Playwright 的 Accessibility Snapshot\n        try:\n            snapshot = await page.accessibility.snapshot()\n            if snapshot:\n                # 扁平化 accessibility tree，提取可交互元素\n                interactive_elements = _flatten_accessibility_tree(snapshot)\n            else:\n                interactive_elements = []\n        except Exception as e:\n            print(f\"[WARN] Accessibility snapshot 失败，使用备用方案: {e}\")\n            interactive_elements = []\n        \n        # 方案2（备用）：使用 JavaScript 提取常见交互元素\n        js_elements = await page.evaluate(\"\"\"\n            () => {\n                const elements = [];\n                let counter = 0;\n                \n                // 辅助函数：生成选择器\n                const getSelector = (el) => {\n                    if (el.id) return `#${el.id}`;\n                    if (el.name) return `[name=\"${el.name}\"]`;\n                    \n                    // 尝试生成简单的选择器\n                    let selector = el.tagName.toLowerCase();\n                    if (el.className) {\n                        const classes = el.className.split(' ').filter(c => c && !c.includes(' '));\n                        if (classes.length > 0) {\n                            selector += '.' + classes.slice(0, 2).join('.');\n                        }\n                    }\n                    return selector;\n                };\n                \n                // 提取输入框\n                document.querySelectorAll('input:not([type=\"hidden\"]), textarea').forEach(el => {\n                    if (counter++ > 200) return;  // 限制数量\n                    elements.push({\n                        type: 'input',\n                        input_type: el.type || 'text',\n                        role: el.getAttribute('role') || 'textbox',\n                        selector: getSelector(el),\n                        id: el.id || '',\n                        name: el.name || '',\n                        placeholder: el.placeholder || '',\n                        value: el.value || '',\n                        aria_label: el.getAttribute('aria-label') || '',\n                        label_text: (() => {\n                            const label = el.labels?.[0] || document.querySelector(`label[for=\"${el.id}\"]`);\n                            return label ? label.innerText.trim() : '';\n                        })()\n                    });\n                });\n                \n                // 提取按钮\n                document.querySelectorAll('button, input[type=\"submit\"], input[type=\"button\"], [role=\"button\"]').forEach(el => {\n                    if (counter++ > 200) return;\n                    elements.push({\n                        type: 'button',\n                        role: 'button',\n                        selector: getSelector(el),\n                        id: el.id || '',\n                        text: (el.innerText || el.value || el.getAttribute('aria-label') || '').trim().substring(0, 100),\n                        aria_label: el.getAttribute('aria-label') || ''\n                    });\n                });\n                \n                // 提取链接（限制数量）\n                const links = Array.from(document.querySelectorAll('a[href]')).slice(0, 100);\n                links.forEach(el => {\n                    if (counter++ > 200) return;\n                    const text = el.innerText.trim();\n                    if (text) {  // 只保留有文字的链接\n                        elements.push({\n                            type: 'link',\n                            role: 'link',\n                            selector: getSelector(el),\n                            id: el.id || '',\n                            text: text.substring(0, 100),\n                            href: el.href\n                        });\n                    }\n                });\n                \n                // 提取下拉框\n                document.querySelectorAll('select').forEach(el => {\n                    if (counter++ > 200) return;\n                    const options = Array.from(el.options).map(opt => ({\n                        value: opt.value,\n                        text: opt.text\n                    }));\n                    elements.push({\n                        type: 'select',\n                        role: 'combobox',\n                        selector: getSelector(el),\n                        id: el.id || '',\n                        name: el.name || '',\n                        options: options.slice(0, 20)  // 限制选项数量\n                    });\n                });\n                \n                // 提取复选框和单选框\n                document.querySelectorAll('input[type=\"checkbox\"], input[type=\"radio\"]').forEach(el => {\n                    if (counter++ > 200) return;\n                    elements.push({\n                        type: el.type,\n                        role: el.type === 'checkbox' ? 'checkbox' : 'radio',\n                        selector: getSelector(el),\n                        id: el.id || '',\n                        name: el.name || '',\n                        checked: el.checked,\n                        value: el.value || '',\n                        label_text: (() => {\n                            const label = el.labels?.[0] || document.querySelector(`label[for=\"${el.id}\"]`);\n                            return label ? label.innerText.trim() : '';\n                        })()\n                    });\n                });\n                \n                return elements;\n            }\n        \"\"\")\n        \n        # 合并两种方案的结果\n        all_elements = interactive_elements + js_elements if interactive_elements else js_elements\n        \n        data = {\n            \"url\": page.url,\n            \"title\": await page.title(),\n            \"timestamp\": datetime.now().isoformat(),\n            \"interactive_elements\": all_elements,\n            \"total_elements\": len(all_elements),\n            \"note\": \"此列表包含页面可见的主要交互元素。对于复杂页面（iframe、动态加载），建议 Agent 结合 Vision 分析和 JavaScript 探测。\"\n        }\n        \n        with open(elements_path, 'w', encoding='utf-8') as f:\n            json.dump(data, f, indent=2, ensure_ascii=False)\n        \n        print(f\"[INFO] 可交互元素已保存: {elements_path} (共 {len(all_elements)} 个)\")\n        \n    except Exception as e:\n        print(f\"[WARN] 保存元素信息失败: {e}\")\n\n\ndef _flatten_accessibility_tree(node: dict, elements: list = None) -> list:\n    \"\"\"扁平化 accessibility tree，提取可交互元素\"\"\"\n    if elements is None:\n        elements = []\n    \n    if not node:\n        return elements\n    \n    # 提取当前节点（如果是可交互元素）\n    role = node.get('role', '')\n    if role in ['button', 'link', 'textbox', 'searchbox', 'combobox', 'checkbox', 'radio', 'menuitem']:\n        element_info = {\n            \"type\": role,\n            \"role\": role,\n            \"name\": node.get('name', ''),\n            \"value\": node.get('value', ''),\n            \"description\": node.get('description', ''),\n        }\n        elements.append(element_info)\n    \n    # 递归处理子节点\n    children = node.get('children', [])\n    for child in children:\n        _flatten_accessibility_tree(child, elements)\n    \n    return elements\n\n\nclass BrowserLaunchTool(BaseTool):\n    \"\"\"启动浏览器会话\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        启动浏览器会话\n        \n        Parameters:\n            headless (bool, optional): 是否无头模式，默认 False（显示浏览器）\n            width (int, optional): 窗口宽度，默认 1280\n            height (int, optional): 窗口高度，默认 800\n            auto_snapshot_interval (int, optional): 自动快照间隔（秒），默认 0（不自动快照）\n        \n        Returns:\n            browser_id: 浏览器会话ID\n        \"\"\"\n        try:\n            if not PLAYWRIGHT_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"playwright 未安装。请运行: pip install playwright && playwright install chromium\"\n                }\n            \n            headless = parameters.get(\"headless\", False)\n            width = parameters.get(\"width\", 1280)\n            height = parameters.get(\"height\", 800)\n            auto_snapshot_interval = parameters.get(\"auto_snapshot_interval\", 0)\n            \n            # 生成唯一的 browser_id\n            browser_id = f\"browser_{uuid.uuid4().hex[:8]}\"\n            \n            # 创建浏览器目录\n            browser_dir = _get_browser_dir(task_id, browser_id)\n            \n            # 反检测启动参数\n            launch_args = [\n                '--disable-blink-features=AutomationControlled',  # 禁用自动化控制特征\n                '--disable-features=IsolateOrigins,site-per-process',\n                '--disable-web-security',  # 可选：禁用某些安全检查\n                '--no-sandbox',\n                '--disable-setuid-sandbox',\n                '--disable-dev-shm-usage',\n                '--disable-accelerated-2d-canvas',\n                '--no-first-run',\n                '--no-zygote',\n                '--disable-gpu',\n            ]\n            \n            if not headless:\n                launch_args.append('--start-maximized')\n            \n            # 启动浏览器\n            playwright = await async_playwright().start()\n            browser = await playwright.chromium.launch(\n                headless=headless,\n                args=launch_args,\n                # 隐藏自动化特征\n                chromium_sandbox=False,\n            )\n            \n            # 真实的浏览器指纹\n            user_agents = [\n                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\n                'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\n                'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\n            ]\n            \n            # 创建上下文（带反检测参数）\n            context = await browser.new_context(\n                viewport={'width': width, 'height': height},\n                user_agent=random.choice(user_agents),\n                locale='zh-CN',\n                timezone_id='Asia/Shanghai',\n                permissions=['geolocation', 'notifications'],\n                # 添加真实的浏览器特征\n                has_touch=False,\n                is_mobile=False,\n                device_scale_factor=1,\n            )\n            \n            # 创建第一个页面\n            page = await context.new_page()\n            \n            # 注入反检测脚本（隐藏 webdriver 标志）\n            await page.add_init_script(\"\"\"\n                // 覆盖 navigator.webdriver\n                Object.defineProperty(navigator, 'webdriver', {\n                    get: () => undefined\n                });\n                \n                // 覆盖 Chrome 对象\n                window.chrome = {\n                    runtime: {}\n                };\n                \n                // 覆盖 permissions\n                const originalQuery = window.navigator.permissions.query;\n                window.navigator.permissions.query = (parameters) => (\n                    parameters.name === 'notifications' ?\n                        Promise.resolve({ state: Notification.permission }) :\n                        originalQuery(parameters)\n                );\n                \n                // 覆盖 plugins\n                Object.defineProperty(navigator, 'plugins', {\n                    get: () => [1, 2, 3, 4, 5]\n                });\n                \n                // 覆盖 languages\n                Object.defineProperty(navigator, 'languages', {\n                    get: () => ['zh-CN', 'zh', 'en']\n                });\n            \"\"\")\n            \n            # 注册到全局管理\n            BROWSER_SESSIONS[browser_id] = {\n                \"playwright\": playwright,\n                \"browser\": browser,\n                \"context\": context,\n                \"pages\": {\"page_0\": page},\n                \"active_page_id\": \"page_0\",\n                \"task_id\": task_id,\n                \"created_at\": datetime.now().isoformat(),\n                \"auto_snapshot_task\": None\n            }\n            \n            # 启动自动快照任务（如果配置了）\n            # if auto_snapshot_interval > 0:\n            #     snapshot_task = asyncio.create_task(\n            #         _auto_snapshot_loop(browser_id, task_id, auto_snapshot_interval)\n            #     )\n            #     BROWSER_SESSIONS[browser_id][\"auto_snapshot_task\"] = snapshot_task\n            #     print(f\"[INFO] 自动快照已启用: 每 {auto_snapshot_interval} 秒\")\n            \n            # 保存元数据\n            metadata = {\n                \"browser_id\": browser_id,\n                \"created_at\": datetime.now().isoformat(),\n                \"headless\": headless,\n                \"viewport\": {\"width\": width, \"height\": height}\n            }\n            \n            with open(browser_dir / \"metadata.json\", 'w', encoding='utf-8') as f:\n                json.dump(metadata, f, indent=2, ensure_ascii=False)\n            \n            print(f\"[INFO] 浏览器已启动: {browser_id}\")\n            print(f\"[INFO] 无头模式: {headless}\")\n            print(f\"[INFO] 窗口尺寸: {width}x{height}\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"浏览器已启动\\n- Browser ID: {browser_id}\\n- 初始页面: page_0\\n- 截图目录: temp/browser/{browser_id}/\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"启动浏览器失败: {str(e)}\"\n            }\n\n\nclass BrowserListSessionsTool(BaseTool):\n    \"\"\"列出所有浏览器会话\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        列出当前所有活跃的浏览器会话\n        \n        Parameters:\n            task_id_filter (str, optional): 只列出指定 task_id 的浏览器，不指定则列出所有\n        \"\"\"\n        try:\n            task_id_filter = parameters.get(\"task_id_filter\")\n            \n            sessions_info = []\n            for browser_id, session in BROWSER_SESSIONS.items():\n                # 过滤 task_id\n                if task_id_filter and session[\"task_id\"] != task_id_filter:\n                    continue\n                \n                info = {\n                    \"browser_id\": browser_id,\n                    \"task_id\": session[\"task_id\"],\n                    \"created_at\": session[\"created_at\"],\n                    \"pages_count\": len(session[\"pages\"]),\n                    \"active_page\": session[\"active_page_id\"],\n                    \"auto_snapshot_enabled\": session.get(\"auto_snapshot_task\") is not None\n                }\n                \n                # 获取活跃页面的 URL 和标题\n                active_page = session[\"pages\"][session[\"active_page_id\"]]\n                info[\"current_url\"] = active_page.url\n                info[\"current_title\"] = await active_page.title()\n                \n                sessions_info.append(info)\n            \n            if not sessions_info:\n                return {\n                    \"status\": \"success\",\n                    \"output\": \"当前没有活跃的浏览器会话\",\n                    \"error\": \"\"\n                }\n            \n            # 格式化输出\n            output_lines = [f\"活跃的浏览器会话（共 {len(sessions_info)} 个）：\\n\"]\n            for info in sessions_info:\n                output_lines.append(f\"🌐 {info['browser_id']}\")\n                output_lines.append(f\"   任务: {info['task_id']}\")\n                output_lines.append(f\"   创建时间: {info['created_at']}\")\n                output_lines.append(f\"   标签页数: {info['pages_count']}\")\n                output_lines.append(f\"   活跃页面: {info['active_page']}\")\n                output_lines.append(f\"   当前页: {info['current_title']}\")\n                output_lines.append(f\"   URL: {info['current_url']}\")\n                output_lines.append(f\"   自动快照: {'✅' if info['auto_snapshot_enabled'] else '❌'}\\n\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": \"\\n\".join(output_lines),\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"列出浏览器会话失败: {str(e)}\"\n            }\n\n\nclass BrowserCloseTool(BaseTool):\n    \"\"\"关闭浏览器会话\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        关闭浏览器会话\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            \n            if not browser_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 取消自动快照任务\n            if session.get(\"auto_snapshot_task\"):\n                session[\"auto_snapshot_task\"].cancel()\n                try:\n                    await session[\"auto_snapshot_task\"]\n                except asyncio.CancelledError:\n                    pass\n            \n            # 关闭浏览器\n            await session[\"context\"].close()\n            await session[\"browser\"].close()\n            await session[\"playwright\"].stop()\n            \n            # 从全局管理中移除\n            del BROWSER_SESSIONS[browser_id]\n            \n            print(f\"[INFO] 浏览器已关闭: {browser_id}\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"浏览器 {browser_id} 已关闭\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"关闭浏览器失败: {str(e)}\"\n            }\n\n\nclass BrowserNewPageTool(BaseTool):\n    \"\"\"新建标签页\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        新建标签页\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            \n            if not browser_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 创建新页面\n            page = await session[\"context\"].new_page()\n            \n            # 生成 page_id\n            page_count = len(session[\"pages\"])\n            page_id = f\"page_{page_count}\"\n            \n            # 注册页面\n            session[\"pages\"][page_id] = page\n            session[\"active_page_id\"] = page_id\n            \n            print(f\"[INFO] 新建标签页: {page_id}\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"新标签页已创建\\n- Page ID: {page_id}\\n- 当前总页数: {len(session['pages'])}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"新建标签页失败: {str(e)}\"\n            }\n\n\nclass BrowserSwitchPageTool(BaseTool):\n    \"\"\"切换到指定标签页\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        切换到指定标签页\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            page_id (str): 页面ID（如 'page_0', 'page_1'）\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            page_id = parameters.get(\"page_id\")\n            \n            if not browser_id or not page_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 page_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            if page_id not in session[\"pages\"]:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"页面不存在: {page_id}。可用页面: {list(session['pages'].keys())}\"\n                }\n            \n            # 切换活跃页面\n            session[\"active_page_id\"] = page_id\n            page = session[\"pages\"][page_id]\n            \n            # 更新完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            print(f\"[INFO] 已切换到标签页: {page_id}\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"已切换到标签页: {page_id}\\n- URL: {page.url}\\n- 标题: {await page.title()}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"切换标签页失败: {str(e)}\"\n            }\n\n\nclass BrowserClosePageTool(BaseTool):\n    \"\"\"关闭指定标签页\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        关闭指定标签页\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            page_id (str): 页面ID（如 'page_0', 'page_1'）\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            page_id = parameters.get(\"page_id\")\n            \n            if not browser_id or not page_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 page_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            if page_id not in session[\"pages\"]:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"页面不存在: {page_id}\"\n                }\n            \n            # 不能关闭唯一的页面\n            if len(session[\"pages\"]) == 1:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"不能关闭唯一的标签页。请使用 browser_close 关闭整个浏览器。\"\n                }\n            \n            # 关闭页面\n            page = session[\"pages\"][page_id]\n            await page.close()\n            del session[\"pages\"][page_id]\n            \n            # 如果关闭的是活跃页面，切换到第一个页面\n            if session[\"active_page_id\"] == page_id:\n                new_active = list(session[\"pages\"].keys())[0]\n                session[\"active_page_id\"] = new_active\n                \n                # 更新完整快照\n                active_page = session[\"pages\"][new_active]\n                await _save_page_snapshot(active_page, browser_id, task_id)\n            \n            print(f\"[INFO] 标签页已关闭: {page_id}\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"标签页 {page_id} 已关闭\\n- 剩余页面数: {len(session['pages'])}\\n- 当前活跃: {session['active_page_id']}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"关闭标签页失败: {str(e)}\"\n            }\n\n\nclass BrowserListPagesTool(BaseTool):\n    \"\"\"列出所有标签页\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        列出所有标签页\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            \n            if not browser_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 收集所有页面信息\n            pages_info = []\n            for page_id, page in session[\"pages\"].items():\n                info = {\n                    \"page_id\": page_id,\n                    \"url\": page.url,\n                    \"title\": await page.title(),\n                    \"is_active\": page_id == session[\"active_page_id\"]\n                }\n                pages_info.append(info)\n            \n            # 格式化输出\n            output_lines = [f\"浏览器 {browser_id} 的所有标签页：\\n\"]\n            for info in pages_info:\n                active_mark = \"🟢\" if info[\"is_active\"] else \"⚪\"\n                output_lines.append(f\"{active_mark} {info['page_id']}\")\n                output_lines.append(f\"   标题: {info['title']}\")\n                output_lines.append(f\"   URL: {info['url']}\\n\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": \"\\n\".join(output_lines),\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"列出标签页失败: {str(e)}\"\n            }\n\n\nclass BrowserNavigateTool(BaseTool):\n    \"\"\"导航到指定 URL\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        导航到指定 URL\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            url (str): 目标 URL\n            wait_until (str, optional): 等待条件，默认 \"load\"\n                - \"load\": 等待 load 事件\n                - \"domcontentloaded\": 等待 DOM 加载完成\n                - \"networkidle\": 等待网络空闲\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            url = parameters.get(\"url\")\n            wait_until = parameters.get(\"wait_until\", \"load\")\n            \n            if not browser_id or not url:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 url\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            active_page_id = session[\"active_page_id\"]\n            page = session[\"pages\"][active_page_id]\n            \n            # 导航\n            print(f\"[INFO] 导航到: {url}\")\n            await page.goto(url, wait_until=wait_until, timeout=30000)\n            \n            # 保存完整快照（截图 + 内容 + 元素）\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            title = await page.title()\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"导航成功\\n- URL: {url}\\n- 标题: {title}\\n- 活跃页面: {active_page_id}\\n- 截图: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"导航失败: {str(e)}\"\n            }\n\n\nclass BrowserSnapshotTool(BaseTool):\n    \"\"\"获取页面快照\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        获取当前页面快照\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            include_html (bool, optional): 是否包含 HTML 源码，默认 False\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            include_html = parameters.get(\"include_html\", False)\n            \n            if not browser_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            active_page_id = session[\"active_page_id\"]\n            page = session[\"pages\"][active_page_id]\n            \n            # 更新完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            # 获取页面信息\n            title = await page.title()\n            url = page.url\n            \n            # 提取文本内容\n            text_content = await page.evaluate(\"() => document.body.innerText\")\n            \n            output_lines = [\n                f\"页面快照（{active_page_id}）\",\n                f\"- 标题: {title}\",\n                f\"- URL: {url}\",\n                f\"- 截图: temp/browser/{browser_id}/current.png\",\n                f\"- 文本内容: temp/browser/{browser_id}/page_content.md\",\n                \"\"\n            ]\n            \n            if include_html:\n                html_content = await page.content()\n                browser_dir = _get_browser_dir(task_id, browser_id)\n                html_path = browser_dir / \"page_source.html\"\n                with open(html_path, 'w', encoding='utf-8') as f:\n                    f.write(html_content)\n                output_lines.append(f\"- HTML 源码: temp/browser/{browser_id}/page_source.html\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": \"\\n\".join(output_lines),\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"获取快照失败: {str(e)}\"\n            }\n\n\nclass BrowserExecuteJsTool(BaseTool):\n    \"\"\"执行 JavaScript 代码\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        在当前页面执行 JavaScript 代码\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            script (str): 要执行的 JavaScript 代码\n            save_result (bool, optional): 是否保存执行结果到文件，默认 False\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            script = parameters.get(\"script\")\n            save_result = parameters.get(\"save_result\", False)\n            \n            if not browser_id or not script:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 script\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            active_page_id = session[\"active_page_id\"]\n            page = session[\"pages\"][active_page_id]\n            \n            # 执行 JavaScript\n            print(f\"[INFO] 执行 JavaScript (页面 {active_page_id}):\")\n            print(f\"[INFO] {script[:100]}{'...' if len(script) > 100 else ''}\")\n            \n            result = await page.evaluate(script)\n            \n            # 等待页面稳定（给时间让 DOM 更新）\n            await page.wait_for_timeout(500)\n            \n            # 保存完整快照（截图 + 内容 + 元素）\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            # 格式化结果\n            result_str = json.dumps(result, ensure_ascii=False, indent=2) if result is not None else \"null\"\n            \n            # 保存结果到文件\n            if save_result and result is not None:\n                browser_dir = _get_browser_dir(task_id, browser_id)\n                result_path = browser_dir / \"js_result.json\"\n                with open(result_path, 'w', encoding='utf-8') as f:\n                    json.dump(result, f, ensure_ascii=False, indent=2)\n                result_info = f\"\\n- 结果已保存: temp/browser/{browser_id}/js_result.json\"\n            else:\n                result_info = \"\"\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"JavaScript 执行成功\\n- 返回值: {result_str[:500]}{'...' if len(result_str) > 500 else ''}\\n- 截图已更新: temp/browser/{browser_id}/current.png{result_info}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行 JavaScript 失败: {str(e)}\"\n            }\n\n\nclass BrowserClickTool(BaseTool):\n    \"\"\"点击页面元素（封装）\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        点击页面元素\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            selector (str): CSS 选择器\n            timeout (int, optional): 等待元素出现的超时时间（毫秒），默认 5000\n            human_like (bool, optional): 是否使用人类化点击，默认 True\n            button (str, optional): 鼠标按钮 (\"left\", \"right\", \"middle\")，默认 \"left\"\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            selector = parameters.get(\"selector\")\n            timeout = parameters.get(\"timeout\", 5000)\n            human_like = parameters.get(\"human_like\", True)\n            button = parameters.get(\"button\", \"left\")\n            \n            if not browser_id or not selector:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 selector\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            # 等待元素出现\n            print(f\"[INFO] 点击元素: {selector}\")\n            await page.wait_for_selector(selector, timeout=timeout)\n            \n            if human_like:\n                # 使用人类化点击\n                await _human_like_click(page, selector=selector, button=button)\n            else:\n                # 直接点击\n                await page.click(selector)\n            \n            # 等待页面稳定\n            await asyncio.sleep(_random_delay(300, 500))\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"点击成功: {selector}\\n- 点击方式: {'人类化' if human_like else '直接点击'}\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"点击失败: {str(e)}\"\n            }\n\n\nclass BrowserTypeTool(BaseTool):\n    \"\"\"在输入框输入文本（封装）\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        在输入框输入文本\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            selector (str): CSS 选择器\n            text (str): 要输入的文本\n            clear_first (bool, optional): 是否先清空，默认 True\n            human_like (bool, optional): 是否使用人类化输入（逐字符），默认 True\n            delay_range (tuple, optional): 字符间延迟范围（毫秒），默认 (50, 150)\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            selector = parameters.get(\"selector\")\n            text = parameters.get(\"text\")\n            clear_first = parameters.get(\"clear_first\", True)\n            human_like = parameters.get(\"human_like\", True)\n            delay_range = parameters.get(\"delay_range\", (50, 150))\n            \n            if not browser_id or not selector or text is None:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id, selector 或 text\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            # 输入文本\n            print(f\"[INFO] 在 {selector} 输入文本\")\n            \n            # 如果需要清空，先清空\n            if clear_first:\n                await page.fill(selector, \"\")\n            \n            if human_like:\n                # 使用人类化输入\n                await _human_like_type(page, selector, text, delay_range)\n            else:\n                # 快速输入\n                if clear_first:\n                    await page.fill(selector, text)\n                else:\n                    await page.type(selector, text, delay=0)\n            \n            # 等待页面稳定\n            await asyncio.sleep(_random_delay(300, 500))\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"文本输入成功: {selector}\\n- 输入方式: {'人类化（逐字符）' if human_like else '直接填充'}\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"输入文本失败: {str(e)}\"\n            }\n\n\nclass BrowserWaitTool(BaseTool):\n    \"\"\"等待条件满足\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        等待条件满足\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            wait_type (str): 等待类型\n                - \"selector\": 等待元素出现\n                - \"navigation\": 等待页面导航完成\n                - \"timeout\": 等待指定时间（毫秒）\n            selector (str, optional): CSS 选择器（wait_type=\"selector\" 时必需）\n            timeout (int, optional): 超时时间（毫秒），默认 30000\n            milliseconds (int, optional): 等待时长（wait_type=\"timeout\" 时必需）\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            wait_type = parameters.get(\"wait_type\")\n            selector = parameters.get(\"selector\")\n            timeout = parameters.get(\"timeout\", 30000)\n            milliseconds = parameters.get(\"milliseconds\")\n            \n            if not browser_id or not wait_type:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 wait_type\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            if wait_type == \"selector\":\n                if not selector:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": \"wait_type='selector' 时必须提供 selector 参数\"\n                    }\n                print(f\"[INFO] 等待元素出现: {selector}\")\n                await page.wait_for_selector(selector, timeout=timeout)\n            \n            elif wait_type == \"navigation\":\n                print(f\"[INFO] 等待页面导航完成\")\n                await page.wait_for_load_state(\"networkidle\", timeout=timeout)\n            \n            elif wait_type == \"timeout\":\n                if not milliseconds:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": \"wait_type='timeout' 时必须提供 milliseconds 参数\"\n                    }\n                print(f\"[INFO] 等待 {milliseconds} 毫秒\")\n                await page.wait_for_timeout(milliseconds)\n            \n            else:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"不支持的 wait_type: {wait_type}。可选: selector, navigation, timeout\"\n                }\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"等待完成: {wait_type}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"等待失败: {str(e)}\"\n            }\n\n\nclass BrowserMouseMoveTool(BaseTool):\n    \"\"\"鼠标移动到指定坐标\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        鼠标移动到指定坐标（模拟人类移动轨迹）\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            x (float): 目标 x 坐标\n            y (float): 目标 y 坐标\n            human_like (bool, optional): 是否使用人类化移动（贝塞尔曲线），默认 True\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            x = parameters.get(\"x\")\n            y = parameters.get(\"y\")\n            human_like = parameters.get(\"human_like\", True)\n            \n            if not browser_id or x is None or y is None:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id, x 或 y\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            print(f\"[INFO] 移动鼠标到: ({x}, {y})\")\n            \n            if human_like:\n                # 使用人类化移动\n                await _human_like_mouse_move(page, x, y)\n            else:\n                # 直接移动\n                await page.mouse.move(x, y)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"鼠标已移动到坐标: ({x}, {y})\\n- 移动方式: {'人类化轨迹' if human_like else '直接移动'}\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"鼠标移动失败: {str(e)}\"\n            }\n\n\nclass BrowserMouseClickCoordsTool(BaseTool):\n    \"\"\"在指定坐标位置点击\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        在指定坐标位置点击\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            x (float): 点击 x 坐标\n            y (float): 点击 y 坐标\n            button (str, optional): 鼠标按钮 (\"left\", \"right\", \"middle\")，默认 \"left\"\n            click_count (int, optional): 点击次数（双击用2），默认 1\n            human_like (bool, optional): 是否使用人类化点击，默认 True\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            x = parameters.get(\"x\")\n            y = parameters.get(\"y\")\n            button = parameters.get(\"button\", \"left\")\n            click_count = parameters.get(\"click_count\", 1)\n            human_like = parameters.get(\"human_like\", True)\n            \n            if not browser_id or x is None or y is None:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id, x 或 y\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            print(f\"[INFO] 在坐标 ({x}, {y}) 点击 {click_count} 次\")\n            \n            if human_like:\n                # 使用人类化点击\n                for _ in range(click_count):\n                    await _human_like_click(page, x=x, y=y, button=button)\n                    if click_count > 1:\n                        await asyncio.sleep(_random_delay(50, 150))\n            else:\n                # 直接点击\n                await page.mouse.click(x, y, button=button, click_count=click_count)\n            \n            # 等待页面稳定\n            await asyncio.sleep(_random_delay(300, 500))\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"坐标点击成功: ({x}, {y})\\n- 按钮: {button}\\n- 点击次数: {click_count}\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"坐标点击失败: {str(e)}\"\n            }\n\n\nclass BrowserDragAndDropTool(BaseTool):\n    \"\"\"鼠标拖拽操作\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        鼠标拖拽操作（从起点拖到终点）\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            from_x (float): 起始 x 坐标\n            from_y (float): 起始 y 坐标\n            to_x (float): 目标 x 坐标\n            to_y (float): 目标 y 坐标\n            human_like (bool, optional): 是否使用人类化拖拽，默认 True\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            from_x = parameters.get(\"from_x\")\n            from_y = parameters.get(\"from_y\")\n            to_x = parameters.get(\"to_x\")\n            to_y = parameters.get(\"to_y\")\n            human_like = parameters.get(\"human_like\", True)\n            \n            if not browser_id or from_x is None or from_y is None or to_x is None or to_y is None:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id, from_x, from_y, to_x 或 to_y\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            print(f\"[INFO] 拖拽: ({from_x}, {from_y}) -> ({to_x}, {to_y})\")\n            \n            if human_like:\n                # 人类化拖拽\n                # 1. 移动到起点\n                await _human_like_mouse_move(page, from_x, from_y)\n                await asyncio.sleep(_random_delay(100, 200))\n                \n                # 2. 按下鼠标\n                await page.mouse.down()\n                await asyncio.sleep(_random_delay(50, 100))\n                \n                # 3. 生成拖拽路径\n                path = _generate_bezier_curve((from_x, from_y), (to_x, to_y), steps=random.randint(20, 30))\n                \n                # 4. 沿路径移动\n                for x, y in path[1:]:  # 跳过第一个点（起点）\n                    await page.mouse.move(x, y)\n                    await asyncio.sleep(random.uniform(0.002, 0.008))\n                \n                # 5. 释放鼠标\n                await asyncio.sleep(_random_delay(50, 100))\n                await page.mouse.up()\n            else:\n                # 直接拖拽\n                await page.mouse.move(from_x, from_y)\n                await page.mouse.down()\n                await page.mouse.move(to_x, to_y)\n                await page.mouse.up()\n            \n            # 等待页面稳定\n            await asyncio.sleep(_random_delay(300, 500))\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"拖拽完成: ({from_x}, {from_y}) -> ({to_x}, {to_y})\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"拖拽失败: {str(e)}\"\n            }\n\n\nclass BrowserHoverTool(BaseTool):\n    \"\"\"鼠标悬停操作\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        鼠标悬停在元素或坐标上\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            selector (str, optional): CSS 选择器（悬停在元素上）\n            x (float, optional): x 坐标（悬停在坐标上）\n            y (float, optional): y 坐标（悬停在坐标上）\n            duration_ms (int, optional): 悬停持续时间（毫秒），默认 1000\n            human_like (bool, optional): 是否使用人类化移动，默认 True\n        \n        注意：selector 和 (x, y) 必须提供其中一个\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            selector = parameters.get(\"selector\")\n            x = parameters.get(\"x\")\n            y = parameters.get(\"y\")\n            duration_ms = parameters.get(\"duration_ms\", 1000)\n            human_like = parameters.get(\"human_like\", True)\n            \n            if not browser_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id\"\n                }\n            \n            if not selector and (x is None or y is None):\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"必须提供 selector 或 (x, y) 坐标\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            # 确定目标坐标\n            if selector:\n                print(f\"[INFO] 悬停在元素: {selector}\")\n                element = page.locator(selector).first\n                box = await element.bounding_box()\n                if not box:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"元素不可见或不存在: {selector}\"\n                    }\n                # 元素中心\n                target_x = box['x'] + box['width'] / 2\n                target_y = box['y'] + box['height'] / 2\n            else:\n                print(f\"[INFO] 悬停在坐标: ({x}, {y})\")\n                target_x, target_y = x, y\n            \n            # 移动到目标位置\n            if human_like:\n                await _human_like_mouse_move(page, target_x, target_y)\n            else:\n                await page.mouse.move(target_x, target_y)\n            \n            # 悬停指定时长\n            await asyncio.sleep(duration_ms / 1000.0)\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"悬停完成\\n- 位置: {selector if selector else f'({target_x}, {target_y})'}\\n- 持续时间: {duration_ms}ms\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"悬停失败: {str(e)}\"\n            }\n\n\nclass BrowserScrollTool(BaseTool):\n    \"\"\"鼠标滚轮滚动操作\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        使用鼠标滚轮滚动页面或元素\n        \n        Parameters:\n            browser_id (str): 浏览器会话ID\n            delta_y (int): 垂直滚动距离（像素）。正数向下滚动，负数向上滚动\n            delta_x (int, optional): 水平滚动距离（像素），默认 0。正数向右滚动，负数向左滚动\n            selector (str, optional): 要滚动的元素 CSS 选择器。不指定则滚动整个页面\n            smooth (bool, optional): 是否平滑滚动（分多次小步滚动），默认 True\n            human_like (bool, optional): 是否先移动鼠标到元素（人类化），默认 True\n        \"\"\"\n        try:\n            browser_id = parameters.get(\"browser_id\")\n            delta_y = parameters.get(\"delta_y\")\n            delta_x = parameters.get(\"delta_x\", 0)\n            selector = parameters.get(\"selector\")\n            smooth = parameters.get(\"smooth\", True)\n            human_like = parameters.get(\"human_like\", True)\n            \n            if not browser_id or delta_y is None:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: browser_id 或 delta_y\"\n                }\n            \n            session = BROWSER_SESSIONS.get(browser_id)\n            if not session:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"浏览器会话不存在: {browser_id}\"\n                }\n            \n            # 获取活跃页面\n            page = session[\"pages\"][session[\"active_page_id\"]]\n            \n            # 如果指定了元素，先移动鼠标到元素位置\n            if selector:\n                print(f\"[INFO] 滚动元素: {selector}, 距离: ({delta_x}, {delta_y})\")\n                element = page.locator(selector).first\n                box = await element.bounding_box()\n                if not box:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"元素不可见或不存在: {selector}\"\n                    }\n                \n                # 移动鼠标到元素中心\n                target_x = box['x'] + box['width'] / 2\n                target_y = box['y'] + box['height'] / 2\n                \n                if human_like:\n                    await _human_like_mouse_move(page, target_x, target_y)\n                else:\n                    await page.mouse.move(target_x, target_y)\n                \n                await asyncio.sleep(_random_delay(50, 100))\n            else:\n                print(f\"[INFO] 滚动页面, 距离: ({delta_x}, {delta_y})\")\n            \n            # 执行滚动\n            if smooth and abs(delta_y) > 100:\n                # 平滑滚动：分多次小步滚动\n                steps = min(int(abs(delta_y) / 50), 20)  # 最多20步\n                step_y = delta_y / steps\n                step_x = delta_x / steps\n                \n                for i in range(steps):\n                    await page.mouse.wheel(step_x, step_y)\n                    # 每次滚动后随机延迟，模拟真实滚动\n                    await asyncio.sleep(random.uniform(0.02, 0.05))\n            else:\n                # 直接滚动\n                await page.mouse.wheel(delta_x, delta_y)\n            \n            # 等待页面稳定（滚动可能触发懒加载）\n            await asyncio.sleep(_random_delay(300, 500))\n            \n            # 保存完整快照\n            await _save_page_snapshot(page, browser_id, task_id)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"滚动完成\\n- 位置: {selector if selector else '整个页面'}\\n- 距离: 垂直 {delta_y}px, 水平 {delta_x}px\\n- 模式: {'平滑滚动' if smooth else '直接滚动'}\\n- 截图已更新: temp/browser/{browser_id}/current.png\",\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"滚动失败: {str(e)}\"\n            }\n\n"
  },
  {
    "path": "tool_server_lite/tools/code_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n代码执行工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any, Tuple, Optional\nimport subprocess\nimport sys\nimport re\nimport time\nimport os\nimport shlex\nimport uuid\nfrom datetime import datetime\nfrom .file_tools import BaseTool, get_abs_path\n\n#def _create_venv(self, venv_path: Path) -> Tuple[bool, str]:重复两遍要记得同时维护。\n#为了美观，def _create_venv还是重复写两次吧，这样一个一个类比较独立。\n\n# 全局后台进程注册表\n# 格式: {process_id: {task_id, pid, command, output_file, start_time, process_obj}}\nBACKGROUND_PROCESSES = {}\nTERMINAL_SESSION_WINDOW_ID = None\nTERMINAL_SESSION_TAB_PREFIX = \"infiAgent-exec\"\nTERMINAL_SESSION_TAB_TITLE = f\"{TERMINAL_SESSION_TAB_PREFIX}-{uuid.uuid4().hex[:6]}\"\nTERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH = False\n\n\ndef has_running_background_processes(task_id: str = None) -> bool:\n    \"\"\"检查是否存在仍在运行的后台进程。\"\"\"\n    stale = []\n    for proc_id, info in BACKGROUND_PROCESSES.items():\n        process = info.get(\"process_obj\")\n        if info.get(\"mode\") == \"system_terminal\":\n            exit_file = info.get(\"exit_file\")\n            running = not (exit_file and Path(exit_file).exists())\n        else:\n            running = bool(process and process.poll() is None)\n\n        if not running:\n            stale.append(proc_id)\n            continue\n\n        if task_id is None or str(info.get(\"task_id\")) == str(task_id):\n            return True\n\n    for proc_id in stale:\n        BACKGROUND_PROCESSES.pop(proc_id, None)\n    return False\n\n\nclass ExecuteCodeTool(BaseTool):\n    \"\"\"代码执行工具（支持虚拟环境）\"\"\"\n    \n    def _create_venv(self, venv_path: Path) -> Tuple[bool, str]:\n        \"\"\"\n        创建虚拟环境（兼容 Anaconda 和标准 Python）\n        \n        策略：\n        1. 优先尝试标准 venv（CPython）\n        2. 失败时尝试 virtualenv（兼容 Anaconda）\n        \n        Returns:\n            (是否成功创建, 错误信息)\n        \"\"\"\n        import os\n        venv_path.parent.mkdir(parents=True, exist_ok=True)\n        \n        #print(f\"[DEBUG] 开始创建虚拟环境: {venv_path}\")\n        #print(f\"[DEBUG] Python 解释器: {sys.executable}\")\n        \n        def _run_cmd(cmd):\n            \"\"\"运行命令并返回 (成功?, 错误信息)\"\"\"\n            # 设置环境变量，确保编码正确初始化\n            env = os.environ.copy()\n            env.setdefault(\"PYTHONIOENCODING\", \"utf-8\")\n            env.setdefault(\"PYTHONUTF8\", \"1\")\n            \n            # Windows 下不使用 close_fds，避免标准句柄问题\n            close_fds = (sys.platform != \"win32\")\n            \n            res = subprocess.run(\n                cmd,\n                stdin=subprocess.DEVNULL,\n                capture_output=True,\n                text=True,\n                timeout=300,  # 增加超时时间\n                env=env,\n                close_fds=close_fds\n            )\n            ok = (res.returncode == 0)\n            err = (res.stderr or \"\") if res.stderr else (res.stdout or \"\")\n            return ok, err\n        \n        # 方法 1: 标准 venv\n        venv_cmd = [sys.executable, \"-m\", \"venv\", str(venv_path)]\n        print(f\"[DEBUG] 方法1 - 尝试标准 venv: {' '.join(venv_cmd)}\")\n        ok, err1 = _run_cmd(venv_cmd)\n        print(f\"[DEBUG] venv 结果: {'成功' if ok else '失败 - ' + err1[:100]}\")\n        if ok:\n            return True, \"\"\n        \n        # 方法 2: virtualenv\n        virtualenv_cmd = [sys.executable, \"-m\", \"virtualenv\", str(venv_path)]\n        print(f\"[DEBUG] 方法2 - 尝试 virtualenv: {' '.join(virtualenv_cmd)}\")\n        ok, err2 = _run_cmd(virtualenv_cmd)\n        print(f\"[DEBUG] virtualenv 结果: {'成功' if ok else '失败 - ' + err2[:100]}\")\n        if ok:\n            return True, \"\"\n        \n        # 都失败\n        print(f\"[DEBUG] ❌ 两种方法都失败\")\n        return False, f\"venv: {err1[:400]} | virtualenv: {err2[:400]}\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行 Python 代码\n        \n        Parameters:\n            code (str, optional): 代码内容\n            file_path (str, optional): 代码文件相对路径\n            working_dir (str, optional): 执行目录相对路径，默认为code_run目录\n            use_venv (bool, optional): 是否使用虚拟环境，默认True\n            timeout (int, optional): 超时时间（秒），默认30，后台执行时忽略\n            background (bool, optional): 是否后台执行（不阻塞），默认False\n            output_file (str, optional): 输出重定向到文件（相对路径），后台执行时必需\n        \"\"\"\n        try:\n            code = parameters.get(\"code\")\n            file_path = parameters.get(\"file_path\")\n            working_dir = parameters.get(\"working_dir\", \"code_run\")\n            use_venv = parameters.get(\"use_venv\", True)\n            timeout = parameters.get(\"timeout\", 30)\n            background = parameters.get(\"background\", False)\n            output_file = parameters.get(\"output_file\")\n            \n            # 后台执行时必须指定输出文件\n            if background and not output_file:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"output_file is required when background=True\"\n                }\n            \n            workspace = Path(task_id)\n            exec_dir = get_abs_path(task_id, working_dir)\n            \n            # 准备代码文件\n            if code:\n                # 创建临时文件\n                code_dir = workspace / \"code_run\"\n                code_dir.mkdir(parents=True, exist_ok=True)\n                temp_file = code_dir / \"temp_code.py\"\n                \n                with open(temp_file, 'w', encoding='utf-8') as f:\n                    f.write(code)\n                \n                exec_file = temp_file\n            elif file_path:\n                exec_file = get_abs_path(task_id, file_path)\n                if not exec_file.exists():\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"Code file not found: {file_path}\"\n                    }\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"Either 'code' or 'file_path' must be provided\"\n                }\n            \n            # 执行 Python 代码\n            if background:\n                # 后台执行\n                output = self._execute_python_background(\n                    workspace, exec_file, exec_dir, use_venv, output_file\n                )\n            else:\n                # 直接执行\n                output = self._execute_python(\n                    workspace, exec_file, exec_dir, use_venv, timeout, output_file\n                )\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except subprocess.TimeoutExpired:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Execution timeout ({timeout}s)\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    def _get_python_exec(self, workspace: Path, use_venv: bool) -> Path:\n        \"\"\"获取 Python 解释器路径\"\"\"\n        env_dir = workspace / \"code_env\"\n        \n        if use_venv:\n            venv_path = env_dir / \"venv\"\n            if not venv_path.exists():\n                venv_created, error_msg = self._create_venv(venv_path)\n                if not venv_created:\n                    print(f\"⚠️ venv 创建失败，使用系统 Python: {error_msg[:100]}\")\n                    return Path(sys.executable)\n                else:\n                    if sys.platform == \"win32\":\n                        return venv_path / \"Scripts\" / \"python.exe\"\n                    else:\n                        return venv_path / \"bin\" / \"python\"\n            else:\n                if sys.platform == \"win32\":\n                    return venv_path / \"Scripts\" / \"python.exe\"\n                else:\n                    return venv_path / \"bin\" / \"python\"\n        else:\n            return Path(sys.executable)\n    \n    def _execute_python(self, workspace: Path, code_file: Path, exec_dir: Path, use_venv: bool, timeout: int, output_file: str = None) -> str:\n        \"\"\"执行Python代码（直接模式）\"\"\"\n        python_exec = self._get_python_exec(workspace, use_venv)\n        \n        # 如果指定了输出文件，重定向输出\n        if output_file:\n            output_path = get_abs_path(str(workspace), output_file)\n            output_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            with open(output_path, 'w', encoding='utf-8') as out_f:\n                result = subprocess.run(\n                    [str(python_exec), str(code_file)],\n                    stdout=out_f,\n                    stderr=subprocess.STDOUT,\n                    text=True,\n                    timeout=timeout,\n                    cwd=str(exec_dir),\n                    stdin=subprocess.DEVNULL\n                )\n            \n            output = f\"代码执行完成，输出已保存到: {output_file}\\n\"\n            output += f\"Exit code: {result.returncode}\"\n            \n            # 读取部分输出用于显示\n            try:\n                with open(output_path, 'r', encoding='utf-8') as f:\n                    content = f.read(1000)  # 读取前1000字符\n                    if len(content) == 1000:\n                        output += f\"\\n\\n输出预览（前1000字符）:\\n{content}\\n...\"\n                    else:\n                        output += f\"\\n\\n完整输出:\\n{content}\"\n            except Exception:\n                pass\n            \n            return output\n        else:\n            # 不重定向，直接捕获输出\n            result = subprocess.run(\n                [str(python_exec), str(code_file)],\n                capture_output=True,\n                text=True,\n                timeout=timeout,\n                cwd=str(exec_dir),\n                stdin=subprocess.DEVNULL\n            )\n            \n            output = result.stdout\n            if result.stderr:\n                output += f\"\\nSTDERR:\\n{result.stderr}\"\n            if result.returncode != 0:\n                output += f\"\\nExit code: {result.returncode}\"\n            \n            return output\n    \n    def _execute_python_background(self, workspace: Path, code_file: Path, exec_dir: Path, use_venv: bool, output_file: str) -> str:\n        \"\"\"执行Python代码（后台模式，不阻塞）\"\"\"\n        python_exec = self._get_python_exec(workspace, use_venv)\n        \n        # 输出文件路径\n        output_path = get_abs_path(str(workspace), output_file)\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        \n        # 打开输出文件\n        out_f = open(output_path, 'w', encoding='utf-8')\n        \n        # 跨平台后台执行\n        if sys.platform == \"win32\":\n            # Windows: 使用 CREATE_NO_WINDOW + DETACHED_PROCESS\n            CREATE_NO_WINDOW = 0x08000000\n            DETACHED_PROCESS = 0x00000008\n            \n            process = subprocess.Popen(\n                [str(python_exec), str(code_file)],\n                stdout=out_f,\n                stderr=subprocess.STDOUT,\n                cwd=str(exec_dir),\n                stdin=subprocess.DEVNULL,\n                creationflags=CREATE_NO_WINDOW | DETACHED_PROCESS,\n                close_fds=False\n            )\n        else:\n            # Unix/Linux/Mac: 使用 start_new_session\n            process = subprocess.Popen(\n                [str(python_exec), str(code_file)],\n                stdout=out_f,\n                stderr=subprocess.STDOUT,\n                cwd=str(exec_dir),\n                stdin=subprocess.DEVNULL,\n                start_new_session=True\n            )\n        \n        # 生成进程ID并注册\n        process_id = f\"bg_{int(time.time())}_{process.pid}\"\n        BACKGROUND_PROCESSES[process_id] = {\n            \"task_id\": str(workspace),\n            \"pid\": process.pid,\n            \"command\": str(code_file),\n            \"output_file\": output_file,\n            \"start_time\": datetime.now().isoformat(),\n            \"process_obj\": process\n        }\n        \n        # 不等待进程结束，立即返回\n        output = f\"✅ 代码已在后台启动\\n\"\n        output += f\"   Process ID: {process_id}\\n\"\n        output += f\"   PID: {process.pid}\\n\"\n        output += f\"   输出文件: {output_file}\\n\"\n        output += f\"   提示: 使用 file_read 读取 {output_file} 查看执行结果\\n\"\n        output += f\"   管理: 使用 execute_command 运行 `ps`/`kill` 或停止任务以终止进程\"\n        \n        return output\n    \n\n\nclass PipInstallTool(BaseTool):\n    \"\"\"pip 包安装工具\"\"\"\n    \n    def _create_venv(self, venv_path: Path) -> Tuple[bool, str]:\n        \"\"\"\n        创建虚拟环境（兼容 Anaconda 和标准 Python）\n        与 ExecuteCodeTool 使用相同的策略\n        \n        Returns:\n            (是否成功创建, 错误信息)\n        \"\"\"\n        import os\n        venv_path.parent.mkdir(parents=True, exist_ok=True)\n        \n        print(f\"[DEBUG] 开始创建虚拟环境: {venv_path}\")\n        print(f\"[DEBUG] Python 解释器: {sys.executable}\")\n        \n        def _run_cmd(cmd):\n            \"\"\"运行命令并返回 (成功?, 错误信息)\"\"\"\n            # 设置环境变量，确保编码正确初始化\n            env = os.environ.copy()\n            env.setdefault(\"PYTHONIOENCODING\", \"utf-8\")\n            env.setdefault(\"PYTHONUTF8\", \"1\")\n            \n            # Windows 下不使用 close_fds，避免标准句柄问题\n            close_fds = (sys.platform != \"win32\")\n            \n            res = subprocess.run(\n                cmd,\n                stdin=subprocess.DEVNULL,\n                capture_output=True,\n                text=True,\n                timeout=180,  # 增加超时时间\n                env=env,\n                close_fds=close_fds\n            )\n            ok = (res.returncode == 0)\n            err = (res.stderr or \"\") if res.stderr else (res.stdout or \"\")\n            return ok, err\n        \n        # 方法 1: 标准 venv\n        venv_cmd = [sys.executable, \"-m\", \"venv\", str(venv_path)]\n        print(f\"[DEBUG] 方法1 - 尝试标准 venv: {' '.join(venv_cmd)}\")\n        ok, err1 = _run_cmd(venv_cmd)\n        print(f\"[DEBUG] venv 结果: {'成功' if ok else '失败 - ' + err1[:100]}\")\n        if ok:\n            return True, \"\"\n        \n        # 方法 2: virtualenv\n        virtualenv_cmd = [sys.executable, \"-m\", \"virtualenv\", str(venv_path)]\n        print(f\"[DEBUG] 方法2 - 尝试 virtualenv: {' '.join(virtualenv_cmd)}\")\n        ok, err2 = _run_cmd(virtualenv_cmd)\n        print(f\"[DEBUG] virtualenv 结果: {'成功' if ok else '失败 - ' + err2[:100]}\")\n        if ok:\n            return True, \"\"\n        \n        # 都失败\n        print(f\"[DEBUG] ❌ 两种方法都失败\")\n        return False, f\"venv: {err1[:400]} | virtualenv: {err2[:400]}\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        在虚拟环境中安装 Python 包\n        \n        Parameters:\n            packages (list or str): 要安装的包列表或单个包名\n            timeout (int, optional): 超时时间（秒），默认300\n        \"\"\"\n        try:\n            packages = parameters.get(\"packages\")\n            timeout = parameters.get(\"timeout\", 300)\n            \n            if not packages:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"packages is required\"\n                }\n            \n            # 转换为列表\n            if isinstance(packages, str):\n                packages = [packages]\n            \n            workspace = Path(task_id)\n            env_dir = workspace / \"code_env\"\n            venv_path = env_dir / \"venv\"\n            \n            # 检查并创建虚拟环境\n            if not venv_path.exists():\n                venv_created, error_msg = self._create_venv(venv_path)\n                if not venv_created:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"无法创建虚拟环境: {error_msg}\"\n                    }\n            \n            # 获取虚拟环境的 pip\n            if sys.platform == \"win32\":\n                pip_exec = venv_path / \"Scripts\" / \"pip.exe\"\n            else:\n                pip_exec = venv_path / \"bin\" / \"pip\"\n            \n            # 安装包\n            results = []\n            for package in packages:\n                # 设置环境变量，避免 Bad file descriptor\n                import os\n                env = os.environ.copy()\n                env.setdefault(\"PYTHONIOENCODING\", \"utf-8\")\n                env.setdefault(\"PYTHONUTF8\", \"1\")\n                \n                # Windows 下不使用 close_fds\n                close_fds = (sys.platform != \"win32\")\n                \n                result = subprocess.run(\n                    [str(pip_exec), \"install\", package],\n                    stdin=subprocess.DEVNULL,\n                    capture_output=True,\n                    text=True,\n                    timeout=timeout,\n                    env=env,\n                    close_fds=close_fds\n                )\n                \n                if result.returncode == 0:\n                    results.append(f\"✅ {package}: installed\")\n                else:\n                    results.append(f\"❌ {package}: {result.stderr.strip()[:200]}\")\n            \n            output = \"\\n\".join(results)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except subprocess.TimeoutExpired:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Installation timeout ({timeout}s)\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass ExecuteCommandTool(BaseTool):\n    \"\"\"命令行执行工具（仅限安全的只读命令）\"\"\"\n    \n    # 白名单：只允许安全的只读命令\n    ALLOWED_COMMANDS = {\n        # 文件查看和搜索\n        'ls', 'dir',           # 列出目录内容\n        'cat', 'type',         # 显示文件内容\n        'head', 'tail',        # 显示文件开头/结尾\n        'grep', 'findstr',     # 文本搜索\n        'find', 'where',       # 查找文件\n        'tree',                # 显示目录树\n        \n        # 系统信息\n        'pwd', 'cd',           # 显示/切换目录（cd仅用于显示）\n        'whoami',              # 当前用户\n        'hostname',            # 主机名\n        'date',                # 日期时间\n        'echo',                # 输出文本\n        \n        # 文件信息\n        'wc',                  # 统计行数/字数\n        'diff',                # 比较文件\n        'file',                # 文件类型\n        'stat',                # 文件状态\n        'du',                  # 磁盘使用\n        'df',                  # 磁盘空间\n        \n        # 其他只读命令\n        'which',               # 查找命令路径\n        'env', 'set',          # 显示环境变量\n        'python', 'python3',   # Python解释器（用于查看版本等）\n        'pip',                 # pip命令（仅限list/show等）\n        'git',                 # git命令（仅限status/log等）\n    }\n    \n    # 危险参数黑名单（即使命令在白名单中，如果包含这些参数也拒绝）\n    DANGEROUS_PATTERNS = [\n        'rm ', 'del ',         # 删除\n        'mv ', 'move ',        # 移动/重命名\n        'cp ', 'copy ',        # 复制\n        'chmod', 'chown',      # 修改权限\n        '>', '>>',             # 重定向（可能覆盖文件）\n        'sudo', 'su',          # 提权\n        'format', 'mkfs',      # 格式化\n        'kill', 'pkill',       # 结束进程\n        '--force', '-f',       # 强制操作\n        'install', 'uninstall', # 安装/卸载\n    ]\n    \n    def _is_command_safe(self, command: str) -> tuple[bool, str]:\n        \"\"\"\n        检查命令是否安全\n        \n        Returns:\n            (是否安全, 错误信息)\n        \"\"\"\n        return True,\"不检查\"\n        command = command.strip()\n        \n        if not command:\n            return False, \"空命令\"\n        \n        # 提取命令的第一个词（命令名）\n        cmd_parts = command.split()\n        if not cmd_parts:\n            return False, \"无效命令\"\n        \n        base_command = cmd_parts[0]\n        \n        # Windows下可能带.exe后缀\n        if base_command.endswith('.exe'):\n            base_command = base_command[:-4]\n        \n        # 检查基础命令是否在白名单中\n        if base_command not in self.ALLOWED_COMMANDS:\n            #return False, f\"命令 '{base_command}' 不在允许列表中。仅允许只读命令如: ls, cat, grep, find, pwd, tree 等\"\n            pass\n        # 检查是否包含危险模式\n        command_lower = command.lower()\n        for pattern in self.DANGEROUS_PATTERNS:\n            if pattern in command_lower:\n                return False, f\"命令包含危险操作 '{pattern}'，已被拒绝\"\n        \n        # git 命令特殊检查：只允许只读操作\n        if base_command == 'git':\n            git_readonly_cmds = ['status', 'log', 'diff', 'show', 'branch', 'remote', 'config', '--version']\n            if len(cmd_parts) < 2 or not any(ro_cmd in command_lower for ro_cmd in git_readonly_cmds):\n                return False, \"git 命令仅允许只读操作（如 status, log, diff, show 等）\"\n        \n        # pip 命令特殊检查：只允许只读操作\n        if base_command in ['pip', 'pip3']:\n            pip_readonly_cmds = ['list', 'show', 'search', 'freeze', '--version', '-V']\n            if len(cmd_parts) < 2 or not any(ro_cmd in command for ro_cmd in pip_readonly_cmds):\n                return False, \"pip 命令仅允许只读操作（如 list, show, freeze 等）\"\n        \n        return True, \"\"\n\n    def _use_system_terminal_mode(self) -> bool:\n        \"\"\"macOS only: optionally route execute_command through Terminal.app.\"\"\"\n        mode = str(os.environ.get(\"MLA_EXECUTE_COMMAND_MODE\", \"direct\")).strip().lower()\n        return sys.platform == \"darwin\" and mode == \"system_terminal\"\n\n    def _escape_applescript_str(self, s: str) -> str:\n        return s.replace(\"\\\\\", \"\\\\\\\\\").replace('\"', '\\\\\"')\n\n    def _run_osascript(self, script: str, timeout: int = 10) -> str:\n        result = subprocess.run(\n            [\"osascript\", \"-e\", script],\n            capture_output=True,\n            text=True,\n            timeout=timeout,\n            stdin=subprocess.DEVNULL,\n        )\n        if result.returncode != 0:\n            err = (result.stderr or result.stdout or \"\").strip()\n            raise RuntimeError(err or \"unknown osascript error\")\n        return (result.stdout or \"\").strip()\n\n    def _find_idle_terminal_window_id(self) -> Optional[int]:\n        \"\"\"\n        Find an existing dedicated Terminal window whose tagged tab is idle.\n\n        We only reuse tabs that are not busy. Otherwise, commands like `sleep`\n        would keep consuming the shell input buffer and block every following\n        execute_command routed through Terminal.app.\n        \"\"\"\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        script = (\n            'tell application \"Terminal\"\\n'\n            'repeat with w in windows\\n'\n            'repeat with t in tabs of w\\n'\n            f'if (custom title of t) is \"{title}\" then\\n'\n            'if (busy of t) is false then return (id of w) as string\\n'\n            'end if\\n'\n            'end if\\n'\n            'end repeat\\n'\n            'end repeat\\n'\n            'return \"\"\\n'\n            'end tell'\n        )\n        out = self._run_osascript(script, timeout=10).strip()\n        if not out:\n            return None\n        return int(out)\n\n    def _terminal_window_exists(self, window_id: int) -> bool:\n        script = (\n            'tell application \"Terminal\"\\n'\n            f'return (exists window id {int(window_id)}) as string\\n'\n            'end tell'\n        )\n        try:\n            return self._run_osascript(script, timeout=5).strip().lower() == \"true\"\n        except Exception:\n            return False\n\n    def _close_tagged_terminal_windows(self) -> None:\n        \"\"\"\n        Close every Terminal window carrying our dedicated custom title.\n\n        This keeps the desktop side to a single managed Terminal window even if\n        earlier retries/timeouts already spawned multiple dedicated windows.\n        \"\"\"\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        script = (\n            'tell application \"Terminal\"\\n'\n            'set targetIds to {}\\n'\n            'repeat with w in windows\\n'\n            'set shouldClose to false\\n'\n            'repeat with t in tabs of w\\n'\n            f'if (custom title of t) is \"{title}\" then\\n'\n            'set shouldClose to true\\n'\n            'exit repeat\\n'\n            'end if\\n'\n            'end repeat\\n'\n            'if shouldClose then set end of targetIds to (id of w)\\n'\n            'end repeat\\n'\n            'repeat with wid in targetIds\\n'\n            'try\\n'\n            'close (window id (contents of wid)) saving no\\n'\n            'end try\\n'\n            'end repeat\\n'\n            'return \"\"\\n'\n            'end tell'\n        )\n        try:\n            self._run_osascript(script, timeout=10)\n        except Exception:\n            pass\n\n    def _list_tagged_terminal_ttys(self) -> list[str]:\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        script = (\n            'tell application \"Terminal\"\\n'\n            'set ttyList to {}\\n'\n            'repeat with w in windows\\n'\n            'repeat with t in tabs of w\\n'\n            f'if (custom title of t) is \"{title}\" then\\n'\n            'set ttyValue to (tty of t) as string\\n'\n            'if ttyValue is not \"\" then set end of ttyList to ttyValue\\n'\n            'exit repeat\\n'\n            'end if\\n'\n            'end repeat\\n'\n            'end repeat\\n'\n            'set AppleScript\\'s text item delimiters to \"\\\\n\"\\n'\n            'set outText to ttyList as text\\n'\n            'set AppleScript\\'s text item delimiters to \"\"\\n'\n            'return outText\\n'\n            'end tell'\n        )\n        try:\n            raw = self._run_osascript(script, timeout=10)\n        except Exception:\n            return []\n        return [line.strip() for line in str(raw or \"\").splitlines() if line.strip()]\n\n    def _force_reset_tagged_terminal_windows(self) -> None:\n        \"\"\"\n        Force-stop processes running in dedicated Terminal windows, then close them.\n\n        Closing a busy Terminal window directly is unreliable because Terminal may\n        keep the session alive while a foreground process is still attached to the\n        TTY. We explicitly terminate the TTY session first so the desktop side can\n        go back to a single managed window.\n        \"\"\"\n        tty_paths = self._list_tagged_terminal_ttys()\n        for tty_path in tty_paths:\n            tty_name = Path(tty_path).name.strip()\n            if not tty_name:\n                continue\n            for signal_name in (\"-TERM\", \"-KILL\"):\n                try:\n                    subprocess.run(\n                        [\"pkill\", signal_name, \"-t\", tty_name],\n                        capture_output=True,\n                        text=True,\n                        timeout=3,\n                        stdin=subprocess.DEVNULL,\n                    )\n                except Exception:\n                    pass\n                time.sleep(0.15)\n        self._close_tagged_terminal_windows()\n\n    def _wait_for_terminal_window_idle(\n        self,\n        window_id: int,\n        timeout: float = 0.8,\n        poll_interval: float = 0.1,\n    ) -> bool:\n        \"\"\"\n        Give Terminal a short grace period to return to the prompt.\n\n        Even fast commands like `pwd` briefly keep the tab marked as busy after\n        the child process exits. Without this grace period, the next command can\n        incorrectly decide the dedicated tab is still occupied and open a fresh\n        Terminal window every time.\n        \"\"\"\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        deadline = time.time() + max(0.0, float(timeout))\n\n        while time.time() < deadline:\n            script = (\n                'tell application \"Terminal\"\\n'\n                f'set w to window id {int(window_id)}\\n'\n                'repeat with t in tabs of w\\n'\n                f'if (custom title of t) is \"{title}\" then\\n'\n                'return ((busy of t) is false) as string\\n'\n                'end if\\n'\n                'end repeat\\n'\n                'return \"false\"\\n'\n                'end tell'\n            )\n            try:\n                out = self._run_osascript(script, timeout=5).strip().lower()\n            except Exception:\n                return False\n            if out == \"true\":\n                return True\n            time.sleep(max(0.01, float(poll_interval)))\n        return False\n\n    def _get_tagged_terminal_tty(self, window_id: int) -> Optional[str]:\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        script = (\n            'tell application \"Terminal\"\\n'\n            f'set w to window id {int(window_id)}\\n'\n            'repeat with t in tabs of w\\n'\n            f'if (custom title of t) is \"{title}\" then return (tty of t) as string\\n'\n            'end repeat\\n'\n            'return \"\"\\n'\n            'end tell'\n        )\n        try:\n            out = self._run_osascript(script, timeout=5).strip()\n        except Exception:\n            return None\n        return out or None\n\n    def _interrupt_terminal_window_processes(self, window_id: int) -> bool:\n        \"\"\"\n        Interrupt the currently running command in our dedicated Terminal tab.\n\n        We keep the parent shell alive and only terminate child processes bound\n        to the same TTY. This avoids the user-facing \"close running process\"\n        dialog while still letting the next command reuse the same Terminal\n        window.\n        \"\"\"\n        tty_path = self._get_tagged_terminal_tty(window_id)\n        if not tty_path:\n            return False\n\n        tty_name = Path(tty_path).name.strip()\n        if not tty_name:\n            return False\n\n        try:\n            result = subprocess.run(\n                [\"ps\", \"-t\", tty_name, \"-o\", \"pid=,ppid=,comm=\"],\n                capture_output=True,\n                text=True,\n                timeout=5,\n                stdin=subprocess.DEVNULL,\n            )\n        except Exception:\n            return False\n\n        processes = []\n        for line in (result.stdout or \"\").splitlines():\n            parts = line.strip().split(None, 2)\n            if len(parts) < 2:\n                continue\n            try:\n                pid = int(parts[0])\n                ppid = int(parts[1])\n            except Exception:\n                continue\n            comm = parts[2] if len(parts) > 2 else \"\"\n            processes.append((pid, ppid, comm))\n\n        if not processes:\n            return self._wait_for_terminal_window_idle(window_id, timeout=0.5)\n\n        pid_set = {pid for pid, _, _ in processes}\n        root_candidates = [pid for pid, ppid, _ in processes if ppid not in pid_set]\n        keep_pid = min(root_candidates) if root_candidates else min(pid_set)\n        target_pids = [pid for pid, _, _ in processes if pid != keep_pid]\n\n        if not target_pids:\n            return self._wait_for_terminal_window_idle(window_id, timeout=1.0)\n\n        for sig in (\"-TERM\", \"-KILL\"):\n            for pid in target_pids:\n                try:\n                    subprocess.run(\n                        [\"kill\", sig, str(pid)],\n                        capture_output=True,\n                        text=True,\n                        timeout=3,\n                        stdin=subprocess.DEVNULL,\n                    )\n                except Exception:\n                    pass\n            if self._wait_for_terminal_window_idle(window_id, timeout=1.0):\n                return True\n            time.sleep(0.2)\n\n        return self._wait_for_terminal_window_idle(window_id, timeout=0.5)\n\n    def _get_or_create_terminal_window_id(self, force_new: bool = False) -> int:\n        \"\"\"\n        Reuse one idle dedicated Terminal tab/window.\n\n        If every dedicated Terminal tab is still busy, create a new dedicated\n        window so that a hung command does not head-of-line block later commands.\n        \"\"\"\n        global TERMINAL_SESSION_WINDOW_ID, TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\n\n        if force_new:\n            self._force_reset_tagged_terminal_windows()\n            TERMINAL_SESSION_WINDOW_ID = None\n\n        if not force_new and TERMINAL_SESSION_WINDOW_ID is not None:\n            cached_id = int(TERMINAL_SESSION_WINDOW_ID)\n            if self._terminal_window_exists(cached_id):\n                return cached_id\n            TERMINAL_SESSION_WINDOW_ID = None\n\n        # Do not reuse leftover tagged windows from previous desktop/backend\n        # sessions. To keep the UX predictable, once the current process loses\n        # its cached window reference we rebuild a single clean dedicated\n        # Terminal window instead of attaching to historical ones.\n        self._force_reset_tagged_terminal_windows()\n        TERMINAL_SESSION_WINDOW_ID = None\n\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        script = (\n            'tell application \"Terminal\"\\n'\n            'do script \"\"\\n'\n            'set targetWin to front window\\n'\n            f'set custom title of selected tab of targetWin to \"{title}\"\\n'\n            'return id of targetWin\\n'\n            'end tell'\n        )\n        out = self._run_osascript(script, timeout=10)\n        wid = int(out)\n        TERMINAL_SESSION_WINDOW_ID = wid\n        TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH = False\n        return wid\n\n    def _launch_terminal_script(self, script_path: Path) -> int:\n        \"\"\"\n        Ask Terminal.app to execute the generated shell script.\n        Reuse one dedicated Terminal tab/window.\n        \"\"\"\n        window_id = self._get_or_create_terminal_window_id()\n        if not self._wait_for_terminal_window_idle(window_id, timeout=1.5):\n            reset_ok = False\n            if TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH:\n                reset_ok = self._interrupt_terminal_window_processes(window_id)\n            else:\n                reset_ok = self._wait_for_terminal_window_idle(window_id, timeout=1.0)\n            if not reset_ok:\n                raise RuntimeError(\"Dedicated Terminal session is still busy; please retry after the current command finishes.\")\n        cmd = f'/bin/bash {shlex.quote(str(script_path))}'\n        esc_cmd = self._escape_applescript_str(cmd)\n        title = self._escape_applescript_str(TERMINAL_SESSION_TAB_TITLE)\n        apple_script = (\n            'tell application \"Terminal\"\\n'\n            f'set w to window id {window_id}\\n'\n            'set targetTab to missing value\\n'\n            'repeat with t in tabs of w\\n'\n            f'if ((custom title of t) is \"{title}\") and ((busy of t) is false) then\\n'\n            'set targetTab to t\\n'\n            'exit repeat\\n'\n            'end if\\n'\n            'end repeat\\n'\n            'if targetTab is missing value then\\n'\n            'do script \"\"\\n'\n            'set w to front window\\n'\n            'set targetTab to selected tab of w\\n'\n            f'set custom title of targetTab to \"{title}\"\\n'\n            'end if\\n'\n            f'do script \"{esc_cmd}\" in targetTab\\n'\n            'return id of w\\n'\n            'end tell'\n        )\n        try:\n            out = self._run_osascript(apple_script, timeout=10)\n            if out:\n                global TERMINAL_SESSION_WINDOW_ID\n                TERMINAL_SESSION_WINDOW_ID = int(out)\n                return int(out)\n        except Exception as e:\n            # If cached window was closed by user, reset cache and retry once.\n            if \"Can’t get window id\" in str(e) or \"can't get window id\" in str(e).lower():\n                TERMINAL_SESSION_WINDOW_ID = None\n                window_id = self._get_or_create_terminal_window_id()\n                retry_script = (\n                    'tell application \"Terminal\"\\n'\n                    f'set w to window id {window_id}\\n'\n                    'set targetTab to missing value\\n'\n                    'repeat with t in tabs of w\\n'\n                    f'if ((custom title of t) is \"{title}\") and ((busy of t) is false) then\\n'\n                    'set targetTab to t\\n'\n                    'exit repeat\\n'\n                    'end if\\n'\n                    'end repeat\\n'\n                    'if targetTab is missing value then\\n'\n                    'do script \"\"\\n'\n                    'set w to front window\\n'\n                    'set targetTab to selected tab of w\\n'\n                    'end if\\n'\n                    f'set custom title of targetTab to \"{title}\"\\n'\n                    f'do script \"{esc_cmd}\" in targetTab\\n'\n                    'return id of w\\n'\n                    'end tell'\n                )\n                out = self._run_osascript(retry_script, timeout=10)\n                if out:\n                    TERMINAL_SESSION_WINDOW_ID = int(out)\n                    return int(out)\n                return window_id\n            raise RuntimeError(f\"Failed to launch Terminal command: {str(e)}\")\n        return window_id\n\n    def _build_terminal_paths(self, workspace: Path, output_path: Optional[Path]) -> tuple[Path, Path, Path]:\n        token = f\"{int(time.time())}_{uuid.uuid4().hex[:8]}\"\n        runtime_dir = workspace / \"temp\" / \"terminal_exec\"\n        runtime_dir.mkdir(parents=True, exist_ok=True)\n        script_path = runtime_dir / f\"run_{token}.sh\"\n        if output_path is None:\n            output_path = runtime_dir / f\"output_{token}.log\"\n        exit_path = runtime_dir / f\"exit_{token}.txt\"\n        return script_path, output_path, exit_path\n\n    def _write_terminal_script(\n        self,\n        script_path: Path,\n        abs_working_dir: Path,\n        command: str,\n        output_path: Path,\n        exit_path: Path,\n    ) -> None:\n        shell = (\n            \"#!/bin/bash\\n\"\n            f\"cd {shlex.quote(str(abs_working_dir))} || exit 1\\n\"\n            f\"{{ {command}; }} > {shlex.quote(str(output_path))} 2>&1\\n\"\n            f'echo \"$?\" > {shlex.quote(str(exit_path))}\\n'\n        )\n        script_path.write_text(shell, encoding=\"utf-8\")\n        script_path.chmod(0o755)\n\n    def _run_via_terminal_foreground(\n        self,\n        workspace: Path,\n        abs_working_dir: Path,\n        command: str,\n        timeout: int,\n        output_file: Optional[str],\n    ) -> Dict[str, Any]:\n        user_output_path = get_abs_path(str(workspace), output_file) if output_file else None\n        if user_output_path:\n            user_output_path.parent.mkdir(parents=True, exist_ok=True)\n\n        script_path, output_path, exit_path = self._build_terminal_paths(workspace, user_output_path)\n        self._write_terminal_script(script_path, abs_working_dir, command, output_path, exit_path)\n        terminal_window_id = self._launch_terminal_script(script_path)\n        global TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\n\n        deadline = time.time() + max(1, int(timeout))\n        while time.time() < deadline:\n            if exit_path.exists():\n                break\n            time.sleep(0.2)\n\n        if not exit_path.exists():\n            TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH = True\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": (\n                    f\"Command timeout ({timeout}s) in system_terminal mode. \"\n                    \"The command may still be running in Terminal.app.\"\n                ),\n            }\n\n        try:\n            exit_code = int(exit_path.read_text(encoding=\"utf-8\").strip() or \"1\")\n        except Exception:\n            exit_code = 1\n\n        # Wait briefly for Terminal to return to an idle prompt so the next\n        # short command can reuse the same dedicated tab instead of creating a\n        # fresh window every time.\n        idle_ready = self._wait_for_terminal_window_idle(terminal_window_id)\n        TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH = not idle_ready\n\n        content = \"\"\n        try:\n            content = output_path.read_text(encoding=\"utf-8\", errors=\"ignore\")\n        except Exception:\n            content = \"\"\n\n        if output_file:\n            msg = f\"命令执行完成（system_terminal），输出已保存到: {output_file}\\nExit code: {exit_code}\"\n            if content:\n                preview = content[:1000]\n                msg += \"\\n\\n输出预览（前1000字符）:\\n\" + preview + (\"\\n...\" if len(content) > 1000 else \"\")\n            return {\"status\": \"success\", \"output\": msg, \"error\": \"\"}\n\n        if exit_code != 0:\n            content = (content or \"\") + f\"\\nExit code: {exit_code}\"\n        return {\"status\": \"success\", \"output\": content, \"error\": \"\"}\n\n    def _run_via_terminal_background(\n        self,\n        workspace: Path,\n        abs_working_dir: Path,\n        command: str,\n        output_file: str,\n    ) -> Dict[str, Any]:\n        output_path = get_abs_path(str(workspace), output_file)\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n\n        script_path, _, exit_path = self._build_terminal_paths(workspace, output_path)\n        self._write_terminal_script(script_path, abs_working_dir, command, output_path, exit_path)\n        self._launch_terminal_script(script_path)\n\n        global TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH\n        TERMINAL_SESSION_ROTATE_ON_NEXT_LAUNCH = True\n\n        process_id = f\"bg_term_{int(time.time())}_{uuid.uuid4().hex[:6]}\"\n        BACKGROUND_PROCESSES[process_id] = {\n            \"task_id\": str(workspace),\n            \"pid\": None,\n            \"command\": command,\n            \"output_file\": output_file,\n            \"start_time\": datetime.now().isoformat(),\n            \"process_obj\": None,\n            \"mode\": \"system_terminal\",\n            \"exit_file\": str(exit_path),\n        }\n\n        return {\n            \"status\": \"success\",\n            \"output\": (\n                \"✅ 命令已在后台启动（system_terminal）\\n\"\n                f\"   Process ID: {process_id}\\n\"\n                \"   PID: terminal-managed\\n\"\n                f\"   输出文件: {output_file}\\n\"\n                f\"   提示: 使用 file_read 读取 {output_file} 查看执行结果\\n\"\n                \"   提示: system_terminal 模式下建议直接在 Terminal 中终止对应命令\"\n            ),\n            \"error\": \"\",\n        }\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行安全的只读命令\n        \n        Parameters:\n            command (str): 要执行的命令（仅限白名单中的安全命令）\n            working_dir (str, optional): 工作目录相对路径，默认为workspace根目录\n            timeout (int, optional): 超时时间（秒），默认30\n            background (bool, optional): 是否后台执行（不阻塞），默认False。后台执行时必须指定 output_file。\n            output_file (str, optional): 输出重定向到文件（相对路径）。后台执行时必需；非后台执行时可选。\n        \"\"\"\n        try:\n            command = parameters.get(\"command\")\n            working_dir = parameters.get(\"working_dir\", \".\")\n            timeout = parameters.get(\"timeout\", 30)\n            background = parameters.get(\"background\", False)\n            output_file = parameters.get(\"output_file\")\n            \n            if not command:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"command parameter is required\"\n                }\n\n            # 后台执行时必须指定输出文件\n            if background and not output_file:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"output_file is required when background=True\"\n                }\n            \n            # 安全检查\n            is_safe, error_msg = self._is_command_safe(command)\n            if not is_safe:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"命令安全检查失败: {error_msg}\"\n                }\n            \n            abs_working_dir = get_abs_path(task_id, working_dir)\n            \n            # 确保工作目录在 workspace 内\n            workspace = Path(task_id)\n            try:\n                abs_working_dir.resolve().relative_to(workspace.resolve())\n            except ValueError:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"工作目录必须在 workspace 内: {working_dir}\"\n                }\n            \n            if not abs_working_dir.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Working directory not found: {working_dir}\"\n                }\n            \n            workspace = Path(task_id)\n\n            # macOS only: optionally proxy through Terminal.app to align with terminal-side permissions\n            if self._use_system_terminal_mode():\n                if background:\n                    return self._run_via_terminal_background(\n                        workspace=workspace,\n                        abs_working_dir=abs_working_dir,\n                        command=command,\n                        output_file=output_file,\n                    )\n                return self._run_via_terminal_foreground(\n                    workspace=workspace,\n                    abs_working_dir=abs_working_dir,\n                    command=command,\n                    timeout=timeout,\n                    output_file=output_file,\n                )\n\n            # 输出重定向到文件\n            if output_file:\n                output_path = get_abs_path(str(workspace), output_file)\n                output_path.parent.mkdir(parents=True, exist_ok=True)\n\n                if background:\n                    # 后台执行：Popen + 输出到文件\n                    out_f = open(output_path, \"w\", encoding=\"utf-8\")\n\n                    if sys.platform == \"win32\":\n                        CREATE_NO_WINDOW = 0x08000000\n                        DETACHED_PROCESS = 0x00000008\n                        process = subprocess.Popen(\n                            command,\n                            shell=True,\n                            stdout=out_f,\n                            stderr=subprocess.STDOUT,\n                            text=True,\n                            cwd=str(abs_working_dir),\n                            stdin=subprocess.DEVNULL,\n                            creationflags=CREATE_NO_WINDOW | DETACHED_PROCESS,\n                            close_fds=False,\n                        )\n                    else:\n                        process = subprocess.Popen(\n                            command,\n                            shell=True,\n                            stdout=out_f,\n                            stderr=subprocess.STDOUT,\n                            text=True,\n                            cwd=str(abs_working_dir),\n                            stdin=subprocess.DEVNULL,\n                            start_new_session=True,\n                        )\n\n                    process_id = f\"bg_cmd_{int(time.time())}_{process.pid}\"\n                    BACKGROUND_PROCESSES[process_id] = {\n                        \"task_id\": str(workspace),\n                        \"pid\": process.pid,\n                        \"command\": command,\n                        \"output_file\": output_file,\n                        \"start_time\": datetime.now().isoformat(),\n                        \"process_obj\": process,\n                    }\n\n                    return {\n                        \"status\": \"success\",\n                        \"output\": (\n                            \"✅ 命令已在后台启动\\n\"\n                            f\"   Process ID: {process_id}\\n\"\n                            f\"   PID: {process.pid}\\n\"\n                            f\"   输出文件: {output_file}\\n\"\n                            f\"   提示: 使用 file_read 读取 {output_file} 查看执行结果\\n\"\n                            \"   终止: 使用 execute_command 运行 `ps`/`kill` 或在桌面端停止任务\"\n                        ),\n                        \"error\": \"\",\n                    }\n                else:\n                    # 非后台：run + 输出到文件\n                    with open(output_path, \"w\", encoding=\"utf-8\") as out_f:\n                        result = subprocess.run(\n                            command,\n                            shell=True,\n                            stdout=out_f,\n                            stderr=subprocess.STDOUT,\n                            text=True,\n                            timeout=timeout,\n                            cwd=str(abs_working_dir),\n                            stdin=subprocess.DEVNULL,\n                        )\n\n                    output = f\"命令执行完成，输出已保存到: {output_file}\\nExit code: {result.returncode}\"\n                    # 读取部分预览\n                    try:\n                        with open(output_path, \"r\", encoding=\"utf-8\") as f:\n                            content = f.read(1000)\n                        if content:\n                            output += \"\\n\\n输出预览（前1000字符）:\\n\" + content + (\"\\n...\" if len(content) == 1000 else \"\")\n                    except Exception:\n                        pass\n\n                    return {\"status\": \"success\", \"output\": output, \"error\": \"\"}\n\n            # 不重定向：直接捕获输出\n            result = subprocess.run(\n                command,\n                shell=True,\n                capture_output=True,\n                text=True,\n                timeout=timeout,\n                cwd=str(abs_working_dir),\n                stdin=subprocess.DEVNULL,\n            )\n\n            output = result.stdout or \"\"\n            if result.stderr:\n                output += f\"\\nSTDERR:\\n{result.stderr}\"\n            if result.returncode != 0:\n                output += f\"\\nExit code: {result.returncode}\"\n\n            return {\"status\": \"success\", \"output\": output, \"error\": \"\"}\n            \n        except subprocess.TimeoutExpired:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Command timeout ({timeout}s)\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass GrepTool(BaseTool):\n    \"\"\"文本搜索工具（跨平台grep实现）\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        在文件中搜索匹配的文本模式（跨平台实现）\n        \n        Parameters:\n            pattern (str): 要搜索的正则表达式模式\n            search_path (str, optional): 搜索路径相对路径，默认为当前工作区根目录\n            file_pattern (str, optional): 文件名匹配模式（支持通配符），如 \"*.py\", \"*.txt\"\n            recursive (bool, optional): 是否递归搜索子目录，默认True\n            case_sensitive (bool, optional): 是否大小写敏感，默认True\n            show_line_number (bool, optional): 是否显示行号，默认True\n            max_results (int, optional): 最大结果数量，默认100\n            context_lines (int, optional): 显示匹配行前后的上下文行数，默认0\n        \"\"\"\n        try:\n            pattern = parameters.get(\"pattern\")\n            if not pattern:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"pattern is required\"\n                }\n            \n            search_path = parameters.get(\"search_path\", \".\")\n            file_pattern = parameters.get(\"file_pattern\", \"*\")\n            recursive = parameters.get(\"recursive\", True)\n            case_sensitive = parameters.get(\"case_sensitive\", True)\n            show_line_number = parameters.get(\"show_line_number\", True)\n            max_results = parameters.get(\"max_results\", 100)\n            context_lines = parameters.get(\"context_lines\", 0)\n            \n            # 获取绝对路径，确保只在 workspace 内搜索\n            abs_search_path = get_abs_path(task_id, search_path)\n            workspace = Path(task_id)\n            \n            # 安全检查：确保搜索路径在 workspace 内\n            try:\n                abs_search_path.resolve().relative_to(workspace.resolve())\n            except ValueError:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Search path must be within workspace: {search_path}\"\n                }\n            \n            if not abs_search_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Search path not found: {search_path}\"\n                }\n            \n            # 编译正则表达式\n            flags = 0 if case_sensitive else re.IGNORECASE\n            try:\n                regex = re.compile(pattern, flags)\n            except re.error as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Invalid regex pattern: {str(e)}\"\n                }\n            \n            # 执行搜索\n            results = []\n            total_matches = 0\n            files_searched = 0\n            \n            # 获取要搜索的文件列表\n            if abs_search_path.is_file():\n                files_to_search = [abs_search_path]\n            else:\n                if recursive:\n                    files_to_search = list(abs_search_path.rglob(file_pattern))\n                else:\n                    files_to_search = list(abs_search_path.glob(file_pattern))\n                \n                # 只保留文件（排除目录）\n                files_to_search = [f for f in files_to_search if f.is_file()]\n            \n            # 搜索每个文件\n            for file_path in files_to_search:\n                if total_matches >= max_results:\n                    break\n                \n                try:\n                    # 尝试读取文件（跳过二进制文件）\n                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:\n                        lines = f.readlines()\n                    \n                    files_searched += 1\n                    matches_in_file = []\n                    \n                    for line_num, line in enumerate(lines, 1):\n                        if total_matches >= max_results:\n                            break\n                        \n                        if regex.search(line):\n                            total_matches += 1\n                            \n                            # 计算相对路径（相对于 workspace）\n                            try:\n                                relative_path = file_path.relative_to(workspace)\n                            except ValueError:\n                                relative_path = file_path\n                            \n                            # 构建输出行\n                            if show_line_number:\n                                match_line = f\"{relative_path}:{line_num}: {line.rstrip()}\"\n                            else:\n                                match_line = f\"{relative_path}: {line.rstrip()}\"\n                            \n                            # 添加上下文行\n                            if context_lines > 0:\n                                context = []\n                                # 前面的行\n                                for i in range(max(0, line_num - context_lines - 1), line_num - 1):\n                                    context.append(f\"{relative_path}:{i+1}- {lines[i].rstrip()}\")\n                                \n                                context.append(match_line)\n                                \n                                # 后面的行\n                                for i in range(line_num, min(len(lines), line_num + context_lines)):\n                                    context.append(f\"{relative_path}:{i+1}- {lines[i].rstrip()}\")\n                                \n                                matches_in_file.append(\"\\n\".join(context))\n                            else:\n                                matches_in_file.append(match_line)\n                    \n                    if matches_in_file:\n                        results.extend(matches_in_file)\n                \n                except (UnicodeDecodeError, PermissionError):\n                    # 跳过无法读取的文件（二进制文件或权限问题）\n                    continue\n                except Exception:\n                    # 跳过其他错误的文件\n                    continue\n            \n            # 构建输出\n            if results:\n                output = \"\\n\".join(results)\n                summary = f\"\\n\\n搜索完成: 在 {files_searched} 个文件中找到 {total_matches} 处匹配\"\n                if total_matches >= max_results:\n                    summary += f\" (已达到最大结果数 {max_results})\"\n                output += summary\n            else:\n                output = f\"未找到匹配项。已搜索 {files_searched} 个文件。\"\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass CodeProcessManagerTool(BaseTool):\n    \"\"\"后台代码进程管理工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        管理后台执行的代码进程\n        \n        Parameters:\n            action (str): 操作类型 'list' 或 'kill'\n            process_id (str, optional): 进程ID（kill 时需要）\n        \"\"\"\n        try:\n            action = parameters.get(\"action\", \"list\")\n            \n            if action == \"list\":\n                return self._list_processes(task_id)\n            elif action == \"kill\":\n                process_id = parameters.get(\"process_id\")\n                if not process_id:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": \"process_id is required for kill action\"\n                    }\n                return self._kill_process(task_id, process_id)\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Unknown action: {action}. Use 'list' or 'kill'\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    def _list_processes(self, task_id: str) -> Dict[str, Any]:\n        \"\"\"列出指定 workspace 的后台进程\"\"\"\n        workspace_processes = []\n        \n        # 清理已结束的进程\n        finished_ids = []\n        for proc_id, info in BACKGROUND_PROCESSES.items():\n            process = info.get(\"process_obj\")\n            if process and process.poll() is not None:\n                # 进程已结束\n                finished_ids.append(proc_id)\n        \n        for proc_id in finished_ids:\n            del BACKGROUND_PROCESSES[proc_id]\n        \n        # 筛选当前 workspace 的进程\n        for proc_id, info in BACKGROUND_PROCESSES.items():\n            if info[\"task_id\"] == task_id:\n                process = info.get(\"process_obj\")\n                if info.get(\"mode\") == \"system_terminal\":\n                    exit_file = info.get(\"exit_file\")\n                    status = \"finished\" if (exit_file and Path(exit_file).exists()) else \"running\"\n                else:\n                    status = \"running\" if process and process.poll() is None else \"finished\"\n                \n                workspace_processes.append({\n                    \"process_id\": proc_id,\n                    \"pid\": info[\"pid\"],\n                    \"command\": info[\"command\"],\n                    \"output_file\": info[\"output_file\"],\n                    \"start_time\": info[\"start_time\"],\n                    \"status\": status\n                })\n        \n        if not workspace_processes:\n            output = \"当前 workspace 没有后台运行的代码进程\"\n        else:\n            output = f\"后台代码进程列表（共 {len(workspace_processes)} 个）:\\n\\n\"\n            for i, proc in enumerate(workspace_processes, 1):\n                output += f\"{i}. Process ID: {proc['process_id']}\\n\"\n                output += f\"   PID: {proc['pid']}\\n\"\n                output += f\"   命令: {proc['command']}\\n\"\n                output += f\"   输出: {proc['output_file']}\\n\"\n                output += f\"   启动: {proc['start_time']}\\n\"\n                output += f\"   状态: {proc['status']}\\n\\n\"\n        \n        return {\n            \"status\": \"success\",\n            \"output\": output,\n            \"error\": \"\"\n        }\n    \n    def _kill_process(self, task_id: str, process_id: str) -> Dict[str, Any]:\n        \"\"\"终止指定的后台进程\"\"\"\n        # 检查进程是否存在\n        if process_id not in BACKGROUND_PROCESSES:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Process not found: {process_id}\"\n            }\n        \n        info = BACKGROUND_PROCESSES[process_id]\n        \n        # 安全检查：只能终止本 workspace 的进程\n        if info[\"task_id\"] != task_id:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Permission denied: Process belongs to another workspace\"\n            }\n        \n        process = info.get(\"process_obj\")\n        pid = info[\"pid\"]\n\n        if info.get(\"mode\") == \"system_terminal\":\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"system_terminal 模式下不支持通过 manage_code_process 终止。请在 Terminal.app 中手动终止命令。\"\n            }\n        \n        # 检查进程是否还在运行\n        if process and process.poll() is None:\n            # 进程仍在运行，尝试终止\n            try:\n                process.terminate()\n                \n                # 等待最多 3 秒\n                try:\n                    process.wait(timeout=3)\n                    status = \"terminated\"\n                except subprocess.TimeoutExpired:\n                    # 强制 kill\n                    process.kill()\n                    process.wait(timeout=1)\n                    status = \"killed\"\n                \n                # 从注册表移除\n                del BACKGROUND_PROCESSES[process_id]\n                \n                output = f\"✅ 进程已终止\\n\"\n                output += f\"   Process ID: {process_id}\\n\"\n                output += f\"   PID: {pid}\\n\"\n                output += f\"   状态: {status}\\n\"\n                output += f\"   输出文件: {info['output_file']}\"\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": output,\n                    \"error\": \"\"\n                }\n            \n            except Exception as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"终止进程失败: {str(e)}\"\n                }\n        else:\n            # 进程已结束\n            del BACKGROUND_PROCESSES[process_id]\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"进程已结束（无需终止）\\n   Process ID: {process_id}\\n   输出文件: {info['output_file']}\",\n                \"error\": \"\"\n            }\n"
  },
  {
    "path": "tool_server_lite/tools/convert_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n文档转换工具 - 调用远程 Pandoc API\n舍弃，等待市面上出现免费的文档类型互转的高质量 api 吧。（tex 转万物或者 md 转万物）\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\nimport requests\nimport yaml\nimport zipfile\nimport tempfile\nimport shutil\nfrom .file_tools import BaseTool, get_abs_path\nfrom utils.user_paths import get_project_root\n\n\ndef load_convert_api_config() -> str:\n    \"\"\"读取文档转换 API 配置\"\"\"\n    try:\n        # 查找配置文件\n        config_path = get_project_root() / \"config\" / \"run_env_config\" / \"document_convert_api.yaml\"\n        \n        if not config_path.exists():\n            return \"如果有的话:8000/\"  # 默认地址\n        \n        with open(config_path, 'r', encoding='utf-8') as f:\n            config = yaml.safe_load(f)\n            api_server = config.get(\"api_server\", \"http://192.168.31.4:8000/\")\n            \n            # 确保以 / 结尾\n            if not api_server.endswith('/'):\n                api_server += '/'\n            \n            return api_server\n    except Exception:\n        return \"http://192.168.31.4:8000/\"\n\n\nclass MarkdownToPdfTool(BaseTool):\n    \"\"\"Markdown 转 PDF 工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        Markdown 转 PDF\n        \n        Parameters:\n            source_path (str): Markdown 文件相对路径\n            output_path (str, optional): 输出 PDF 相对路径\n            engine (str, optional): PDF 引擎 (pdflatex/xelatex/lualatex)，默认 xelatex\n        \"\"\"\n        try:\n            source_path = parameters.get(\"source_path\")\n            output_path = parameters.get(\"output_path\")\n            engine = parameters.get(\"engine\", \"xelatex\")\n            \n            if not source_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"source_path is required\"\n                }\n            \n            # 读取 Markdown 文件\n            abs_source = get_abs_path(task_id, source_path)\n            if not abs_source.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Source file not found: {source_path}\"\n                }\n            \n            # 准备输出路径\n            if not output_path:\n                output_path = str(Path(source_path).with_suffix('.pdf'))\n            \n            abs_output = get_abs_path(task_id, output_path)\n            abs_output.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 调用转换 API\n            api_server = load_convert_api_config()\n            url = f\"{api_server}convert/md-to-pdf\"\n            \n            with open(abs_source, 'rb') as f:\n                files = {'file': (abs_source.name, f, 'text/markdown')}\n                params = {'engine': engine}\n                \n                response = requests.post(url, files=files, params=params, timeout=120)\n                response.raise_for_status()\n            \n            # 保存 PDF\n            with open(abs_output, 'wb') as f:\n                f.write(response.content)\n            \n            file_size = abs_output.stat().st_size / 1024  # KB\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"PDF 已生成: {output_path} ({file_size:.1f} KB)\",\n                \"error\": \"\"\n            }\n            \n        except requests.RequestException as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"API 调用失败: {str(e)}\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass TexToPdfTool(BaseTool):\n    \"\"\"LaTeX 项目转 PDF 工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        LaTeX 项目转 PDF\n        \n        Parameters:\n            project_dir (str): LaTeX 项目目录相对路径\n            main_file (str): 主 tex 文件名（如 main.tex）\n            output_path (str, optional): 输出 PDF 相对路径\n            engine (str, optional): LaTeX 引擎，默认 xelatex\n        \"\"\"\n        try:\n            project_dir = parameters.get(\"project_dir\")\n            main_file = parameters.get(\"main_file\")\n            output_path = parameters.get(\"output_path\")\n            engine = parameters.get(\"engine\", \"xelatex\")\n            \n            if not project_dir:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"project_dir is required\"\n                }\n            \n            if not main_file:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"main_file is required\"\n                }\n            \n            # 获取项目目录\n            abs_project_dir = get_abs_path(task_id, project_dir)\n            if not abs_project_dir.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Project directory not found: {project_dir}\"\n                }\n            \n            # 检查主文件是否存在\n            main_file_path = abs_project_dir / main_file\n            if not main_file_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Main file not found: {main_file} in {project_dir}\"\n                }\n            \n            # 创建 tmp 目录\n            workspace = Path(task_id)\n            tmp_dir = workspace / \"tmp\"\n            tmp_dir.mkdir(exist_ok=True)\n            \n            # 打包项目为 ZIP\n            zip_path = tmp_dir / f\"{abs_project_dir.name}.zip\"\n            \n            with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:\n                for file_path in abs_project_dir.rglob('*'):\n                    if file_path.is_file():\n                        # 计算相对路径\n                        arcname = file_path.relative_to(abs_project_dir)\n                        zipf.write(file_path, arcname)\n            \n            # 准备输出路径\n            if not output_path:\n                output_path = str(Path(project_dir) / f\"{Path(main_file).stem}.pdf\")\n            \n            abs_output = get_abs_path(task_id, output_path)\n            abs_output.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 调用转换 API\n            api_server = load_convert_api_config()\n            url = f\"{api_server}convert/tex-zip-to-pdf\"\n            \n            with open(zip_path, 'rb') as f:\n                files = {'file': (zip_path.name, f, 'application/zip')}\n                params = {\n                    'main_file': main_file,\n                    'engine': engine\n                }\n                \n                response = requests.post(url, files=files, params=params, timeout=300)\n                response.raise_for_status()\n            \n            # 保存 PDF\n            with open(abs_output, 'wb') as f:\n                f.write(response.content)\n            \n            file_size = abs_output.stat().st_size / 1024  # KB\n            \n            # 清理临时 ZIP 文件\n            zip_path.unlink()\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"PDF 已生成: {output_path} ({file_size:.1f} KB)\",\n                \"error\": \"\"\n            }\n            \n        except requests.RequestException as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"API 调用失败: {str(e)}\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass MarkdownToDocxTool(BaseTool):\n    \"\"\"Markdown 转 Word 工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        Markdown 转 DOCX\n        \n        Parameters:\n            source_path (str): Markdown 文件相对路径\n            output_path (str, optional): 输出 DOCX 相对路径\n        \"\"\"\n        try:\n            source_path = parameters.get(\"source_path\")\n            output_path = parameters.get(\"output_path\")\n            \n            if not source_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"source_path is required\"\n                }\n            \n            # 读取 Markdown 文件\n            abs_source = get_abs_path(task_id, source_path)\n            if not abs_source.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Source file not found: {source_path}\"\n                }\n            \n            # 准备输出路径\n            if not output_path:\n                output_path = str(Path(source_path).with_suffix('.docx'))\n            \n            abs_output = get_abs_path(task_id, output_path)\n            abs_output.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 调用转换 API\n            api_server = load_convert_api_config()\n            url = f\"{api_server}convert/md-to-doc\"\n            \n            with open(abs_source, 'rb') as f:\n                files = {'file': (abs_source.name, f, 'text/markdown')}\n                \n                response = requests.post(url, files=files, timeout=120)\n                response.raise_for_status()\n            \n            # 保存 DOCX\n            with open(abs_output, 'wb') as f:\n                f.write(response.content)\n            \n            file_size = abs_output.stat().st_size / 1024  # KB\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"DOCX 已生成: {output_path} ({file_size:.1f} KB)\",\n                \"error\": \"\"\n            }\n            \n        except requests.RequestException as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"API 调用失败: {str(e)}\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n"
  },
  {
    "path": "tool_server_lite/tools/document_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n文档处理工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any, List\nfrom .file_tools import BaseTool, get_abs_path\n\n\nclass ParseDocumentTool(BaseTool):\n    \"\"\"PDF/文档解析工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        解析PDF或其他文档\n        \n        Parameters:\n            path (str): 文档相对路径\n            save_path (str, optional): 保存解析结果的相对路径\n                                      图片会自动保存到 {save_path}_images/ 目录\n                                      (仅对PDF有效，Word文档只提取文字和表格)\n        \"\"\"\n        try:\n            path = parameters.get(\"path\")\n            save_path = parameters.get(\"save_path\")\n            \n            abs_path = get_abs_path(task_id, path)\n            \n            if not abs_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Document not found: {path}\"\n                }\n            \n            # 自动生成图片目录路径（基于save_path）\n            if save_path:\n                # 从 save_path 生成 images_dir\n                # 例如: \"result.txt\" -> \"result_images\"\n                save_path_obj = Path(save_path)\n                images_dir = str(save_path_obj.parent / (save_path_obj.stem + \"_images\"))\n                extract_images = True\n            else:\n                # 如果没有 save_path，使用默认值\n                images_dir = \"extracted_images\"\n                extract_images = True\n            \n            # 判断文件类型\n            suffix = abs_path.suffix.lower()\n            \n            if suffix == '.pdf':\n                content = self._parse_pdf(abs_path, task_id, extract_images, images_dir)\n            elif suffix in ['.docx', '.doc']:\n                content = self._parse_word(abs_path, task_id, extract_images, images_dir)\n            elif suffix in ['.txt', '.md']:\n                with open(abs_path, 'r', encoding='utf-8') as f:\n                    content = f.read()\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Unsupported document type: {suffix}\"\n                }\n            \n            # 保存解析结果\n            if save_path:\n                abs_save_path = get_abs_path(task_id, save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(content)\n                output = f\"结果保存在 {save_path}\"\n            else:\n                output = content\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    def _parse_pdf(self, pdf_path: Path, task_id: str, extract_images: bool, images_dir: str) -> str:\n        \"\"\"解析PDF文件 - 使用 pdfplumber（质量更高）\"\"\"\n        try:\n            import pdfplumber\n            from PIL import Image\n            \n            text_content = []\n            image_counter = 0\n            \n            with pdfplumber.open(pdf_path) as pdf:\n                num_pages = len(pdf.pages)\n                \n                for page_num, page in enumerate(pdf.pages, 1):\n                    # 提取文本\n                    text = page.extract_text() or \"\"\n                    \n                    # 提取表格（转为Markdown格式）\n                    tables = page.extract_tables()\n                    \n                    page_content = f\"--- Page {page_num}/{num_pages} ---\\n{text}\\n\"\n                    \n                    # 如果有表格，添加表格内容（Markdown格式）\n                    if tables:\n                        page_content += f\"\\n[Tables found: {len(tables)}]\\n\"\n                        for table_idx, table in enumerate(tables, 1):\n                            page_content += f\"\\n--- Table {table_idx} ---\\n\"\n                            page_content += self._table_to_markdown(table)\n                    \n                    # 提取图片\n                    if extract_images and hasattr(page, 'images'):\n                        images = page.images\n                        if images:\n                            page_content += f\"\\n[Images found: {len(images)}]\\n\"\n                            for img_idx, img in enumerate(images, 1):\n                                image_counter += 1\n                                img_filename = f\"pdf_page{page_num}_img{img_idx}.png\"\n                                img_path = self._save_pdf_image(\n                                    page, img, task_id, images_dir, img_filename\n                                )\n                                if img_path:\n                                    page_content += f\"\\n[Image {img_idx}]: {img_path}\\n\"\n                    \n                    text_content.append(page_content)\n            \n            result = '\\n'.join(text_content)\n            if image_counter > 0:\n                result = f\"[提取了 {image_counter} 张图片到 {images_dir}/ 目录]\\n\\n\" + result\n            \n            return result\n            \n        except ImportError as e:\n            if 'pdfplumber' in str(e):\n                raise Exception(\"pdfplumber not installed. Run: pip install pdfplumber\")\n            elif 'PIL' in str(e):\n                raise Exception(\"Pillow not installed. Run: pip install Pillow\")\n            else:\n                raise e\n        except Exception as e:\n            raise Exception(f\"PDF parsing error: {str(e)}\")\n    \n    def _parse_word(self, doc_path: Path, task_id: str, extract_images: bool, images_dir: str) -> str:\n        \"\"\"解析Word文档 - 只提取文字和表格，不提取图片（避免提取过多小图标）\"\"\"\n        try:\n            import docx\n            from docx.oxml.table import CT_Tbl\n            from docx.oxml.text.paragraph import CT_P\n            from docx.table import Table\n            from docx.text.paragraph import Paragraph\n            \n            doc = docx.Document(doc_path)\n            content_parts = []\n            table_counter = 0\n            \n            # 遍历文档的所有元素（保持顺序）\n            for element in doc.element.body:\n                # 处理段落\n                if isinstance(element, CT_P):\n                    para = Paragraph(element, doc)\n                    para_text = para.text.strip()\n                    \n                    # 只添加段落文本，忽略图片\n                    if para_text:\n                        content_parts.append(para_text)\n                \n                # 处理表格\n                elif isinstance(element, CT_Tbl):\n                    table = Table(element, doc)\n                    table_counter += 1\n                    content_parts.append(f\"\\n--- Table {table_counter} ---\\n\")\n                    \n                    # 提取表格数据\n                    table_data = []\n                    for row in table.rows:\n                        row_data = [cell.text.strip() for cell in row.cells]\n                        table_data.append(row_data)\n                    \n                    # 转为Markdown格式\n                    content_parts.append(self._table_to_markdown(table_data))\n            \n            result = '\\n'.join(content_parts)\n            \n            # 添加统计信息\n            if table_counter > 0:\n                result = f\"[提取了 {table_counter} 个表格]\\n\\n\" + result\n            \n            return result\n            \n        except ImportError:\n            raise Exception(\"python-docx not installed. Run: pip install python-docx\")\n        except Exception as e:\n            raise Exception(f\"Word document parsing error: {str(e)}\")\n    \n    def _table_to_markdown(self, table_data: List[List[str]]) -> str:\n        \"\"\"将表格数据转换为Markdown格式\"\"\"\n        if not table_data or len(table_data) == 0:\n            return \"\"\n        \n        markdown_lines = []\n        \n        # 处理表头（第一行）\n        header = table_data[0]\n        markdown_lines.append(\"| \" + \" | \".join([str(cell or \"\") for cell in header]) + \" |\")\n        \n        # 添加分隔线\n        markdown_lines.append(\"| \" + \" | \".join([\"---\" for _ in header]) + \" |\")\n        \n        # 处理数据行\n        for row in table_data[1:]:\n            # 确保行的长度与表头一致\n            padded_row = row + [\"\"] * (len(header) - len(row)) if len(row) < len(header) else row[:len(header)]\n            markdown_lines.append(\"| \" + \" | \".join([str(cell or \"\") for cell in padded_row]) + \" |\")\n        \n        return \"\\n\".join(markdown_lines) + \"\\n\"\n    \n    def _save_pdf_image(self, page, img_info: Dict, task_id: str, images_dir: str, filename: str) -> str:\n        \"\"\"保存PDF中的图片 - 使用PyMuPDF提取\"\"\"\n        try:\n            # 创建图片保存目录\n            abs_images_dir = get_abs_path(task_id, images_dir)\n            abs_images_dir.mkdir(parents=True, exist_ok=True)\n            \n            # pdfplumber本身不直接支持提取图片二进制数据\n            # 这里使用PyMuPDF (fitz) 来提取\n            try:\n                import fitz  # PyMuPDF - 可选依赖，用于提取PDF图片\n                from PIL import Image\n                \n                # 获取PDF路径和页码\n                pdf_path = page.pdf.path\n                page_num = page.page_number - 1  # PyMuPDF使用0索引\n                \n                # 打开PDF文档\n                doc = fitz.open(pdf_path)\n                fitz_page = doc[page_num]\n                \n                # 获取页面中的图片\n                image_list = fitz_page.get_images()\n                \n                if not image_list:\n                    return None\n                \n                # 提取第一张图片（简化处理）\n                # 更复杂的实现需要匹配pdfplumber的img_info坐标\n                xref = image_list[0][0]  # 获取图片引用\n                base_image = doc.extract_image(xref)\n                image_bytes = base_image[\"image\"]\n                image_ext = base_image[\"ext\"]\n                \n                # 保存图片\n                img_path = abs_images_dir / filename.replace('.png', f'.{image_ext}')\n                with open(img_path, 'wb') as f:\n                    f.write(image_bytes)\n                \n                doc.close()\n                \n                # 返回相对路径\n                return f\"{images_dir}/{img_path.name}\"\n                \n            except ImportError:\n                # 如果PyMuPDF未安装，返回占位符信息\n                return f\"{images_dir}/{filename} (需安装PyMuPDF: pip install PyMuPDF)\"\n            except Exception as e:\n                # 如果提取失败，返回None\n                return None\n                \n        except Exception as e:\n            return None\n    \n\n\nif __name__ == \"__main__\":\n    \"\"\"测试文档解析工具\"\"\"\n    import sys\n    import os\n    \n    # 添加项目根目录到路径，这样可以正确导入模块\n    project_root = Path(__file__).parent.parent.parent\n    sys.path.insert(0, str(project_root))\n    \n    # 现在可以正确导入\n    os.chdir(str(project_root))\n    \n    # 测试文件路径 - 测试PDF文档解析\n    test_doc_path = project_root / \"test_doc\" / \"1.pdf\"\n    \n    print(\"=\" * 60)\n    print(\"📄 测试PDF文档解析工具（文字+表格+图片）\")\n    print(\"=\" * 60)\n    print(f\"测试文件: {test_doc_path}\")\n    print(f\"文件存在: {test_doc_path.exists()}\")\n    print()\n    \n    if not test_doc_path.exists():\n        print(\"❌ 测试文件不存在!\")\n        sys.exit(1)\n    \n    # 创建工具实例\n    tool = ParseDocumentTool()\n    \n    # 设置保存路径（同目录下）\n    save_path = \"1_parsed.txt\"\n    # 图片会自动保存到 1_parsed_images/ 目录\n    \n    # 执行解析\n    print(\"🔄 开始解析PDF文档...\")\n    print(f\"   - 保存路径: {save_path}\")\n    print(f\"   - 图片目录: {Path(save_path).stem}_images/ (自动生成)\")\n    print()\n    \n    try:\n        # 使用相对路径（相对于test_doc目录）\n        result = tool.execute(\n            task_id=\"test_doc\",  # 使用test_doc作为task_id\n            parameters={\n                \"path\": \"1.pdf\",\n                \"save_path\": save_path\n            }\n        )\n        \n        print(\"=\" * 60)\n        print(\"📊 解析结果\")\n        print(\"=\" * 60)\n        print(f\"状态: {result['status']}\")\n        print()\n        \n        if result['status'] == 'success':\n            print(\"✅ 解析成功!\")\n            print(f\"\\n{result['output']}\")\n            \n            # 显示保存的文件信息\n            abs_save_path = get_abs_path(\"test_doc\", save_path)\n            if abs_save_path.exists():\n                file_size = abs_save_path.stat().st_size\n                print(f\"\\n📁 输出文件信息:\")\n                print(f\"   - 路径: {abs_save_path}\")\n                print(f\"   - 大小: {file_size:,} 字节\")\n                \n                # 显示前500个字符\n                with open(abs_save_path, 'r', encoding='utf-8') as f:\n                    content_preview = f.read(500)\n                print(f\"\\n📝 内容预览 (前500字符):\")\n                print(\"-\" * 60)\n                print(content_preview)\n                if file_size > 500:\n                    print(\"...\")\n                print(\"-\" * 60)\n            \n            # 检查图片目录\n            images_dir = Path(save_path).stem + \"_images\"\n            abs_images_dir = get_abs_path(\"test_doc\", images_dir)\n            if abs_images_dir.exists():\n                image_files = list(abs_images_dir.glob(\"*\"))\n                if image_files:\n                    print(f\"\\n🖼️  提取的图片:\")\n                    for img_file in image_files:\n                        img_size = img_file.stat().st_size\n                        print(f\"   - {img_file.name} ({img_size:,} 字节)\")\n                else:\n                    print(f\"\\n📂 图片目录已创建，但没有提取到图片\")\n        else:\n            print(f\"❌ 解析失败!\")\n            print(f\"错误: {result['error']}\")\n    \n    except Exception as e:\n        print(f\"❌ 测试过程中出错:\")\n        print(f\"错误类型: {type(e).__name__}\")\n        print(f\"错误信息: {str(e)}\")\n        import traceback\n        traceback.print_exc()\n    \n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试完成!\")\n    print(\"=\" * 60)\n\n"
  },
  {
    "path": "tool_server_lite/tools/file_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n文件操作工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any, Optional\nimport shutil\nimport chardet\n\n\nclass BaseTool:\n    \"\"\"工具基类\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"执行工具\"\"\"\n        raise NotImplementedError\n\n\ndef get_abs_path(task_id: str, relative_path: str) -> Path:\n    \"\"\"\n    将相对路径转换为绝对路径\n    \n    Args:\n        task_id: workspace 绝对路径\n        relative_path: 相对路径\n        \n    Returns:\n        绝对路径\n    \"\"\"\n    workspace = Path(task_id)\n    # 移除开头的 / 或 ./\n    rel_path = str(relative_path).lstrip('/').lstrip('./')\n    return workspace / rel_path\n\n\ndef detect_encoding(file_path: Path) -> str:\n    \"\"\"检测文件编码\"\"\"\n    try:\n        with open(file_path, 'rb') as f:\n            raw_data = f.read(10240)\n        result = chardet.detect(raw_data)\n        encoding = result.get('encoding', 'utf-8')\n        return encoding or 'utf-8'\n    except Exception:\n        return 'utf-8'\n\n\n# 常见二进制文件后缀名（黑名单）\nBINARY_EXTENSIONS = {\n    # 图片\n    '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg', '.webp', '.tiff', '.tif',\n    # 文档\n    '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',\n    # 压缩文件\n    '.zip', '.tar', '.gz', '.bz2', '.rar', '.7z', '.xz',\n    # 可执行文件\n    '.exe', '.dll', '.so', '.dylib', '.bin', '.app',\n    # 音视频\n    '.mp3', '.mp4', '.avi', '.mov', '.wav', '.flac', '.mkv', '.webm',\n    # 其他\n    '.pyc', '.pyo', '.o', '.a', '.lib', '.class', '.jar'\n}\n\n\ndef is_binary_file(file_path: Path) -> bool:\n    \"\"\"\n    判断是否为二进制文件\n    \n    检测策略：\n    1. 先检查文件后缀名（高效）\n    2. 如果后缀名不在黑名单中，再检查文件内容（准确）\n    \"\"\"\n    try:\n        # 策略1：检查文件后缀名（快速路径）\n        if file_path.suffix.lower() in BINARY_EXTENSIONS:\n            return True\n        \n        # 策略2：检查文件内容（检查是否包含 null 字节）\n        with open(file_path, 'rb') as f:\n            chunk = f.read(1024)\n        return b'\\x00' in chunk\n    except Exception:\n        return False\n\n\nclass FileReadTool(BaseTool):\n    \"\"\"文件读取工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        读取文件内容（支持单个或多个文件）\n        \n        Parameters:\n            path (list): 文件路径数组，单个文件传 ['file.txt']\n            file_path (str or list): 同 path（兼容性参数）\n            start_line (int, optional): 起始行号（从1开始）\n            end_line (int, optional): 结束行号\n            encoding (str, optional): 文件编码\n            show_line_numbers (bool, optional): 是否显示行号，默认 True\n        \"\"\"\n        try:\n            # 兼容 path 和 file_path 两种参数名\n            path = parameters.get(\"path\") or parameters.get(\"file_path\")\n            \n            if not path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"Missing required parameter: 'path' or 'file_path'\"\n                }\n            \n            # 统一转换为列表\n            if isinstance(path, str):\n                # 兼容旧版本：如果是字符串，转换为单元素列表\n                path = [path]\n            elif not isinstance(path, list):\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Invalid path type: {type(path).__name__}, expected list\"\n                }\n            \n            # 根据列表长度决定使用哪种模式\n            if len(path) == 1:\n                # 单文件模式\n                return self._read_single_file(task_id, path[0], parameters)\n            else:\n                # 多文件模式\n                return self._read_multiple_files(task_id, path, parameters)\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    def _read_single_file(self, task_id: str, path: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"读取单个文件\"\"\"\n        start_line = parameters.get(\"start_line\")\n        end_line = parameters.get(\"end_line\")\n        encoding = parameters.get(\"encoding\")\n        show_line_numbers = parameters.get(\"show_line_numbers\", True)\n        \n        abs_path = get_abs_path(task_id, path)\n        \n        # 检查文件是否存在\n        if not abs_path.exists():\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"File not found: {path}\"\n            }\n        \n        # 检查是否为二进制文件\n        if is_binary_file(abs_path):\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Cannot read binary file: {path}. Use other tools to analyze the file.\"\n            }\n        \n        # 自动检测编码\n        if not encoding:\n            encoding = detect_encoding(abs_path)\n        \n        # 读取文件\n        try:\n            with open(abs_path, 'r', encoding=encoding) as f:\n                lines = f.readlines()\n        except UnicodeDecodeError:\n            # 如果指定编码失败，尝试 utf-8\n            with open(abs_path, 'r', encoding='utf-8', errors='ignore') as f:\n                lines = f.readlines()\n        \n        # 处理行范围\n        start_idx = (start_line - 1) if start_line else 0\n        end_idx = end_line if end_line else len(lines)\n        selected_lines = lines[start_idx:end_idx]\n        \n        # 格式化输出\n        if show_line_numbers:\n            # 带行号格式\n            import json\n            output_lines = []\n            for i, line in enumerate(selected_lines, start=start_idx + 1):\n                output_lines.append({\n                    \"line\": i,\n                    \"content\": line.rstrip('\\n\\r')\n                })\n            content = json.dumps(output_lines, ensure_ascii=False, indent=2)\n        else:\n            # 纯文本格式\n            content = ''.join(selected_lines)\n        \n        return {\n            \"status\": \"success\",\n            \"output\": content,\n            \"error\": \"\"\n        }\n    \n    def _read_multiple_files(self, task_id: str, paths: list, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"读取多个文件\"\"\"\n        import json\n        \n        start_line = parameters.get(\"start_line\")\n        end_line = parameters.get(\"end_line\")\n        encoding = parameters.get(\"encoding\")\n        show_line_numbers = parameters.get(\"show_line_numbers\", True)\n        \n        results = {}\n        errors = []\n        success_count = 0\n        \n        for path in paths:\n            try:\n                abs_path = get_abs_path(task_id, path)\n                \n                # 检查文件是否存在\n                if not abs_path.exists():\n                    errors.append(f\"File not found: {path}\")\n                    results[path] = {\n                        \"status\": \"error\",\n                        \"error\": f\"File not found: {path}\"\n                    }\n                    continue\n                \n                # 检查是否为二进制文件\n                if is_binary_file(abs_path):\n                    errors.append(f\"Cannot read binary file: {path}\")\n                    results[path] = {\n                        \"status\": \"error\",\n                        \"error\": f\"Binary file, use other tools\"\n                    }\n                    continue\n                \n                # 自动检测编码\n                file_encoding = encoding or detect_encoding(abs_path)\n                \n                # 读取文件\n                try:\n                    with open(abs_path, 'r', encoding=file_encoding) as f:\n                        lines = f.readlines()\n                except UnicodeDecodeError:\n                    with open(abs_path, 'r', encoding='utf-8', errors='ignore') as f:\n                        lines = f.readlines()\n                \n                # 处理行范围\n                start_idx = (start_line - 1) if start_line else 0\n                end_idx = end_line if end_line else len(lines)\n                selected_lines = lines[start_idx:end_idx]\n                \n                # 格式化内容\n                if show_line_numbers:\n                    output_lines = []\n                    for i, line in enumerate(selected_lines, start=start_idx + 1):\n                        output_lines.append({\n                            \"line\": i,\n                            \"content\": line.rstrip('\\n\\r')\n                        })\n                    content = output_lines  # 保持为列表，稍后统一序列化\n                else:\n                    content = ''.join(selected_lines)\n                \n                results[path] = {\n                    \"status\": \"success\",\n                    \"content\": content,\n                    \"total_lines\": len(lines)\n                }\n                success_count += 1\n                \n            except Exception as e:\n                errors.append(f\"{path}: {str(e)}\")\n                results[path] = {\n                    \"status\": \"error\",\n                    \"error\": str(e)\n                }\n        \n        # 构建输出\n        output_data = {\n            \"total_files\": len(paths),\n            \"success_count\": success_count,\n            \"error_count\": len(errors),\n            \"files\": results\n        }\n        \n        if errors:\n            output_data[\"errors\"] = errors\n        \n        return {\n            \"status\": \"success\" if success_count > 0 else \"error\",\n            \"output\": json.dumps(output_data, ensure_ascii=False, indent=2),\n            \"error\": \"\\n\".join(errors) if errors else \"\"\n        }\n\n\nclass FileWriteTool(BaseTool):\n    \"\"\"文件写入工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        写入文件\n        \n        Parameters:\n            path (str): 相对路径\n            content (str): 文件内容\n            mode (str, optional): 写入模式 'write'(覆盖) 或 'append'(追加)，默认 'write'\n            start_line (int, optional): replace模式 - 起始行号\n            end_line (int, optional): replace模式 - 结束行号\n        \"\"\"\n        try:\n            path = parameters.get(\"path\")\n            content = parameters.get(\"content\", \"\")\n            mode = parameters.get(\"mode\", \"write\")\n            start_line = parameters.get(\"start_line\")\n            end_line = parameters.get(\"end_line\")\n            \n            # 禁止写入 reference.bib 文件\n            # if path and path.endswith(\"reference.bib\"):\n            #     return {\n            #         \"status\": \"error\",\n            #         \"output\": \"\",\n            #         \"error\": \"禁止使用 file_write 工具写入 reference.bib 文件。请使用专门的参考文献管理工具：reference_add（添加）、reference_delete（删除）。\"\n            #     }\n            \n            abs_path = get_abs_path(task_id, path)\n            \n            # 确保父目录存在\n            abs_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # Replace line 模式\n            if start_line is not None:\n                if not abs_path.exists():\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"File not found for line replacement: {path}\"\n                    }\n                \n                with open(abs_path, 'r', encoding='utf-8') as f:\n                    lines = f.readlines()\n                \n                start_idx = start_line - 1\n                end_idx = end_line if end_line else start_line\n                \n                # 替换指定行\n                new_lines = lines[:start_idx] + [content + '\\n'] + lines[end_idx:]\n                \n                with open(abs_path, 'w', encoding='utf-8') as f:\n                    f.writelines(new_lines)\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": f\"Replaced lines {start_line}-{end_idx} in {path}\",\n                    \"error\": \"\"\n                }\n            \n            # 普通写入模式\n            if mode == \"append\":\n                with open(abs_path, 'a', encoding='utf-8') as f:\n                    f.write(content)\n                msg = f\"Appended to {path}\"\n            else:\n                with open(abs_path, 'w', encoding='utf-8') as f:\n                    f.write(content)\n                msg = f\"Written to {path}\"\n            \n            return {\n                \"status\": \"success\",\n                \"output\": msg,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass DirListTool(BaseTool):\n    \"\"\"目录列表工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        列出目录内容\n        \n        Parameters:\n            path (str): 相对路径，默认 '.'\n            recursive (bool): 是否递归列出子目录，默认 False\n        \"\"\"\n        try:\n            path = parameters.get(\"path\", \".\")\n            recursive = parameters.get(\"recursive\", False)\n            abs_path = get_abs_path(task_id, path)\n            \n            if not abs_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Directory not found: {path}\"\n                }\n            \n            if not abs_path.is_dir():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Not a directory: {path}\"\n                }\n            \n            if recursive:\n                items = self._list_recursive(abs_path, abs_path)\n            else:\n                items = []\n                for item in sorted(abs_path.iterdir()):\n                    item_type = \"dir\" if item.is_dir() else \"file\"\n                    items.append(f\"[{item_type}] {item.name}\")\n            \n            output = \"\\n\".join(items) if items else \"(empty directory)\"\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    def _list_recursive(self, root: Path, current: Path, indent: int = 0) -> list:\n        \"\"\"递归列出目录内容，排除 code_env 目录\"\"\"\n        items = []\n        \n        try:\n            for item in sorted(current.iterdir()):\n                # 跳过 code_env 目录\n                if item.name == \"code_env\":\n                    continue\n                \n                # 只显示当前项的名称（不带父路径）\n                indent_str = \"  \" * indent\n                item_type = \"dir\" if item.is_dir() else \"file\"\n                items.append(f\"{indent_str}[{item_type}] {item.name}\")\n                \n                # 如果是目录且不是 code_env，递归处理\n                if item.is_dir():\n                    items.extend(self._list_recursive(root, item, indent + 1))\n        except PermissionError:\n            pass\n        \n        return items\n\n\nclass DirCreateTool(BaseTool):\n    \"\"\"创建目录工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        创建目录\n        \n        Parameters:\n            path (str): 相对路径\n        \"\"\"\n        try:\n            path = parameters.get(\"path\")\n            abs_path = get_abs_path(task_id, path)\n            \n            abs_path.mkdir(parents=True, exist_ok=True)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"Directory created: {path}\",\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass FileMoveTool(BaseTool):\n    \"\"\"文件移动/复制工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        移动/重命名/复制文件\n        \n        Parameters:\n            source (str): 源文件相对路径\n            destination (str): 目标相对路径\n            copy (bool): 是否复制（保留原文件），默认 False（移动）\n        \"\"\"\n        try:\n            sources = parameters.get(\"source\")\n            destination = parameters.get(\"destination\")\n            copy_mode = parameters.get(\"copy\", False)\n            dst_path = get_abs_path(task_id, destination)\n            for source in sources:\n            \n                src_path = get_abs_path(task_id, source)\n            \n            \n                if not src_path.exists():\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"Source not found: {source}\"\n                    }\n            \n            # 确保目标目录存在\n                dst_path.parent.mkdir(parents=True, exist_ok=True)\n                \n                if copy_mode:\n                    # 复制模式\n                    if src_path.is_dir():\n                        shutil.copytree(str(src_path), str(dst_path), dirs_exist_ok=True)\n                    else:\n                        shutil.copy2(str(src_path), str(dst_path))\n                    action = \"Copied\"\n                else:\n                    # 移动模式\n                    shutil.move(str(src_path), str(dst_path))\n                    action = \"Moved\"\n                \n            return {\n                    \"status\": \"success\",\n                    \"output\": f\"全部移动成功\",\n                    \"error\": \"\"\n                }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass FileDeleteTool(BaseTool):\n    \"\"\"文件删除工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        删除文件或目录\n        \n        Parameters:\n            path (str): 相对路径\n        \"\"\"\n        try:\n            path = parameters.get(\"path\")\n            abs_path = get_abs_path(task_id, path)\n            \n            if not abs_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Path not found: {path}\"\n                }\n            \n            if abs_path.is_dir():\n                shutil.rmtree(abs_path)\n            else:\n                abs_path.unlink()\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"Deleted: {path}\",\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n"
  },
  {
    "path": "tool_server_lite/tools/human_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n人类交互工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\nimport asyncio\nfrom .file_tools import BaseTool\nfrom utils.event_emitter import get_event_emitter\n\n# 全局 HIL 任务状态存储\nHIL_TASKS = {}\n\n# 全局工具确认请求存储（与 HIL 分开）\nTOOL_CONFIRMATIONS = {}\n\n\nclass HumanInLoopTool(BaseTool):\n    \"\"\"人类交互工具 - 挂起等待人类完成任务（异步，不阻塞服务器）\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        人类交互 - 挂起等待人类完成\n        \n        Parameters:\n            hil_id (str): 人类任务唯一ID\n            instruction (str): 给人类的指令\n            timeout (int, optional): 超时时间（秒），默认 None（无限等待）\n        \"\"\"\n        try:\n            hil_id = parameters.get(\"hil_id\")\n            instruction = parameters.get(\"instruction\")\n            timeout = parameters.get(\"timeout\")  # 默认 None\n            \n            if not hil_id:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"hil_id is required\"\n                }\n            \n            if not instruction:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"instruction is required\"\n                }\n            \n            # 注册 HIL 任务\n            HIL_TASKS[hil_id] = {\n                \"status\": \"waiting\",\n                \"instruction\": instruction,\n                \"task_id\": task_id,\n                \"result\": None\n            }\n\n            try:\n                get_event_emitter().human_in_loop(\n                    hil_id=hil_id,\n                    title=\"Human-in-Loop\",\n                    message=instruction,\n                    ui={\"type\": \"text\"},\n                    timeout_sec=int(timeout) if timeout is not None else 1800,\n                    resume_hint=\"请在前端或 CLI 中直接回复该请求\",\n                )\n            except Exception:\n                pass\n            \n            # 异步轮询等待完成\n            start_time = asyncio.get_event_loop().time()\n            check_interval = 2  # 每2秒检查一次\n            \n            while True:\n                # 检查是否超时\n                if timeout is not None:\n                    elapsed = asyncio.get_event_loop().time() - start_time\n                    if elapsed > timeout:\n                        HIL_TASKS[hil_id][\"status\"] = \"timeout\"\n                        return {\n                            \"status\": \"error\",\n                            \"output\": \"\",\n                            \"error\": f\"Human task timeout ({timeout}s)\"\n                        }\n                \n                # 检查任务状态\n                task = HIL_TASKS.get(hil_id)\n                if task and task[\"status\"] == \"completed\":\n                    result = task.get(\"result\", \"任务已完成\")\n                    # 清理任务\n                    del HIL_TASKS[hil_id]\n                    return {\n                        \"status\": \"success\",\n                        \"output\": f\": 用户回复：{result}\",\n                        \"error\": \"\"\n                    }\n                \n                # 异步等待（不阻塞服务器）\n                await asyncio.sleep(check_interval)\n                \n        except Exception as e:\n            # 清理任务\n            if hil_id in HIL_TASKS:\n                del HIL_TASKS[hil_id]\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\ndef get_hil_status(hil_id: str) -> Dict[str, Any]:\n    \"\"\"获取 HIL 任务状态\"\"\"\n    task = HIL_TASKS.get(hil_id)\n    if not task:\n        return {\n            \"found\": False,\n            \"error\": f\"HIL task not found: {hil_id}\"\n        }\n    \n    return {\n        \"found\": True,\n        \"hil_id\": hil_id,\n        \"status\": task[\"status\"],\n        \"instruction\": task[\"instruction\"],\n        \"task_id\": task[\"task_id\"]\n    }\n\n\ndef respond_hil_task(hil_id: str, response: str) -> Dict[str, Any]:\n    \"\"\"响应 HIL 任务（用户可以回复任何内容）\"\"\"\n    task = HIL_TASKS.get(hil_id)\n    if not task:\n        return {\n            \"success\": False,\n            \"error\": f\"HIL task not found: {hil_id}\"\n        }\n    \n    # 标记为完成，并保存用户响应\n    HIL_TASKS[hil_id][\"status\"] = \"completed\"\n    HIL_TASKS[hil_id][\"result\"] = response\n    \n    return {\n        \"success\": True,\n        \"message\": f\"HIL task {hil_id} responded with: {response[:100]}\"\n    }\n\n\ndef list_hil_tasks() -> Dict[str, Any]:\n    \"\"\"列出所有 HIL 任务\"\"\"\n    tasks = []\n    for hil_id, task in HIL_TASKS.items():\n        tasks.append({\n            \"hil_id\": hil_id,\n            \"status\": task[\"status\"],\n            \"instruction\": task[\"instruction\"],\n            \"task_id\": task[\"task_id\"]\n        })\n    \n    return {\n        \"total\": len(tasks),\n        \"tasks\": tasks\n    }\n\n\ndef get_hil_task_for_workspace(task_id: str) -> Dict[str, Any]:\n    \"\"\"获取指定 workspace 的 HIL 任务（如果有）\"\"\"\n    for hil_id, task in HIL_TASKS.items():\n        if task[\"task_id\"] == task_id and task[\"status\"] == \"waiting\":\n            return {\n                \"found\": True,\n                \"hil_id\": hil_id,\n                \"instruction\": task[\"instruction\"],\n                \"task_id\": task[\"task_id\"]\n            }\n    \n    return {\n        \"found\": False\n    }\n\n\n# ========== 工具确认相关函数 ==========\n\ndef create_tool_confirmation(confirm_id: str, task_id: str, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:\n    \"\"\"创建工具确认请求\"\"\"\n    TOOL_CONFIRMATIONS[confirm_id] = {\n        \"status\": \"waiting\",\n        \"task_id\": task_id,\n        \"tool_name\": tool_name,\n        \"arguments\": arguments,\n        \"result\": None  # \"approved\" or \"rejected\"\n    }\n\n    try:\n        get_event_emitter().emit({\n            \"type\": \"tool_confirmation\",\n            \"confirm_id\": confirm_id,\n            \"tool_name\": tool_name,\n            \"arguments\": arguments,\n            \"task_id\": task_id,\n        })\n    except Exception:\n        pass\n    \n    return {\n        \"success\": True,\n        \"message\": f\"Tool confirmation created: {confirm_id}\"\n    }\n\n\ndef get_tool_confirmation_status(confirm_id: str) -> Dict[str, Any]:\n    \"\"\"获取工具确认状态\"\"\"\n    confirmation = TOOL_CONFIRMATIONS.get(confirm_id)\n    if not confirmation:\n        return {\n            \"found\": False,\n            \"error\": f\"Tool confirmation not found: {confirm_id}\"\n        }\n    \n    return {\n        \"found\": True,\n        \"confirm_id\": confirm_id,\n        \"status\": confirmation[\"status\"],\n        \"tool_name\": confirmation[\"tool_name\"],\n        \"arguments\": confirmation[\"arguments\"],\n        \"task_id\": confirmation[\"task_id\"],\n        \"result\": confirmation.get(\"result\")\n    }\n\n\ndef respond_tool_confirmation(confirm_id: str, approved: bool) -> Dict[str, Any]:\n    \"\"\"响应工具确认请求\"\"\"\n    confirmation = TOOL_CONFIRMATIONS.get(confirm_id)\n    if not confirmation:\n        return {\n            \"success\": False,\n            \"error\": f\"Tool confirmation not found: {confirm_id}\"\n        }\n    \n    # 标记为完成\n    TOOL_CONFIRMATIONS[confirm_id][\"status\"] = \"completed\"\n    TOOL_CONFIRMATIONS[confirm_id][\"result\"] = \"approved\" if approved else \"rejected\"\n    \n    return {\n        \"success\": True,\n        \"message\": f\"Tool confirmation {confirm_id}: {'approved' if approved else 'rejected'}\"\n    }\n\n\ndef get_tool_confirmation_for_workspace(task_id: str) -> Dict[str, Any]:\n    \"\"\"获取指定 workspace 的工具确认请求（如果有）\"\"\"\n    for confirm_id, confirmation in TOOL_CONFIRMATIONS.items():\n        if confirmation[\"task_id\"] == task_id and confirmation[\"status\"] == \"waiting\":\n            return {\n                \"found\": True,\n                \"confirm_id\": confirm_id,\n                \"tool_name\": confirmation[\"tool_name\"],\n                \"arguments\": confirmation[\"arguments\"],\n                \"task_id\": confirmation[\"task_id\"]\n            }\n    \n    return {\n        \"found\": False\n    }\n\n\ndef list_tool_confirmations() -> Dict[str, Any]:\n    \"\"\"列出所有工具确认请求\"\"\"\n    confirmations = []\n    for confirm_id, confirmation in TOOL_CONFIRMATIONS.items():\n        confirmations.append({\n            \"confirm_id\": confirm_id,\n            \"status\": confirmation[\"status\"],\n            \"tool_name\": confirmation[\"tool_name\"],\n            \"task_id\": confirmation[\"task_id\"]\n        })\n    \n    return {\n        \"total\": len(confirmations),\n        \"confirmations\": confirmations\n    }\n\n"
  },
  {
    "path": "tool_server_lite/tools/paper_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nPaper分析工具 - 论文内容分析\n舍弃了，标准化为 agent 即可\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\n\nfrom .file_tools import BaseTool, get_abs_path\n\n\nclass PaperAnalyzeTool(BaseTool):\n    \"\"\"论文分析工具 - 解析并分析论文内容\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行论文分析\n        \n        Parameters:\n            paper_path (str): 论文文件相对路径（相对于任务目录）\n            question (str, optional): 要问的问题，默认\"请总结这篇论文的主要内容\"\n            parse_save_path (str, optional): 解析结果保存路径，可选\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 分析结果文本\n            error: 错误信息（如有）\n        \"\"\"\n        try:\n            # 获取参数\n            paper_path = parameters.get(\"paper_path\")\n            question = parameters.get(\"question\", \"请总结这篇论文的主要内容\")\n            parse_save_path = parameters.get(\"parse_save_path\")\n            \n            if not paper_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: paper_path\"\n                }\n            \n            # 转换为绝对路径\n            abs_paper_path = get_abs_path(task_id, paper_path)\n            \n            if not abs_paper_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"论文文件不存在: {paper_path}\"\n                }\n            \n            # 步骤1: 解析文档\n            from .document_tools import ParseDocumentTool\n            parse_tool = ParseDocumentTool()\n            \n            parse_params = {\n                \"path\": paper_path  # 使用相对路径\n            }\n            \n            if parse_save_path:\n                parse_params[\"save_path\"] = parse_save_path\n            \n            parse_result = parse_tool.execute(task_id, parse_params)\n            \n            if parse_result[\"status\"] != \"success\":\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"文档解析失败: {parse_result.get('error', '未知错误')}\"\n                }\n            \n            # 步骤2: 读取解析结果\n            if parse_save_path:\n                # 如果保存了解析结果，读取保存的文件\n                read_path = parse_save_path\n            else:\n                # 否则读取返回的内容\n                paper_content = parse_result.get(\"output\", \"\")\n                if not paper_content:\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": \"文档解析结果为空\"\n                    }\n                \n                # 临时处理：如果输出是\"结果保存在 xxx\"，则需要读取该文件\n                if \"结果保存在\" in paper_content:\n                    # 提取文件路径\n                    import re\n                    match = re.search(r'结果保存在\\s+(\\S+)', paper_content)\n                    if match:\n                        read_path = match.group(1)\n                    else:\n                        read_path = paper_path.replace(\".pdf\", \".txt\")\n                else:\n                    # 直接返回内容\n                    read_path = None\n                    paper_content = paper_content\n            \n            # 步骤3: 如果有文件路径，读取文件\n            if read_path:\n                from .file_tools import FileReadTool\n                read_tool = FileReadTool()\n                read_result = read_tool.execute(task_id, {\"path\": read_path})\n                \n                if read_result[\"status\"] != \"success\":\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"读取解析结果失败: {read_result.get('error', '未知错误')}\"\n                    }\n                \n                paper_content = read_result.get(\"output\", \"\")\n            \n            # 步骤4: 使用 LLM 分析内容\n            import sys\n            import os\n            parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n            if parent_dir not in sys.path:\n                sys.path.insert(0, parent_dir)\n            \n            from tool_server_lite.llm_client_lite import get_llm_client\n            \n            try:\n                # 获取 LLM 客户端\n                llm_client = get_llm_client()\n                \n                # 调用文本分析\n                analysis_result = llm_client.text_query(\n                    text=paper_content,\n                    question=question\n                )\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": analysis_result,\n                    \"error\": \"\"\n                }\n                    \n            except Exception as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"LLM分析失败: {str(e)}\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行失败: {str(e)}\"\n            }\n\n"
  },
  {
    "path": "tool_server_lite/tools/powerpoint_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nPowerPoint 操作工具\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any, Optional\nfrom .file_tools import BaseTool, get_abs_path\n\ntry:\n    from pptx import Presentation\n    from pptx.util import Inches, Pt\n    from PIL import Image\n    PPTX_AVAILABLE = True\nexcept ImportError:\n    PPTX_AVAILABLE = False\n\n\nclass ImagesToPptTool(BaseTool):\n    \"\"\"将多张图片转换为 PPT - 每张图片一页，PPT 尺寸自动匹配第一张图片\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        将多张图片转换为 PowerPoint（简化版）\n        \n        Parameters:\n            image_paths (list[str]): 图片文件相对路径列表\n            output_path (str): 输出 PPT 文件相对路径\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: PPT 文件保存位置信息\n            error: 错误信息（如有）\n        \n        Note:\n            - PPT 尺寸会自动根据第一张图片的宽高比设置\n            - 每张图片占满整页（保持比例，居中显示）\n        \"\"\"\n        try:\n            if not PPTX_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"python-pptx 未安装。请运行: pip install python-pptx\"\n                }\n            \n            # 获取参数\n            image_paths = parameters.get(\"image_paths\")\n            output_path = parameters.get(\"output_path\")\n            \n            if not image_paths:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: image_paths\"\n                }\n            \n            if not output_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: output_path\"\n                }\n            \n            # 统一转换为列表\n            if isinstance(image_paths, str):\n                image_paths = [image_paths]\n            \n            # 转换为绝对路径\n            abs_image_paths = [get_abs_path(task_id, path) for path in image_paths]\n            abs_output_path = get_abs_path(task_id, output_path)\n            \n            # 检查图片是否存在\n            for img_path in abs_image_paths:\n                if not img_path.exists():\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"图片文件不存在: {img_path.name}\"\n                    }\n            \n            # 确保输出目录存在\n            abs_output_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 读取第一张图片，确定 PPT 尺寸\n            first_img = Image.open(abs_image_paths[0])\n            img_width, img_height = first_img.size\n            img_ratio = img_width / img_height\n            \n            # 根据图片比例设置 PPT 尺寸\n            # 标准宽度 10 英寸，高度根据比例计算\n            slide_width = 10.0\n            slide_height = slide_width / img_ratio\n            \n            print(f\"[INFO] PPT 尺寸: {slide_width:.2f}\\\" x {slide_height:.2f}\\\" (根据图片 {img_width}x{img_height} 计算)\")\n            \n            # 创建 PPT\n            prs = Presentation()\n            prs.slide_width = Inches(slide_width)\n            prs.slide_height = Inches(slide_height)\n            \n            # 添加图片页\n            for idx, img_path in enumerate(abs_image_paths, 1):\n                # 使用空白布局\n                slide = prs.slides.add_slide(prs.slide_layouts[6])\n                \n                # 获取当前图片尺寸\n                img = Image.open(img_path)\n                img_w, img_h = img.size\n                current_ratio = img_w / img_h\n                ppt_ratio = slide_width / slide_height\n                \n                # 计算图片位置和尺寸（保持比例，适应页面）\n                if abs(current_ratio - ppt_ratio) < 0.01:\n                    # 比例相同，填满整页\n                    left = Inches(0)\n                    top = Inches(0)\n                    width = Inches(slide_width)\n                    height = Inches(slide_height)\n                else:\n                    # 比例不同，保持比例居中\n                    if current_ratio > ppt_ratio:\n                        # 图片更宽，以宽度为准\n                        width = Inches(slide_width)\n                        height = Inches(slide_width / current_ratio)\n                        left = Inches(0)\n                        top = Inches((slide_height - height.inches) / 2)\n                    else:\n                        # 图片更高，以高度为准\n                        height = Inches(slide_height)\n                        width = Inches(slide_height * current_ratio)\n                        top = Inches(0)\n                        left = Inches((slide_width - width.inches) / 2)\n                \n                # 添加图片到幻灯片\n                slide.shapes.add_picture(\n                    str(img_path),\n                    left, top,\n                    width=width,\n                    height=height\n                )\n                \n                print(f\"[INFO] 添加图片 {idx}/{len(abs_image_paths)}: {img_path.name}\")\n            \n            # 保存 PPT\n            prs.save(str(abs_output_path))\n            \n            file_size = abs_output_path.stat().st_size / 1024  # KB\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"PPT 已生成: {output_path}\\n- 总页数: {len(prs.slides)}\\n- 图片数: {len(abs_image_paths)}\\n- 文件大小: {file_size:.1f} KB\",\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"生成 PPT 失败: {str(e)}\"\n            }\n"
  },
  {
    "path": "tool_server_lite/tools/reference_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n参考文献管理工具 - 用于管理 reference.bib 文件\n\"\"\"\n\nimport re\nfrom pathlib import Path\nfrom typing import Dict, Any, List\nfrom .file_tools import BaseTool, get_abs_path\n\n\nclass ReferenceListTool(BaseTool):\n    \"\"\"列出所有参考文献（直接显示原文）\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        列出 reference.bib 中的所有参考文献（原文）\n        \n        Parameters:\n            bib_path (str, optional): bib文件相对路径，默认 \"reference.bib\"\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 文件原文内容\n            error: 错误信息（如有）\n        \"\"\"\n        try:\n            bib_path = parameters.get(\"bib_path\", \"reference.bib\")\n            abs_bib_path = get_abs_path(task_id, bib_path)\n            \n            if not abs_bib_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"文件不存在: {bib_path}\"\n                }\n            \n            # 直接读取并返回文件内容\n            with open(abs_bib_path, 'r', encoding='utf-8') as f:\n                content = f.read()\n            \n            if not content.strip():\n                return {\n                    \"status\": \"success\",\n                    \"output\": \"(文件为空)\",\n                    \"error\": \"\"\n                }\n            \n            return {\n                \"status\": \"success\",\n                \"output\": content,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"读取失败: {str(e)}\"\n            }\n\n\nclass ReferenceAddTool(BaseTool):\n    \"\"\"添加参考文献（追加模式，不修改原有内容）\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        向 reference.bib 添加参考文献（使用追加模式，不会修改原有内容）\n        \n        Parameters:\n            entries (list): 参考文献字符串数组，每个元素是一条完整的bib条目\n            bib_path (str, optional): bib文件相对路径，默认 \"reference.bib\"\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 添加结果信息\n            error: 错误信息（如有）\n        \n        注意：本工具使用追加模式，不会解析和重写原有内容，确保原始数据安全\n        \"\"\"\n        try:\n            entries = parameters.get(\"entries\", [])\n            bib_path = parameters.get(\"bib_path\", \"reference.bib\")\n            \n            if not entries:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: entries\"\n                }\n            \n            if not isinstance(entries, list):\n                entries = [entries]\n            \n            abs_bib_path = get_abs_path(task_id, bib_path)\n            \n            # 如果文件不存在，创建它\n            if not abs_bib_path.exists():\n                abs_bib_path.parent.mkdir(parents=True, exist_ok=True)\n                needs_separator = False\n                needs_newline = False\n            else:\n                # 检查文件是否为空，以及是否以换行符结尾\n                file_size = abs_bib_path.stat().st_size\n                if file_size == 0:\n                    needs_separator = False\n                    needs_newline = False\n                else:\n                    with open(abs_bib_path, 'rb') as f:\n                        f.seek(-1, 2)  # 移到最后一个字符\n                        last_char = f.read(1)\n                        needs_separator = True\n                        # 如果不是换行符，需要先加换行\n                        needs_newline = (last_char != b'\\n')\n            \n            # 使用追加模式打开文件\n            with open(abs_bib_path, 'a', encoding='utf-8') as f:\n                # 如果需要，先添加分隔\n                if needs_separator:\n                    if needs_newline:\n                        f.write('\\n')\n                    f.write('\\n')\n                \n                # 追加所有新条目\n                added_count = 0\n                for entry in entries:\n                    entry = entry.strip()\n                    if not entry:\n                        continue\n                    \n                    f.write(entry)\n                    f.write('\\n\\n')\n                    added_count += 1\n            \n            if added_count == 0:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"没有有效的文献被添加\"\n                }\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"成功添加 {added_count} 条参考文献\",\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"添加失败: {str(e)}\"\n            }\n\n\nclass ReferenceDeleteTool(BaseTool):\n    \"\"\"删除参考文献\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        从 reference.bib 删除指定的参考文献\n        \n        Parameters:\n            keys (str or list): 要删除的引用键（如 \"sun2023blockchain\"）或引用键列表\n            bib_path (str, optional): bib文件相对路径，默认 \"reference.bib\"\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 删除结果信息\n            error: 错误信息（如有）\n        \"\"\"\n        try:\n            keys = parameters.get(\"keys\", [])\n            bib_path = parameters.get(\"bib_path\", \"reference.bib\")\n            \n            if not keys:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: keys\"\n                }\n            \n            # 统一转为列表\n            if isinstance(keys, str):\n                keys = [keys]\n            \n            abs_bib_path = get_abs_path(task_id, bib_path)\n            \n            if not abs_bib_path.exists():\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"文件不存在: {bib_path}\"\n                }\n            \n            # 读取文件\n            with open(abs_bib_path, 'r', encoding='utf-8') as f:\n                content = f.read()\n            \n            # 解析所有条目\n            entries = self._parse_bib_entries(content)\n            \n            # 过滤掉要删除的条目\n            deleted_keys = []\n            not_found_keys = []\n            remaining_entries = []\n            \n            for entry in entries:\n                if entry[\"key\"] in keys:\n                    deleted_keys.append(entry[\"key\"])\n                else:\n                    remaining_entries.append(entry[\"content\"])\n            \n            # 检查哪些key没找到\n            for key in keys:\n                if key not in deleted_keys:\n                    not_found_keys.append(key)\n            \n            if not deleted_keys:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"未找到要删除的文献: {', '.join(keys)}\"\n                }\n            \n            # 重新写入文件\n            new_content = '\\n\\n'.join(remaining_entries)\n            if new_content and not new_content.endswith('\\n'):\n                new_content += '\\n'\n            \n            with open(abs_bib_path, 'w', encoding='utf-8') as f:\n                f.write(new_content)\n            \n            # 生成结果信息\n            result_parts = [f\"成功删除 {len(deleted_keys)} 条参考文献: {', '.join(deleted_keys)}\"]\n            if not_found_keys:\n                result_parts.append(f\"未找到: {', '.join(not_found_keys)}\")\n            result_parts.append(f\"剩余 {len(remaining_entries)} 条参考文献\")\n            \n            return {\n                \"status\": \"success\",\n                \"output\": \"\\n\".join(result_parts),\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"删除失败: {str(e)}\"\n            }\n    \n    def _parse_bib_entries(self, content: str) -> List[Dict[str, str]]:\n        \"\"\"解析bib文件内容，提取所有条目（改进版，支持多种格式）\"\"\"\n        if not content.strip():\n            return []\n        \n        entries = []\n        # 改进的正则表达式：支持多行和单行格式\n        # 匹配 @type{key, 后面的任意内容直到 }\n        pattern = r'@(\\w+)\\s*\\{\\s*([^,\\s]+)\\s*,([^}]*)\\}'\n        \n        matches = re.finditer(pattern, content, re.DOTALL)\n        \n        for match in matches:\n            entry_type = match.group(1)\n            entry_key = match.group(2).strip()\n            entry_content = match.group(0)\n            \n            entries.append({\n                \"type\": entry_type,\n                \"key\": entry_key,\n                \"content\": entry_content\n            })\n        \n        return entries\n\n\nif __name__ == \"__main__\":\n    \"\"\"测试参考文献管理工具\"\"\"\n    import sys\n    from pathlib import Path\n    \n    # 添加项目根目录到路径\n    project_root = Path(__file__).parent.parent.parent\n    sys.path.insert(0, str(project_root))\n    \n    print(\"=\" * 60)\n    print(\"📚 测试参考文献管理工具\")\n    print(\"=\" * 60)\n    \n    # 创建测试用的bib文件\n    test_bib_content = \"\"\"@article{sun2023blockchain,\n  title={区块链技术, 供应链网络与数据共享: 基于演化博弈视角},\n  author={孙国强 and 谢雨菲},\n  journal={中国管理科学},\n  volume={31},\n  number={11},\n  pages={155--166},\n  year={2023}\n}\n\n@article{li2021evolutionary,\n  title={我国战略性新兴产业间供应链企业协同创新演化博弈研究},\n  author={李柏洲 and 王雪 and 苏屹 and 罗小芳},\n  journal={中国管理科学},\n  volume={29},\n  number={1},\n  pages={11--22},\n  year={2021}\n}\n\"\"\"\n    \n    # 写入测试文件\n    test_dir = project_root / \"test_reference\"\n    test_dir.mkdir(exist_ok=True)\n    test_bib_path = test_dir / \"reference.bib\"\n    \n    with open(test_bib_path, 'w', encoding='utf-8') as f:\n        f.write(test_bib_content)\n    \n    print(f\"测试文件已创建: {test_bib_path}\\n\")\n    \n    # 测试1: 列出参考文献\n    print(\"=\" * 60)\n    print(\"测试1: 列出所有参考文献（原文）\")\n    print(\"=\" * 60)\n    \n    list_tool = ReferenceListTool()\n    result = list_tool.execute(\"test_reference\", {\"bib_path\": \"reference.bib\"})\n    print(f\"状态: {result['status']}\")\n    print(f\"输出:\\n{result['output']}\\n\")\n    \n    # 测试2: 添加参考文献\n    print(\"=\" * 60)\n    print(\"测试2: 添加新参考文献\")\n    print(\"=\" * 60)\n    \n    new_entry = \"\"\"@article{yang2025stability,\n  title={多主体参与下食品安全社会共治演化博弈稳定性},\n  author={杨松 and others},\n  journal={食品安全质量检测学报},\n  volume={16},\n  number={4},\n  pages={325--334},\n  year={2025}\n}\"\"\"\n    \n    add_tool = ReferenceAddTool()\n    result = add_tool.execute(\"test_reference\", {\n        \"bib_path\": \"reference.bib\",\n        \"entries\": [new_entry]\n    })\n    print(f\"状态: {result['status']}\")\n    print(f\"输出: {result['output']}\\n\")\n    \n    # 测试3: 再次列出（查看添加结果）\n    print(\"=\" * 60)\n    print(\"测试3: 再次列出所有参考文献（应该有3条）\")\n    print(\"=\" * 60)\n    \n    result = list_tool.execute(\"test_reference\", {\"bib_path\": \"reference.bib\"})\n    print(f\"输出:\\n{result['output']}\\n\")\n    \n    # 测试4: 测试追加模式（再次添加一条文献）\n    print(\"=\" * 60)\n    print(\"测试4: 测试追加模式（添加第4条文献）\")\n    print(\"=\" * 60)\n    \n    another_entry = \"\"\"@article{wang2024test,\n  title={测试追加模式的文献},\n  author={王测试},\n  journal={测试期刊},\n  year={2024}\n}\"\"\"\n    \n    result = add_tool.execute(\"test_reference\", {\n        \"bib_path\": \"reference.bib\",\n        \"entries\": [another_entry]\n    })\n    print(f\"状态: {result['status']}\")\n    print(f\"输出: {result['output']}\\n\")\n    \n    # 测试4.5: 查看追加结果\n    print(\"=\" * 60)\n    print(\"测试4.5: 查看追加结果（应该有4条）\")\n    print(\"=\" * 60)\n    \n    result = list_tool.execute(\"test_reference\", {\"bib_path\": \"reference.bib\"})\n    print(f\"输出:\\n{result['output']}\\n\")\n    \n    # 测试5: 批量删除参考文献（测试数组形式）\n    print(\"=\" * 60)\n    print(\"测试5: 批量删除参考文献 ['sun2023blockchain', 'yang2025stability']\")\n    print(\"=\" * 60)\n    \n    delete_tool = ReferenceDeleteTool()\n    result = delete_tool.execute(\"test_reference\", {\n        \"bib_path\": \"reference.bib\",\n        \"keys\": [\"sun2023blockchain\", \"yang2025stability\"]\n    })\n    print(f\"状态: {result['status']}\")\n    print(f\"输出: {result['output']}\\n\")\n    \n    # 测试6: 最后列出（查看删除结果）\n    print(\"=\" * 60)\n    print(\"测试6: 最后列出所有参考文献（应该剩2条：li2021evolutionary, wang2024test）\")\n    print(\"=\" * 60)\n    \n    result = list_tool.execute(\"test_reference\", {\"bib_path\": \"reference.bib\"})\n    print(f\"输出:\\n{result['output']}\\n\")\n    \n    print(\"=\" * 60)\n    print(\"测试完成!\")\n    print(\"=\" * 60)\n\n"
  },
  {
    "path": "tool_server_lite/tools/skill_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nSkill 部署工具 - 将 skill 从全局仓库复制到 workspace\n\"\"\"\n\nimport shutil\nfrom pathlib import Path\nfrom typing import Dict, Any\n\nfrom .file_tools import BaseTool, get_abs_path\nfrom utils.user_paths import get_user_skills_library_root\n\n\nclass LoadSkillTool(BaseTool):\n    \"\"\"\n    Skill 部署工具 - 将指定 skill 从主 skills 目录（默认 ~/.agent/skills）复制到 workspace/.skills/\n    \n    部署后 Agent 可以通过 file_read 读取 .skills/{skill_name}/SKILL.md 获取详细指令，\n    并通过 execute_command 运行 .skills/{skill_name}/scripts/ 中的脚本。\n    \"\"\"\n    \n    def __init__(self):\n        super().__init__()\n        self.skills_library = get_user_skills_library_root()\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        将 skill 从全局仓库部署到 workspace\n        \n        Parameters:\n            skill_name (str): 要部署的 skill 名称（对应 skills_library 下的文件夹名）\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 部署结果信息\n        \"\"\"\n        try:\n            skill_name = parameters.get(\"skill_name\")\n            \n            if not skill_name:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: skill_name\"\n                }\n            \n            # 源路径\n            source_dir = self.skills_library / skill_name\n            source_skill_md = source_dir / \"SKILL.md\"\n            \n            if not source_dir.is_dir() or not source_skill_md.exists():\n                # 列出可用的 skills\n                available = []\n                if self.skills_library.exists():\n                    for d in sorted(self.skills_library.iterdir()):\n                        if d.is_dir() and (d / \"SKILL.md\").exists():\n                            available.append(d.name)\n                \n                available_str = \", \".join(available) if available else \"（无可用 skill）\"\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Skill '{skill_name}' 不存在。可用的 skills: {available_str}\"\n                }\n            \n            # 目标路径：workspace/.skills/{skill_name}/\n            target_dir = get_abs_path(task_id, f\".skills/{skill_name}\")\n            \n            # 如果已存在，先删除（更新部署）\n            if target_dir.exists():\n                shutil.rmtree(target_dir)\n            \n            # 复制整个 skill 文件夹\n            shutil.copytree(source_dir, target_dir)\n            \n            # 统计复制的文件\n            file_count = sum(1 for _ in target_dir.rglob(\"*\") if _.is_file())\n            \n            # 列出 skill 内容结构\n            structure_parts = []\n            for item in sorted(target_dir.rglob(\"*\")):\n                rel = item.relative_to(target_dir)\n                if item.is_dir():\n                    structure_parts.append(f\"  [dir] {rel}/\")\n                else:\n                    size_kb = item.stat().st_size / 1024\n                    structure_parts.append(f\"  [file] {rel} ({size_kb:.1f}KB)\")\n            \n            structure_str = \"\\n\".join(structure_parts) if structure_parts else \"  (空)\"\n            \n            output = (\n                f\"✅ Skill '{skill_name}' 已部署到 workspace\\n\"\n                f\"   位置: ./.skills/{skill_name}/\\n\"\n                f\"   文件数: {file_count}\\n\"\n                f\"   结构:\\n{structure_str}\\n\\n\"\n                f\"📖 下一步: 使用 file_read 读取 ./.skills/{skill_name}/SKILL.md 获取详细指令\"\n            )\n            \n            skill_md_text = source_skill_md.read_text(encoding='utf-8')\n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\",\n                \"_skill_name\": skill_name,\n                \"_skill_abs_path\": str(source_dir),\n                \"_workspace_skill_path\": str(target_dir),\n                \"_skill_md_text\": skill_md_text\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"部署 skill 失败: {str(e)}\"\n            }\n\n\nclass OffloadSkillTool(BaseTool):\n    \"\"\"\n    Skill 卸载工具 - 仅从当前运行上下文中卸载 skill.md 的注入内容。\n    不删除磁盘上的 skill 文件。\n    \"\"\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        skill_name = str(parameters.get(\"skill_name\") or \"\").strip()\n        if not skill_name:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"缺少必需参数: skill_name\"\n            }\n        return {\n            \"status\": \"success\",\n            \"output\": f\"已请求从当前上下文卸载 skill: {skill_name}\",\n            \"error\": \"\",\n            \"_offload_skill_name\": skill_name\n        }\n\n\nclass FreshTool(BaseTool):\n    \"\"\"\n    Fresh 工具 - 请求在安全点刷新运行时配置/工具注册/提示词缓存。\n    支持可选 task_id：\n    - 不传：fresh 当前 task\n    - 传入 task_id：fresh 对应 task；若不在运行则后台 resume\n    \"\"\"\n\n    name = \"fresh\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        reason = str(parameters.get(\"reason\") or \"\").strip()\n        target_task_id = str(parameters.get(\"task_id\") or \"\").strip()\n        effective_task_id = target_task_id or task_id\n        if effective_task_id == task_id:\n            output = \"已请求 fresh，系统将在安全点重载配置并续跑当前任务。\"\n        else:\n            output = f\"已请求 fresh task: {effective_task_id}。若该任务未在运行，将重载配置后后台 resume。\"\n        return {\n            \"status\": \"success\",\n            \"output\": output,\n            \"error\": \"\",\n            \"_fresh_requested\": True,\n            \"_fresh_reason\": reason,\n            \"_fresh_task_id\": effective_task_id\n        }\n"
  },
  {
    "path": "tool_server_lite/tools/task_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\n任务级工具：\n- 追加消息到指定 task\n- 后台启动新 task\n- 返回指定 task 的 share context 路径\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom pathlib import Path\nfrom typing import Any, Dict\n\nfrom .file_tools import BaseTool\nfrom utils.task_runtime import (\n    append_task_message,\n    get_task_share_paths,\n    launch_task_process,\n    list_known_tasks,\n)\nfrom utils.task_history_index import (\n    search_task_history_records,\n    sync_task_history_from_context,\n)\nfrom core.hierarchy_manager import get_hierarchy_manager\n\n\nclass AddMessageTool(BaseTool):\n    \"\"\"向指定 task 的 current.instructions 追加一条消息。\"\"\"\n\n    name = \"add_message\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        target_task_id = str(parameters.get(\"task_id\") or task_id or \"\").strip()\n        message = str(parameters.get(\"message\") or \"\").strip()\n        source = str(parameters.get(\"source\") or \"agent\").strip() or \"agent\"\n        resume_if_needed = bool(parameters.get(\"resume_if_needed\", False))\n        fallback_agent_system = str(parameters.get(\"agent_system\") or \"\").strip() or None\n        if fallback_agent_system is None:\n            try:\n                fallback_agent_system = (\n                    get_hierarchy_manager(task_id).get_runtime_metadata().get(\"agent_system\") or None\n                )\n            except Exception:\n                fallback_agent_system = None\n\n        ok, payload = append_task_message(\n            task_id=target_task_id,\n            message=message,\n            source=source,\n            resume_if_needed=resume_if_needed,\n            fallback_agent_system=fallback_agent_system,\n        )\n        if not ok:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": payload.get(\"error\") or \"追加消息失败\",\n            }\n\n        return {\n            \"status\": \"success\",\n            \"output\": (\n                f\"{payload.get('message', '')}\\n\"\n                f\"share_context: {payload.get('share_context_path', '')}\"\n            ).strip(),\n            \"error\": \"\",\n            \"task_id\": payload.get(\"task_id\", target_task_id),\n            \"instruction_id\": payload.get(\"instruction_id\", \"\"),\n            \"share_context_path\": payload.get(\"share_context_path\", \"\"),\n            \"stack_path\": payload.get(\"stack_path\", \"\"),\n            \"running\": payload.get(\"running\", False),\n            \"resumed\": payload.get(\"resumed\", False),\n            \"launched\": payload.get(\"launched\", False),\n        }\n\n\nclass StartBackgroundTaskTool(BaseTool):\n    \"\"\"后台启动一个新的 task 进程。\"\"\"\n\n    name = \"start_background_task\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        target_task_id = str(parameters.get(\"task_id\") or \"\").strip()\n        if not target_task_id:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"缺少必需参数: task_id\"\n            }\n\n        user_input = str(parameters.get(\"user_input\") or parameters.get(\"message\") or \"\").strip()\n        agent_system = str(parameters.get(\"agent_system\") or \"OpenCowork\").strip() or \"OpenCowork\"\n        agent_name = str(parameters.get(\"agent_name\") or \"alpha_agent\").strip() or \"alpha_agent\"\n        config = parameters.get(\"config\")\n        if config is not None and not isinstance(config, dict):\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"参数 config 必须是 object\"\n            }\n\n        ok, payload = launch_task_process(\n            task_id=str(Path(target_task_id).expanduser().resolve()),\n            user_input=user_input,\n            agent_system=agent_system,\n            agent_name=agent_name,\n            config=config,\n            force_new=bool(parameters.get(\"force_new\", False)),\n            direct_tools=bool(parameters.get(\"direct_tools\", True)),\n        )\n        if not ok:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": payload.get(\"error\") or \"后台启动任务失败\",\n            }\n\n        return {\n            \"status\": \"success\",\n            \"output\": (\n                f\"{payload.get('message', '')}\\n\"\n                f\"log_path: {payload.get('log_path', '')}\"\n            ).strip(),\n            \"error\": \"\",\n            \"task_id\": payload.get(\"task_id\", \"\"),\n            \"pid\": payload.get(\"pid\"),\n            \"log_path\": payload.get(\"log_path\", \"\"),\n            \"agent_system\": payload.get(\"agent_system\", agent_system),\n            \"agent_name\": payload.get(\"agent_name\", agent_name),\n        }\n\n\nclass TaskShareContextPathTool(BaseTool):\n    \"\"\"返回指定 task 的 share context / stack 路径。\"\"\"\n\n    name = \"task_share_context_path\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        target_task_id = str(parameters.get(\"task_id\") or task_id or \"\").strip()\n        if not target_task_id:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": \"缺少 task_id\"\n            }\n\n        paths = get_task_share_paths(target_task_id)\n        return {\n            \"status\": \"success\",\n            \"output\": (\n                \"已定位对应 task 的共享上下文文件，请自行读取查看。\\n\"\n                f\"share_context_path: {paths['share_context_path']}\\n\"\n                f\"stack_path: {paths['stack_path']}\"\n            ),\n            \"error\": \"\",\n            **paths,\n        }\n\n\nclass ListTaskIdsTool(BaseTool):\n    \"\"\"列出当前已知 task_id。\"\"\"\n\n    name = \"list_task_ids\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        only_running = bool(parameters.get(\"only_running\", False))\n        payload = list_known_tasks(only_running=only_running)\n        tasks = payload[\"tasks\"]\n        if not tasks:\n            scope = \"运行中的\" if only_running else \"已知的\"\n            return {\n                \"status\": \"success\",\n                \"output\": f\"当前没有{scope} task。\",\n                \"error\": \"\",\n                \"tasks\": [],\n            }\n\n        lines = []\n        for idx, item in enumerate(tasks, 1):\n            lines.append(\n                f\"{idx}. {item['task_id']} | running={item['running']} | share_context={item['share_context_path']}\"\n            )\n        return {\n            \"status\": \"success\",\n            \"output\": \"\\n\".join(lines),\n            \"error\": \"\",\n            \"tasks\": tasks,\n        }\n\n\nclass TaskHistorySearchTool(BaseTool):\n    \"\"\"检索历史任务数据库。\"\"\"\n\n    name = \"task_history_search\"\n\n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        keyword = str(parameters.get(\"keyword\") or \"\").strip()\n        relevance_query_text = str(parameters.get(\"relevance_query_text\") or \"\").strip()\n        start_time_from = str(parameters.get(\"start_time_from\") or \"\").strip()\n        start_time_to = str(parameters.get(\"start_time_to\") or \"\").strip()\n        start_round = int(parameters.get(\"start_round\") or 0)\n        enable_vector_search = bool(parameters.get(\"enable_vector_search\", False))\n\n        try:\n            if task_id:\n                try:\n                    sync_task_history_from_context(task_id)\n                except Exception:\n                    pass\n            payload = search_task_history_records(\n                task_id=task_id,\n                keyword=keyword,\n                relevance_query_text=relevance_query_text,\n                start_time_from=start_time_from,\n                start_time_to=start_time_to,\n                start_round=start_round,\n                enable_vector_search=enable_vector_search,\n            )\n            results = payload.get(\"results\", [])\n            semantic_error = payload.get(\"semantic_error\") or \"\"\n            if enable_vector_search and relevance_query_text and semantic_error:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": semantic_error,\n                    \"results\": results,\n                }\n\n            if not results:\n                return {\n                    \"status\": \"success\",\n                    \"output\": \"没有检索到匹配的历史任务信息。\",\n                    \"error\": \"\",\n                    \"results\": [],\n                }\n\n            lines = []\n            for idx, item in enumerate(results, 1):\n                lines.append(\n                    f\"{idx}. 第{item.get('round')}条历史任务 | start={item.get('start_time','')} | completion={item.get('completion_time','')}\"\n                )\n                for instruction in item.get(\"instructions\", [])[:3]:\n                    lines.append(f\"   instruction: {instruction[:300]}\")\n                if item.get(\"final_output\"):\n                    lines.append(f\"   final_output: {str(item['final_output'])[:800]}\")\n                if item.get(\"latest_thinking\"):\n                    lines.append(f\"   latest_thinking: {str(item['latest_thinking'])[:500]}\")\n                score = item.get(\"score\")\n                if score is not None:\n                    lines.append(f\"   score: {score:.4f}\")\n\n            return {\n                \"status\": \"success\",\n                \"output\": \"\\n\".join(lines),\n                \"error\": \"\",\n                \"results\": results,\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e),\n                \"results\": [],\n            }\n"
  },
  {
    "path": "tool_server_lite/tools/vision_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nVision分析工具 - 图片内容分析 & 图片读取（多模态支持）\n\"\"\"\n\nimport base64\nimport os\nfrom pathlib import Path\nfrom typing import Dict, Any\n\nfrom .file_tools import BaseTool, get_abs_path\nfrom utils.user_paths import ensure_user_llm_config_exists\n\n# NOTE:\n# 以前这里用 `sys.path` hack + `from llm_client_lite import ...`，\n# 在 direct-tools / PyInstaller 环境下会因为模块名不在顶层而失败。\n# 统一使用包内绝对导入，保证 dev/packaged 都一致可用。\nfrom tool_server_lite.llm_client_lite import get_llm_client\n\n\nclass ImageReadTool(BaseTool):\n    \"\"\"\n    图片读取工具 - 支持双模式：\n    1. multimodal 模式：读取图片转 base64，嵌入到主模型 messages 中（主模型直接看图）\n    2. text-only 模式：调用 Vision LLM 分析图片，返回文字描述\n    \n    mode 由运行时从 llm_config.yaml 的 multimodal 字段读取决定\n    \"\"\"\n    \n    def __init__(self):\n        \"\"\"初始化\"\"\"\n        super().__init__()\n    \n    @property\n    def multimodal(self) -> bool:\n        \"\"\"从 llm_config.yaml 读取 multimodal 配置（每次读取，不缓存，确保配置修改后即时生效）\"\"\"\n        try:\n            import yaml\n            config_path = ensure_user_llm_config_exists()\n            if config_path.exists():\n                with open(config_path, 'r', encoding='utf-8') as f:\n                    config = yaml.safe_load(f)\n                return config.get(\"multimodal\", False)\n        except Exception:\n            pass\n        return False\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行图片读取（支持多张图片）\n        \n        Parameters:\n            image_paths (list[str]): 图片文件相对路径数组（相对于任务目录），读单图传单元素数组\n            query (str, optional): 要问的问题（text-only 模式下传给 Vision LLM，\n                                   multimodal 模式下作为元信息由 agent_executor 嵌入 user 消息）\n            save_path (str, optional): 保存分析结果的相对路径（仅 text-only 模式有效）\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 分析结果文本\n            _image_base64_list: base64 编码的图片 data URI 列表（仅 multimodal 模式）\n            _multimodal: 是否为多模态模式（仅 multimodal 模式）\n        \"\"\"\n        try:\n            image_paths = parameters.get(\"image_paths\")\n            query = parameters.get(\"query\", \"请描述这些图片的内容\")\n            save_path = parameters.get(\"save_path\")\n            \n            if not image_paths:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: image_paths（字符串数组）\"\n                }\n            \n            if isinstance(image_paths, str):\n                image_paths = [image_paths]\n            \n            # 验证所有路径\n            abs_paths = []\n            for p in image_paths:\n                abs_p = get_abs_path(task_id, p)\n                if not abs_p.exists():\n                    return {\n                        \"status\": \"error\",\n                        \"output\": \"\",\n                        \"error\": f\"图片文件不存在: {p}\"\n                    }\n                abs_paths.append((abs_p, p))\n            \n            # 根据多模态配置选择模式\n            if self.multimodal:\n                return self._execute_multimodal_batch(abs_paths, query)\n            else:\n                # text-only 模式：逐张分析（每张都调用 Vision LLM）\n                all_results = []\n                for abs_p, rel_p in abs_paths:\n                    result = self._execute_text_only(abs_p, rel_p, query, task_id, save_path)\n                    if result[\"status\"] == \"error\":\n                        return result\n                    all_results.append(f\"[{rel_p}]\\n{result['output']}\")\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": \"\\n\\n\".join(all_results),\n                    \"error\": \"\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行失败: {str(e)}\"\n            }\n    \n    # 图片分辨率限制（长边最大像素数）\n    MAX_IMAGE_DIMENSION = 1568  # OpenAI/Anthropic 推荐的最大尺寸\n    MAX_IMAGE_BYTES = 4 * 1024 * 1024  # base64 前的原始字节上限 4MB\n    JPEG_QUALITY = 85  # JPEG 压缩质量\n    \n    def _compress_single_image(self, abs_image_path: Path) -> tuple:\n        \"\"\"\n        压缩单张图片，返回 (data_uri, info_str)\n        \"\"\"\n        try:\n            from PIL import Image\n            import io\n            \n            img = Image.open(abs_image_path)\n            original_size = img.size\n            \n            # 转换色彩模式\n            if img.mode in ('RGBA', 'P', 'LA'):\n                background = Image.new('RGB', img.size, (255, 255, 255))\n                if img.mode == 'P':\n                    img = img.convert('RGBA')\n                background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)\n                img = background\n            elif img.mode != 'RGB':\n                img = img.convert('RGB')\n            \n            # 缩放\n            width, height = img.size\n            max_dim = self.MAX_IMAGE_DIMENSION\n            resized = False\n            if width > max_dim or height > max_dim:\n                if width > height:\n                    new_width = max_dim\n                    new_height = int(height * max_dim / width)\n                else:\n                    new_height = max_dim\n                    new_width = int(width * max_dim / height)\n                img = img.resize((new_width, new_height), Image.LANCZOS)\n                resized = True\n            \n            # 编码为 JPEG\n            buffer = io.BytesIO()\n            img.save(buffer, format='JPEG', quality=self.JPEG_QUALITY, optimize=True)\n            image_data = buffer.getvalue()\n            \n            # 二次压缩\n            if len(image_data) > self.MAX_IMAGE_BYTES:\n                for quality in [70, 55, 40]:\n                    buffer = io.BytesIO()\n                    img.save(buffer, format='JPEG', quality=quality, optimize=True)\n                    image_data = buffer.getvalue()\n                    if len(image_data) <= self.MAX_IMAGE_BYTES:\n                        break\n            \n            image_base64 = base64.b64encode(image_data).decode('utf-8')\n            data_uri = f\"data:image/jpeg;base64,{image_base64}\"\n            \n            final_size = img.size\n            size_kb = len(image_data) / 1024\n            resize_info = f\", resized from {original_size} to {final_size}\" if resized else \"\"\n            info = f\"{final_size[0]}x{final_size[1]}, {size_kb:.0f}KB{resize_info}\"\n            \n            return data_uri, info\n            \n        except ImportError:\n            # PIL 不可用，直接读取\n            with open(abs_image_path, 'rb') as f:\n                image_data = f.read()\n            image_base64 = base64.b64encode(image_data).decode('utf-8')\n            suffix = abs_image_path.suffix.lower()\n            mime_types = {\n                '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',\n                '.png': 'image/png', '.gif': 'image/gif',\n                '.webp': 'image/webp', '.bmp': 'image/bmp'\n            }\n            mime_type = mime_types.get(suffix, 'image/jpeg')\n            data_uri = f\"data:{mime_type};base64,{image_base64}\"\n            size_kb = len(image_data) / 1024\n            return data_uri, f\"{size_kb:.0f}KB, no compression\"\n    \n    def _execute_multimodal_batch(self, abs_paths: list, query: str) -> Dict[str, Any]:\n        \"\"\"\n        多模态模式（批量）：读取多张图片，压缩，转 base64 列表\n        \n        Args:\n            abs_paths: [(abs_path, rel_path), ...] 绝对路径和相对路径的元组列表\n            query: 用户查询\n        \"\"\"\n        try:\n            data_uri_list = []\n            output_parts = []\n            \n            for abs_p, rel_p in abs_paths:\n                data_uri, info = self._compress_single_image(abs_p)\n                data_uri_list.append(data_uri)\n                output_parts.append(f\"{rel_p} ({info})\")\n            \n            output_msg = f\"Loaded {len(data_uri_list)} image(s) in multimodal mode: {'; '.join(output_parts)}. Images are embedded in the conversation.\"\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output_msg,\n                \"_image_base64_list\": data_uri_list,\n                \"_multimodal\": True,\n                \"error\": \"\"\n            }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"读取图片失败: {str(e)}\"\n            }\n    \n    def _execute_text_only(self, abs_image_path: Path, image_path: str, query: str, \n                           task_id: str, save_path: str = None) -> Dict[str, Any]:\n        \"\"\"\n        Text-only 模式：调用 Vision LLM 分析图片，返回文字描述\n        \"\"\"\n        try:\n            llm_client = get_llm_client()\n            \n            result = llm_client.vision_query(\n                image_path=str(abs_image_path),\n                question=query\n            )\n            \n            # 保存分析结果\n            if save_path:\n                abs_save_path = get_abs_path(task_id, save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(result)\n                output = f\"结果保存在 {save_path}\"\n            else:\n                output = result\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n        \n        except FileNotFoundError as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"图片文件不存在: {str(e)}\"\n            }\n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"Vision分析失败: {str(e)}\"\n            }\n\n\nclass VisionTool(BaseTool):\n    \"\"\"图片Vision分析工具 - 调用LLM分析图片内容\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行Vision分析\n        \n        Parameters:\n            image_path (str): 图片文件相对路径（相对于任务目录）\n            question (str, optional): 要问的问题，默认\"请描述这张图片的内容\"\n            model (str, optional): 模型名称，默认使用配置中的模型\n            save_path (str, optional): 保存分析结果的相对路径\n        \n        Returns:\n            status: \"success\" 或 \"error\"\n            output: 分析结果文本或保存位置信息\n            error: 错误信息（如有）\n        \"\"\"\n        try:\n            # 获取参数\n            image_path = parameters.get(\"image_path\")\n            question = parameters.get(\"question\", \"请描述这张图片的内容\")\n            model = parameters.get(\"model\")\n            save_path = parameters.get(\"save_path\")\n            \n            if not image_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: image_path\"\n                }\n            \n            # 转换为绝对路径\n            abs_image_path = get_abs_path(task_id, image_path)\n            \n            # 调用LLM客户端\n            llm_client = get_llm_client()\n            \n            try:\n                result = llm_client.vision_query(\n                    image_path=str(abs_image_path),\n                    question=question,\n                    model=model\n                )\n                \n                # 保存分析结果\n                if save_path:\n                    abs_save_path = get_abs_path(task_id, save_path)\n                    abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                    with open(abs_save_path, 'w', encoding='utf-8') as f:\n                        f.write(result)\n                    output = f\"结果保存在 {save_path}\"\n                else:\n                    output = result\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": output,\n                    \"error\": \"\"\n                }\n                \n            except FileNotFoundError as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"图片文件不存在: {str(e)}\"\n                }\n            except Exception as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"Vision分析失败: {str(e)}\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行失败: {str(e)}\"\n            }\n\n\nclass CreateImageTool(BaseTool):\n    \"\"\"图片生成工具 - 根据提示词生成图片（支持参考图）\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        执行图片生成\n        \n        Parameters:\n            prompt (str): 图片提示词\n            image_path (str): 生成图片保存的相对路径（相对于任务目录）\n            reference_images (list[str], optional): 参考图片相对路径列表（用于图片编辑/风格迁移）\n            model (str, optional): 模型名称\n            size (str, optional): 图片尺寸，默认 \"1024x1024\"\n            n (int, optional): 生成图片数量，默认 1\n        \"\"\"\n        try:\n            # 获取参数\n            prompt = parameters.get(\"prompt\")\n            image_path = parameters.get(\"image_path\")\n            reference_images = parameters.get(\"reference_images\")\n            model = parameters.get(\"model\")\n            size = parameters.get(\"size\", \"1024x1024\")\n            n = parameters.get(\"n\", 1)\n            \n            if not prompt or not image_path:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"缺少必需参数: prompt 或 image_path\"\n                }\n            \n            # 转换为绝对路径\n            abs_save_path = get_abs_path(task_id, image_path)\n            \n            # 处理参考图片路径\n            abs_reference_images = None\n            if reference_images:\n                if isinstance(reference_images, str):\n                    reference_images = [reference_images]\n                abs_reference_images = [str(get_abs_path(task_id, ref_path)) for ref_path in reference_images]\n            \n            # 确保父目录存在\n            abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 调用LLM客户端\n            llm_client = get_llm_client()\n            \n            try:\n                # 生成图片\n                result_data = llm_client.create_image(\n                    prompt=prompt,\n                    model=model,\n                    reference_images=abs_reference_images,\n                    size=size,\n                    n=n\n                )\n                \n                import requests\n                import base64\n                \n                # 处理返回结果（URL 或 Base64）\n                results_to_save = [result_data] if isinstance(result_data, str) else result_data\n                \n                for idx, result in enumerate(results_to_save):\n                    # 确定保存路径\n                    if idx == 0:\n                        save_path = abs_save_path\n                    else:\n                        # 多个结果时，添加序号\n                        stem = abs_save_path.stem\n                        suffix = abs_save_path.suffix\n                        save_path = abs_save_path.parent / f\"{stem}_{idx}{suffix}\"\n                    \n                    if result.startswith('http'):\n                        # 下载图片\n                        response = requests.get(result, timeout=30)\n                        if response.status_code == 200:\n                            with open(save_path, 'wb') as f:\n                                f.write(response.content)\n                        else:\n                            return {\n                                \"status\": \"error\",\n                                \"output\": \"\",\n                                \"error\": f\"下载生成的图片失败: HTTP {response.status_code}\"\n                            }\n                    else:\n                        # Base64 数据\n                        # 有可能带 data:image/png;base64, 前缀，需要处理\n                        if \",\" in result:\n                            result = result.split(\",\")[1]\n                        \n                        image_content = base64.b64decode(result)\n                        with open(save_path, 'wb') as f:\n                            f.write(image_content)\n                \n                # 构建输出消息\n                if len(results_to_save) == 1:\n                    output_msg = f\"图片已生成并保存至: {image_path}\"\n                else:\n                    output_msg = f\"已生成 {len(results_to_save)} 张图片，保存至: {image_path} 及其变体\"\n                \n                return {\n                    \"status\": \"success\",\n                    \"output\": output_msg,\n                    \"error\": \"\"\n                }\n                \n            except Exception as e:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": f\"生成图片失败: {str(e)}\"\n                }\n        \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": f\"执行失败: {str(e)}\"\n            }\n"
  },
  {
    "path": "tool_server_lite/tools/web_tools.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n网络工具 - 使用 crawl4ai\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Dict, Any\nimport asyncio\nimport re\nimport requests\nfrom urllib.parse import urlencode\nfrom .file_tools import BaseTool, get_abs_path\n\n# Crawl4AI 导入\nCRAWL4AI_IMPORT_ERROR = \"\"\ntry:\n    from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode\n    CRAWL4AI_AVAILABLE = True\nexcept (ImportError, TypeError, Exception) as exc:\n    CRAWL4AI_AVAILABLE = False\n    CRAWL4AI_IMPORT_ERROR = f\"{type(exc).__name__}: {exc}\"\n\n# DuckDuckGo 导入\ntry:\n    from ddgs import DDGS\n    DDGS_AVAILABLE = True\nexcept ImportError:\n    try:\n        from duckduckgo_search import DDGS\n        DDGS_AVAILABLE = True\n    except ImportError:\n        DDGS_AVAILABLE = False\n\n\ndef _get_field(obj: Any, name: str, default: Any = None) -> Any:\n    \"\"\"\n    crawl4ai 的返回对象在不同版本/运行环境下可能是:\n    - 一个带属性的对象 (result.markdown / result.cleaned_html ...)\n    - 或者被序列化/包装成 dict\n    这里统一做兼容读取，避免 `getattr(...)=None` 造成误判。\n    \"\"\"\n    try:\n        if isinstance(obj, dict):\n            return obj.get(name, default)\n        return getattr(obj, name, default)\n    except Exception:\n        return default\n\n\nclass CrawlPageTool(BaseTool):\n    \"\"\"网页爬取工具 - 使用 crawl4ai\"\"\"\n\n    @staticmethod\n    def _crawl4ai_unavailable_error() -> str:\n        detail = CRAWL4AI_IMPORT_ERROR.strip()\n        if not detail:\n            return \"crawl4ai not available\"\n        lower = detail.lower()\n        if \"no module named\" in lower or \"crawl4ai\" in lower:\n            return f\"crawl4ai import failed: {detail}. Install with: pip install crawl4ai\"\n        return f\"crawl4ai import failed: {detail}\"\n\n    @staticmethod\n    def _normalize_runtime_error_message(error: Exception) -> str:\n        message = str(error or \"\").strip()\n        lower = message.lower()\n        if \"browsertype.launch\" in lower and \"executable doesn't exist\" in lower:\n            return (\n                message\n                + \"\\nPlaywright Chromium executable is missing in the current runtime. \"\n                + \"For local Python envs run: python -m playwright install chromium. \"\n                + \"For packaged desktop builds, ensure PLAYWRIGHT_BROWSERS_PATH points to the bundled .local-browsers directory.\"\n            )\n        return message\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        爬取网页内容\n        \n        Parameters:\n            url (str): 网页URL\n            save_path (str, optional): 保存结果的相对路径（.md文件）\n            download_images (bool, optional): 是否下载图片，默认False\n        \"\"\"\n        try:\n            if not CRAWL4AI_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": self._crawl4ai_unavailable_error()\n                }\n            \n            url = parameters.get(\"url\")\n            save_path = parameters.get(\"save_path\")\n            download_images = parameters.get(\"download_images\", False)\n            \n            if not url:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"url is required\"\n                }\n            \n            # 爬取页面\n            markdown_text = await self._crawl_page(url)\n            \n            # 处理图片\n            if not download_images:\n                # 移除图片标记\n                markdown_text = re.sub(r\"!\\[[^\\]]*\\]\\([^\\)]+\\)\", \"\", markdown_text)\n            \n            # 保存到文件\n            if save_path:\n                abs_save_path = get_abs_path(task_id, save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                \n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(markdown_text)\n                \n                output = f\"结果保存在 {save_path}\"\n            else:\n                output = markdown_text\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": self._normalize_runtime_error_message(e)\n            }\n    \n    async def _crawl_page(self, url: str) -> str:\n        \"\"\"使用 crawl4ai 爬取页面\"\"\"\n        browser_conf = BrowserConfig(headless=True, verbose=False)\n        run_conf = CrawlerRunConfig(cache_mode=CacheMode.BYPASS)\n        \n        async with AsyncWebCrawler(config=browser_conf) as crawler:\n            result = await crawler.arun(url, config=run_conf)\n            \n            # 先看 crawl4ai 是否明确失败\n            success = _get_field(result, \"success\", None)\n            if success is False:\n                err = _get_field(result, \"error_message\", \"\") or _get_field(result, \"error\", \"\") or \"\"\n                raise Exception(f\"crawl4ai failed: {err[:300]}\")\n\n            markdown_attr = _get_field(result, \"markdown\", None)\n            if markdown_attr is None:\n                # 输出可诊断信息，便于定位不同版本的字段差异\n                if isinstance(result, dict):\n                    keys = list(result.keys())[:60]\n                    raise Exception(f\"Unable to extract markdown from crawl result (missing field: markdown; dict keys sample={keys})\")\n                attrs = [a for a in dir(result) if not a.startswith(\"_\")][:60]\n                raise Exception(f\"Unable to extract markdown from crawl result (missing field: markdown; attrs sample={attrs})\")\n\n            try:\n                markdown_text = (\n                    _get_field(markdown_attr, \"raw_markdown\", None)\n                    or _get_field(markdown_attr, \"markdown\", None)\n                    or str(markdown_attr)\n                )\n            except Exception:\n                markdown_text = str(markdown_attr)\n\n            if not (isinstance(markdown_text, str) and markdown_text.strip()):\n                # 不做兜底：确保“原生使用 crawl4ai 的 markdown”才算成功\n                mtype = type(markdown_attr).__name__\n                raw_len = 0\n                md_len = 0\n                try:\n                    raw_len = len((_get_field(markdown_attr, \"raw_markdown\", \"\") or \"\"))\n                except Exception:\n                    raw_len = 0\n                try:\n                    md_len = len((_get_field(markdown_attr, \"markdown\", \"\") or \"\"))\n                except Exception:\n                    md_len = 0\n                raise Exception(f\"Unable to extract markdown from crawl result (markdown empty; type={mtype}; raw_markdown_len={raw_len}; markdown_len={md_len})\")\n\n            return markdown_text\n\n\nclass GoogleScholarSearchTool(BaseTool):\n    \"\"\"谷歌学术搜索工具 - 使用 crawl4ai\"\"\"\n    \n    async def execute_async(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        谷歌学术搜索\n        \n        Parameters:\n            query (str): 搜索关键词\n            year_low (int, optional): 年份下限\n            year_high (int, optional): 年份上限\n            pages (int, optional): 爬取页数，默认1\n            save_path (str, optional): 保存结果的相对路径（.md文件）\n        \"\"\"\n        try:\n            if not CRAWL4AI_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": CrawlPageTool._crawl4ai_unavailable_error()\n                }\n            \n            query = parameters.get(\"query\")\n            year_low = parameters.get(\"year_low\")\n            year_high = parameters.get(\"year_high\")\n            pages = parameters.get(\"pages\", 1)\n            save_path = parameters.get(\"save_path\")\n            \n            if not query:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"query is required\"\n                }\n            \n            # 爬取学术搜索结果（Google Scholar 在很多网络环境下会被封/重定向/403）\n            # 如果失败，则回退到 DuckDuckGo 的 site:scholar.google.com 搜索（无需代理也更稳）\n            try:\n                all_content = await self._crawl_scholar(query, year_low, year_high, pages)\n            except Exception as crawl_err:\n                if DDGS_AVAILABLE:\n                    ddg_query = f\"site:scholar.google.com {query}\"\n                    results = DDGS().text(ddg_query, max_results=min(10, pages * 10))\n                    lines = [\n                        \"# Google Scholar (fallback via DuckDuckGo)\",\n                        \"\",\n                        f\"- query: `{query}`\",\n                        f\"- note: direct crawling failed: `{str(crawl_err)[:200]}`\",\n                        \"\",\n                    ]\n                    for i, r in enumerate(results or [], 1):\n                        title = (r.get(\"title\") or \"\").strip()\n                        href = (r.get(\"href\") or r.get(\"link\") or \"\").strip()\n                        body = (r.get(\"body\") or \"\").strip()\n                        if href:\n                            lines.append(f\"{i}. **{title or 'Untitled'}**\")\n                            lines.append(f\"   - {href}\")\n                            if body:\n                                lines.append(f\"   - {body}\")\n                    all_content = \"\\n\".join(lines) + \"\\n\"\n                else:\n                    raise\n            \n            # 保存到文件\n            if save_path:\n                # 生成包含搜索参数的文件名\n                from pathlib import Path\n                save_path_obj = Path(save_path)\n                safe_query = re.sub(r'[^\\w\\s-]', '', query).strip()\n                safe_query = re.sub(r'[-\\s]+', '_', safe_query)[:50]\n                \n                year_suffix = \"\"\n                if year_low or year_high:\n                    year_suffix = f\"_y{year_low or 'X'}-{year_high or 'X'}\"\n                \n                new_filename = f\"{save_path_obj.stem}_{safe_query}{year_suffix}_p{pages}{save_path_obj.suffix}\"\n                final_save_path = str(save_path_obj.parent / new_filename)\n                \n                abs_save_path = get_abs_path(task_id, final_save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                \n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(all_content)\n                \n                output = f\"结果保存在 {final_save_path}\"\n            else:\n                output = all_content\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n    \n    async def _crawl_scholar(self, query: str, year_low: int, year_high: int, pages: int) -> str:\n        \"\"\"爬取谷歌学术搜索结果\"\"\"\n        base_url = \"https://scholar.google.com/scholar\"\n        all_content = []\n        \n        browser_conf = BrowserConfig(headless=True, verbose=False)\n        run_conf = CrawlerRunConfig(cache_mode=CacheMode.BYPASS)\n        \n        async with AsyncWebCrawler(config=browser_conf) as crawler:\n            for page in range(pages):\n                start = page * 10\n                \n                params = {\n                    \"start\": str(start),\n                    \"q\": query,\n                    \"as_sdt\": \"0,5\"\n                }\n                \n                if year_low:\n                    params[\"as_ylo\"] = str(year_low)\n                if year_high:\n                    params[\"as_yhi\"] = str(year_high)\n                \n                url = f\"{base_url}?{urlencode(params)}\"\n                \n                result = await crawler.arun(url, config=run_conf)\n                \n                markdown_attr = _get_field(result, \"markdown\", None)\n                if markdown_attr:\n                    markdown_text = (\n                        _get_field(markdown_attr, \"raw_markdown\", None)\n                        or _get_field(markdown_attr, \"markdown\", None)\n                        or str(markdown_attr)\n                    )\n                    # 移除图片\n                    markdown_text = re.sub(r\"!\\[[^\\]]*\\]\\([^\\)]+\\)\", \"\", markdown_text)\n                    all_content.append(f\"--- Page {page + 1} ---\\n{markdown_text}\\n\")\n        \n        return '\\n'.join(all_content)\n\n\nclass WebSearchTool(BaseTool):\n    \"\"\"网络搜索工具 - 使用 DuckDuckGo\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        网络搜索（DuckDuckGo）\n        \n        Parameters:\n            query (str): 搜索关键词\n            max_results (int, optional): 最大结果数，默认10\n            save_path (str, optional): 保存结果的相对路径（.md文件）\n        \"\"\"\n        try:\n            if not DDGS_AVAILABLE:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"ddgs not installed. Run: pip install ddgs\"\n                }\n            \n            query = parameters.get(\"query\")\n            max_results = parameters.get(\"max_results\", 10)\n            save_path = parameters.get(\"save_path\")\n            \n            if not query:\n                return {\n                    \"status\": \"error\",\n                    \"output\": \"\",\n                    \"error\": \"query is required\"\n                }\n            \n            # 使用 DuckDuckGo 搜索\n            results = DDGS().text(query, max_results=max_results)\n            \n            # 格式化为 Markdown\n            results_md = []\n            results_md.append(f\"# Search Results: {query}\\n\")\n            results_md.append(f\"Total: {len(results)} results\\n\")\n            \n            for i, result in enumerate(results, 1):\n                title = result.get('title', 'No title')\n                url = result.get('href', '')\n                snippet = result.get('body', '')\n                \n                results_md.append(f\"## {i}. {title}\\n\")\n                results_md.append(f\"**URL**: {url}\\n\")\n                results_md.append(f\"**Snippet**: {snippet}\\n\")\n            \n            results_text = '\\n'.join(results_md)\n            \n            # 保存到文件\n            if save_path:\n                # 生成包含搜索参数的文件名\n                from pathlib import Path\n                save_path_obj = Path(save_path)\n                safe_query = re.sub(r'[^\\w\\s-]', '', query).strip()\n                safe_query = re.sub(r'[-\\s]+', '_', safe_query)[:50]  # 限制长度\n                \n                new_filename = f\"{save_path_obj.stem}_{safe_query}_n{max_results}{save_path_obj.suffix}\"\n                final_save_path = str(save_path_obj.parent / new_filename)\n                \n                abs_save_path = get_abs_path(task_id, final_save_path)\n                abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n                \n                with open(abs_save_path, 'w', encoding='utf-8') as f:\n                    f.write(results_text)\n                \n                output = f\"结果保存在 {final_save_path}\"\n            else:\n                output = results_text\n            \n            return {\n                \"status\": \"success\",\n                \"output\": output,\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n\n\nclass FileDownloadTool(BaseTool):\n    \"\"\"文件下载工具\"\"\"\n    \n    def execute(self, task_id: str, parameters: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"\n        从URL下载文件\n        \n        Parameters:\n            url (str): 文件URL\n            save_path (str): 保存的相对路径\n        \"\"\"\n        try:\n            url = parameters.get(\"url\")\n            save_path = parameters.get(\"save_path\")\n            \n            abs_save_path = get_abs_path(task_id, save_path)\n            abs_save_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # 下载文件\n            response = requests.get(url, stream=True, timeout=60)\n            response.raise_for_status()\n            \n            # 写入文件\n            with open(abs_save_path, 'wb') as f:\n                for chunk in response.iter_content(chunk_size=8192):\n                    f.write(chunk)\n            \n            file_size = abs_save_path.stat().st_size\n            size_mb = file_size / (1024 * 1024)\n            \n            return {\n                \"status\": \"success\",\n                \"output\": f\"Downloaded to {save_path} ({size_mb:.2f} MB)\",\n                \"error\": \"\"\n            }\n            \n        except Exception as e:\n            return {\n                \"status\": \"error\",\n                \"output\": \"\",\n                \"error\": str(e)\n            }\n"
  },
  {
    "path": "utils/__init__.py",
    "content": "# Utils modules\n"
  },
  {
    "path": "utils/cli_mode.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n交互式 CLI 模式\n\"\"\"\n\nimport os\nimport sys\nfrom pathlib import Path\nimport subprocess\nimport threading\nimport queue\nimport signal\nimport time\nimport json\nimport hashlib\nfrom datetime import datetime\n\nfrom utils.user_paths import (\n    apply_runtime_env_defaults,\n    get_user_conversations_dir,\n    get_user_agent_library_root,\n)\n\ntry:\n    from prompt_toolkit import PromptSession, print_formatted_text\n    from prompt_toolkit.completion import WordCompleter\n    from prompt_toolkit.formatted_text import HTML\n    from prompt_toolkit.patch_stdout import patch_stdout\n    PROMPT_TOOLKIT_AVAILABLE = True\nexcept ImportError:\n    PROMPT_TOOLKIT_AVAILABLE = False\n\ntry:\n    from rich.console import Console\n    from rich.panel import Panel\n    from rich.text import Text\n    from rich.live import Live\n    from rich.table import Table\n    RICH_AVAILABLE = True\nexcept ImportError:\n    RICH_AVAILABLE = False\n\n\ndef t(key: str, lang: str = 'en') -> str:\n    \"\"\"获取指定语言的文本（全局函数）\"\"\"\n    return TEXTS.get(lang, TEXTS['en']).get(key, key)\n\n\n# 多语言文本配置\nTEXTS = {\n    'en': {\n        # System messages\n        'select_agent_system': 'Select Agent System',\n        'select_mode': 'Select Tool Execution Mode',\n        'auto_mode': 'Auto Mode - All tools execute automatically (fast, risky)',\n        'manual_mode': 'Manual Mode - File write/code exec/pip install need confirmation (safe)',\n        'mode_set_auto': 'Set to: Auto Mode',\n        'mode_set_manual': 'Set to: Manual Mode',\n        'invalid_choice': 'Invalid choice, please enter',\n        'default': 'default',\n        \n        # Banner\n        'cli_title': 'MLA Agent - Interactive CLI',\n        'work_dir': 'Work Directory',\n        'default_agent': 'Default Agent',\n        'available_agents': 'Available Agents',\n        'usage': 'Usage',\n        'usage_1': 'Enter task directly (use default Agent)',\n        'usage_2': '@agent_name task (switch and use specified Agent)',\n        'usage_3': 'HIL tasks will auto-prompt for response',\n        'usage_4': 'Ctrl+C interrupt | /resume resume | /quit exit | /help help',\n        \n        # Commands\n        'starting_task': 'Starting Task',\n        'input': 'Input',\n        'hint_resume': 'Hint: Enter /resume to resume, enter new content to start new task',\n        'stopping_task': 'Stopping running task...',\n        'task_stopped': 'Task stopped',\n        'task_force_stopped': 'Task force stopped',\n        'goodbye': 'Goodbye!',\n        'available_agents_list': 'Available Agents',\n        'current': 'current',\n        'interrupting_task': 'Interrupting task...',\n        'task_interrupted': 'Task interrupted',\n        'no_running_task': 'No running task. Enter /quit to exit CLI',\n        \n        # HIL\n        'hil_detected': 'HIL task detected! Press Enter to handle...',\n        'hil_task': 'Human-in-Loop Task',\n        'task_id': 'Task ID',\n        'instruction': 'Instruction',\n        'enter_response': 'Please enter your response (any text)',\n        'skip_task': 'Enter /skip to skip this task',\n        'hil_responded': 'HIL task responded',\n        'content': 'Content',\n        'hil_response_failed': 'HIL response failed, please retry',\n        'hil_skipped': 'HIL task skipped',\n        'response_empty': 'Response cannot be empty, please re-enter',\n        \n        # Tool confirmation\n        'tool_confirm_detected': 'Tool execution request detected! Press Enter to confirm...',\n        'tool_confirm_title': 'Tool Execution Confirmation',\n        'tool_name': 'Tool Name',\n        'confirm_id': 'Confirm ID',\n        'parameters': 'Parameters',\n        'choose_action': 'Choose action',\n        'approve_tool': 'yes / y - Approve tool execution',\n        'reject_tool': 'no / n  - Reject tool execution',\n        'tool_approved': 'Tool approved',\n        'tool_rejected': 'Tool rejected',\n        'invalid_choice_yn': 'Invalid choice, please enter yes or no',\n        \n        # Resume\n        'checking_task': 'Checking interrupted task...',\n        'task_found': 'Interrupted task found',\n        'agent': 'Agent',\n        'task': 'Task',\n        'interrupted_at': 'Interrupted at',\n        'stack_depth': 'Stack depth',\n        'resume_confirm': 'Resume this task? [y/N]',\n        'resume_cancelled': 'Resume cancelled',\n        'resuming_task': 'Resuming task...',\n        \n        # Pending task warning\n        'pending_task_warning': 'Pending task detected, cannot start new task!',\n        'hil_pending': 'HIL task waiting for response',\n        'tool_confirm_pending': 'Tool confirmation waiting for processing',\n        'press_enter_hint': 'Please press Enter to enter processing mode',\n        \n        # Toolbar\n        'toolbar': '@agent switch | Ctrl+C interrupt | /resume resume | /quit exit',\n        'toolbar_hil': 'HIL task waiting for response!',\n    },\n    'zh': {\n        # System messages\n        'select_agent_system': '选择 Agent 系统',\n        'select_mode': '选择工具执行模式',\n        'auto_mode': '自动模式 (Auto) - 所有工具自动执行（快速，但有风险）',\n        'manual_mode': '手动模式 (Manual) - 文件写入、代码执行、包安装需要确认（安全）',\n        'mode_set_auto': '已设置为: 自动模式 (Auto)',\n        'mode_set_manual': '已设置为: 手动模式 (Manual)',\n        'invalid_choice': '无效选择，请输入',\n        'default': '默认',\n        \n        # Banner\n        'cli_title': 'MLA Agent - 交互式 CLI',\n        'work_dir': '工作目录',\n        'default_agent': '默认Agent',\n        'available_agents': '可用Agents',\n        'usage': '使用说明',\n        'usage_1': '直接输入任务（使用默认 Agent）',\n        'usage_2': '@agent_name 任务（切换并使用指定 Agent）',\n        'usage_3': 'HIL 任务出现时会自动提示，输入响应内容即可',\n        'usage_4': 'Ctrl+C 中断任务 | /resume 恢复 | /quit 退出 | /help 帮助',\n        \n        # Commands\n        'starting_task': '启动任务',\n        'input': '输入',\n        'hint_resume': '提示: 输入/resume回车可续跑，输入新内容开始新任务',\n        'stopping_task': '正在停止运行中的任务...',\n        'task_stopped': '任务已停止',\n        'task_force_stopped': '任务已强制终止',\n        'goodbye': '再见！',\n        'available_agents_list': '可用 Agents',\n        'current': '当前',\n        'interrupting_task': '正在中断任务...',\n        'task_interrupted': '任务已中断',\n        'no_running_task': '没有运行中的任务。输入 /quit 退出 CLI',\n        \n        # HIL\n        'hil_detected': '检测到 HIL 任务！请按回车处理...',\n        'hil_task': '人类交互任务 (HIL)',\n        'task_id': '任务ID',\n        'instruction': '指令',\n        'enter_response': '请输入您的响应（任何文本）',\n        'skip_task': '输入 /skip 跳过此任务',\n        'hil_responded': 'HIL 任务已响应',\n        'content': '内容',\n        'hil_response_failed': 'HIL 响应失败，请稍后重试',\n        'hil_skipped': '已跳过此 HIL 任务',\n        'response_empty': '响应内容不能为空，请重新输入',\n        \n        # Tool confirmation\n        'tool_confirm_detected': '检测到工具执行请求！请按回车确认...',\n        'tool_confirm_title': '工具执行确认请求',\n        'tool_name': '工具名称',\n        'confirm_id': '确认ID',\n        'parameters': '参数',\n        'choose_action': '选择操作',\n        'approve_tool': 'yes / y - 批准执行此工具',\n        'reject_tool': 'no / n  - 拒绝执行此工具',\n        'tool_approved': '已批准执行工具',\n        'tool_rejected': '已拒绝执行工具',\n        'invalid_choice_yn': '无效选择，请输入 yes 或 no',\n        \n        # Resume\n        'checking_task': '检查中断的任务...',\n        'task_found': '发现中断的任务',\n        'agent': 'Agent',\n        'task': '任务',\n        'interrupted_at': '中断于',\n        'stack_depth': '栈深度',\n        'resume_confirm': '是否恢复此任务？ [y/N]',\n        'resume_cancelled': '已取消恢复',\n        'resuming_task': '恢复任务...',\n        \n        # Pending task warning\n        'pending_task_warning': '检测到待处理的任务，无法启动新任务！',\n        'hil_pending': 'HIL 任务正在等待您的响应',\n        'tool_confirm_pending': '工具确认请求正在等待您的处理',\n        'press_enter_hint': '请直接按回车进入处理模式',\n        \n        # Toolbar\n        'toolbar': '@agent 切换 | Ctrl+C 中断 | /resume 恢复 | /quit 退出',\n        'toolbar_hil': '有HIL任务等待响应！',\n    }\n}\n\n\nclass InteractiveCLI:\n    \"\"\"交互式命令行界面\"\"\"\n    \n    def __init__(self, task_id: str, agent_system: str = \"Test_agent\"):\n        apply_runtime_env_defaults()\n        self.task_id = task_id\n        self.agent_system = agent_system\n        self.current_agent = \"alpha_agent\"\n        self.current_process = None\n        self.direct_tools = True\n        self.output_queue = queue.Queue()\n        self.output_lines = []  # 保存最近的输出\n        self.max_output_lines = 20  # 最多保留20行输出\n        self.hil_mode = False  # 是否处于 HIL 响应模式\n        self.current_hil_task = None  # 当前的 HIL 任务\n        self.pending_hil = None  # 待处理的 HIL 任务（后台线程检测到的）\n        self.hil_processing = False  # 是否正在处理 HIL 任务（避免重复检测）\n        self.hil_check_interval = 2  # HIL 检查间隔（秒）\n        self.stop_hil_checker = False  # 停止 HIL 检查线程的标志\n        \n        # 工具确认相关\n        self.pending_tool_confirmation = None  # 待处理的工具确认（后台线程检测到的）\n        self.tool_confirmation_processing = False  # 是否正在处理工具确认\n        self.auto_mode = None  # 权限模式（None=未设置, True=自动, False=手动）\n        \n        # 语言设置\n        self.language = 'en'  # 默认英文\n        \n        # Rich console\n        self.console = Console() if RICH_AVAILABLE else None\n        \n        # 加载可用 agent 列表\n        self.available_agents = self._load_available_agents()\n        \n        # direct-tools 模式通过 JSONL 事件 + stdin 控制\n        self._start_hil_checker()\n    \n    def t(self, key: str) -> str:\n        \"\"\"获取当前语言的文本\"\"\"\n        return TEXTS.get(self.language, TEXTS['en']).get(key, key)\n    \n    def _load_available_agents(self):\n        \"\"\"加载 Level 2/3 Agent 列表\"\"\"\n        try:\n            from utils.config_loader import ConfigLoader\n            config_loader = ConfigLoader(self.agent_system)\n            \n            agents = []\n            for name, config in config_loader.all_tools.items():\n                if config.get(\"type\") == \"llm_call_agent\":\n                    level = config.get(\"level\", 0)\n                    if level in [1,2, 3]:\n                        agents.append(name)\n            \n            return agents\n        except:\n            return [\"alpha_agent\"]\n    \n    def _check_hil_task(self) -> dict:\n        \"\"\"检查当前 workspace 是否有等待中的 HIL 任务\"\"\"\n        return self.pending_hil or {\"found\": False}\n    \n    def _respond_hil_task(self, hil_id: str, response: str) -> bool:\n        \"\"\"响应 HIL 任务\"\"\"\n        return self._send_control_message({\n            \"type\": \"hil_response\",\n            \"hil_id\": hil_id,\n            \"response\": response,\n        })\n    \n    def _check_tool_confirmation(self) -> dict:\n        \"\"\"检查当前 workspace 是否有等待中的工具确认请求\"\"\"\n        return self.pending_tool_confirmation or {\"found\": False}\n    \n    def _respond_tool_confirmation(self, confirm_id: str, approved: bool) -> bool:\n        \"\"\"响应工具确认请求\"\"\"\n        return self._send_control_message({\n            \"type\": \"tool_confirmation_response\",\n            \"confirm_id\": confirm_id,\n            \"approved\": approved,\n        })\n    \n    def _get_interrupted_task(self) -> dict:\n        \"\"\"获取中断的任务（检查 stack）\"\"\"\n        try:\n            # 计算 task_id 的 hash（与 hierarchy_manager 一致）\n            task_hash = hashlib.md5(self.task_id.encode()).hexdigest()[:8]  # 8位，不是12位\n            \n            # 跨平台路径处理\n            task_folder = Path(self.task_id).name if (os.sep in self.task_id or '/' in self.task_id or '\\\\' in self.task_id) else self.task_id\n            task_name = f\"{task_hash}_{task_folder}\"\n            \n            # Stack 文件位置（与 hierarchy_manager 一致）\n            conversations_dir = get_user_conversations_dir()\n            stack_file = conversations_dir / f\"{task_name}_stack.json\"\n            \n            if not stack_file.exists():\n                return {\"found\": False, \"message\": f\"没有找到中断的任务（文件不存在: {stack_file})\"}\n            \n            # 读取 stack\n            with open(stack_file, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n                stack = data.get(\"stack\", [])\n            \n            if not stack:\n                return {\"found\": False, \"message\": \"没有中断的任务（stack 为空）\"}\n            \n            # 获取栈底任务（最初的用户输入）\n            bottom_task = stack[0]\n            agent_name = bottom_task.get(\"agent_name\")\n            user_input = bottom_task.get(\"user_input\")\n            \n            if not agent_name or not user_input:\n                return {\"found\": False, \"message\": \"任务数据不完整\"}\n            \n            return {\n                \"found\": True,\n                \"agent_name\": agent_name,\n                \"user_input\": user_input,\n                \"interrupted_at\": bottom_task.get(\"start_time\", \"未知\"),\n                \"stack_depth\": len(stack)\n            }\n        \n        except Exception as e:\n            return {\"found\": False, \"message\": f\"读取任务失败: {e}\"}\n    \n    def _start_hil_checker(self):\n        \"\"\"启动后台 HIL/工具确认检查线程\"\"\"\n        if self.direct_tools:\n            return\n\n        def hil_checker_thread():\n            while not self.stop_hil_checker:\n                try:\n                    # 检查 HIL 任务\n                    if not self.pending_hil and not self.hil_processing:\n                        hil_task = self._check_hil_task()\n                        if hil_task.get(\"found\"):\n                            # 发现新的 HIL 任务\n                            self.pending_hil = hil_task\n                            # 打印提示音（ASCII bell）和可见提示\n                            print(\"\\n\\n\\a\")  # \\a 是响铃符号\n                            print(\"\\n\" + \"=\"*80)\n                            print(f\"🔔🔔🔔 {self.t('hil_detected')} 🔔🔔🔔\")\n                            print(\"=\"*80 + \"\\n\")\n                    \n                    # 检查工具确认请求（仅在手动模式下）\n                    if self.auto_mode == False and not self.pending_tool_confirmation and not self.tool_confirmation_processing:\n                        tool_confirmation = self._check_tool_confirmation()\n                        if tool_confirmation.get(\"found\"):\n                            # 发现新的工具确认请求\n                            self.pending_tool_confirmation = tool_confirmation\n                            # 打印提示音和可见提示\n                            print(\"\\n\\n\\a\")\n                            print(\"\\n\" + \"=\"*80)\n                            print(f\"⚠️⚠️⚠️ {self.t('tool_confirm_detected')} ⚠️⚠️⚠️\")\n                            print(\"=\"*80 + \"\\n\")\n                except Exception:\n                    pass\n                \n                # 等待一段时间再检查\n                time.sleep(self.hil_check_interval)\n        \n        thread = threading.Thread(target=hil_checker_thread, daemon=True)\n        thread.start()\n\n    def _send_control_message(self, payload: dict) -> bool:\n        \"\"\"向 direct-tools 子进程发送控制消息（HIL/工具确认）。\"\"\"\n        try:\n            if not self.current_process or not self.current_process.stdin:\n                return False\n            self.current_process.stdin.write(json.dumps(payload, ensure_ascii=False) + \"\\n\")\n            self.current_process.stdin.flush()\n            return True\n        except Exception:\n            return False\n    \n    def _show_hil_prompt(self, hil_id: str, instruction: str):\n        \"\"\"显示 HIL 提示界面\"\"\"\n        print(\"\\n\" + \"=\"*80)\n        print(f\"🔔 {self.t('hil_task')}\")\n        print(\"=\"*80)\n        print(f\"📝 {self.t('task_id')}: {hil_id}\")\n        print(f\"📋 {self.t('instruction')}: {instruction}\")\n        print(\"=\"*80)\n        print(f\"💡 {self.t('enter_response')}\")\n        print(f\"   {self.t('skip_task')}\")\n        print(\"=\"*80 + \"\\n\")\n    \n    def _show_tool_confirmation_prompt(self, confirm_id: str, tool_name: str, arguments: dict):\n        \"\"\"显示工具确认界面\"\"\"\n        print(\"\\n\" + \"=\"*80)\n        print(f\"⚠️  {self.t('tool_confirm_title')}\")\n        print(\"=\"*80)\n        print(f\"🔧 {self.t('tool_name')}: {tool_name}\")\n        print(f\"📝 {self.t('confirm_id')}: {confirm_id}\")\n        print(f\"📋 {self.t('parameters')}:\")\n        for key, value in arguments.items():\n            # 截断过长的参数值\n            value_str = str(value)\n            if len(value_str) > 100:\n                value_str = value_str[:100] + \"...\"\n            print(f\"     {key}: {value_str}\")\n        print(\"=\"*80)\n        print(f\"💡 {self.t('choose_action')}:\")\n        print(f\"   {self.t('approve_tool')}\")\n        print(f\"   {self.t('reject_tool')}\")\n        print(\"=\"*80 + \"\\n\")\n    \n    def get_banner_text(self):\n        \"\"\"获取 banner 文本（用于顶部固定显示）\"\"\"\n        return (\n            \"=\"*80 + \"\\n\" +\n            f\"🤖 {self.t('cli_title')}\\n\" +\n            \"=\"*80 + \"\\n\" +\n            f\"📂 {self.t('work_dir')}: {self.task_id}\\n\" +\n            f\"🤖 {self.t('default_agent')}: {self.current_agent}\\n\" +\n            f\"📋 {self.t('available_agents')}: {', '.join(self.available_agents[:3])}{'...' if len(self.available_agents) > 3 else ''}\\n\" +\n            \"-\"*80 + \"\\n\" +\n            f\"💡 {self.t('usage')}:\\n\" +\n            f\"  - {self.t('usage_1')}\\n\" +\n            f\"  - {self.t('usage_2')}\\n\" +\n            f\"  - 🔔 {self.t('usage_3')}\\n\" +\n            f\"  - {self.t('usage_4')}\\n\" +\n            \"-\"*80 + \"\\n\"\n        )\n    \n    def show_banner(self):\n        \"\"\"显示欢迎信息（初始时）\"\"\"\n        if RICH_AVAILABLE:\n            self.console.clear()\n            \n            # 创建顶部 Panel\n            header_table = Table.grid(padding=(0, 2))\n            header_table.add_column(style=\"cyan\")\n            header_table.add_column()\n            \n            header_table.add_row(f\"📂 {self.t('work_dir')}:\", self.task_id)\n            header_table.add_row(f\"🤖 {self.t('default_agent')}:\", f\"[bold green]{self.current_agent}[/]\")\n            header_table.add_row(f\"📋 {self.t('available_agents')}:\", \", \".join(self.available_agents[:4]) + (\"...\" if len(self.available_agents) > 4 else \"\"))\n            \n            self.console.print(Panel(\n                header_table,\n                title=f\"[bold blue]🤖 {self.t('cli_title')}[/]\",\n                border_style=\"blue\"\n            ))\n            \n            # 使用说明\n            help_text = Text()\n            help_text.append(f\"💡 {self.t('usage')}:\\n\", style=\"bold yellow\")\n            help_text.append(f\"  • {self.t('usage_1')}\\n\")\n            help_text.append(f\"  • {self.t('usage_2')}\\n\")\n            help_text.append(f\"  • 🔔 {self.t('usage_3')}\\n\", style=\"cyan\")\n            help_text.append(f\"  • {self.t('usage_4')}\\n\")\n            \n            self.console.print(Panel(help_text, border_style=\"dim\"))\n            print()\n        else:\n            # 回退到简单模式\n            os.system('clear' if os.name != 'nt' else 'cls')\n            print(self.get_banner_text())\n    \n    def parse_input(self, user_input: str):\n        \"\"\"\n        解析用户输入\n        \n        Returns:\n            (agent_name, task_description)\n        \"\"\"\n        user_input = user_input.strip()\n        \n        # 检查是否指定 agent\n        if user_input.startswith('@'):\n            parts = user_input[1:].split(None, 1)\n            if len(parts) == 2:\n                agent_name, task = parts\n                # 验证 agent 是否存在\n                if agent_name in self.available_agents:\n                    return agent_name, task\n                else:\n                    print(f\"⚠️  Agent '{agent_name}' 不存在，使用默认 Agent\")\n                    return self.current_agent, user_input\n            elif len(parts) == 1:\n                # 只有 @agent_name，没有任务\n                agent_name = parts[0]\n                if agent_name in self.available_agents:\n                    self.current_agent = agent_name\n                    print(f\"✅ 已切换到: {agent_name}\")\n                    return None, None\n                else:\n                    print(f\"⚠️  Agent '{agent_name}' 不存在\")\n                    return None, None\n        \n        # 没有 @，使用默认 agent\n        return self.current_agent, user_input\n    \n    def stop_current_task(self):\n        \"\"\"停止当前运行的任务\"\"\"\n        if self.current_process and self.current_process.poll() is None:\n            try:\n                if sys.platform == 'win32':\n                    # Windows: 发送 Ctrl+Break 信号\n                    self.current_process.send_signal(signal.CTRL_BREAK_EVENT)\n                    try:\n                        self.current_process.wait(timeout=2)\n                    except subprocess.TimeoutExpired:\n                        # 如果信号无效，强制终止\n                        self.current_process.terminate()\n                        self.current_process.wait(timeout=1)\n                else:\n                    # Unix/Mac: 使用 terminate (发送 SIGTERM)\n                    self.current_process.terminate()\n                    self.current_process.wait(timeout=3)\n                print(\"\\n⚠️  已终止前一个任务\\n\")\n            except Exception as e:\n                # 最后手段：强制 kill\n                try:\n                    self.current_process.kill()\n                    self.current_process.wait(timeout=1)\n                except (subprocess.TimeoutExpired, ProcessLookupError, PermissionError):\n                    pass\n    \n    def run_task(self, agent_name: str, user_input: str):\n        \"\"\"\n        在后台运行任务（JSONL模式）\n        前台保持输入可用\n        \"\"\"\n        # 终止当前任务（如果有）\n        self.stop_current_task()\n        \n        print(f\"\\n{'='*80}\")\n        print(f\"🤖 {self.t('starting_task')}: {agent_name}\")\n        print(f\"📝 {self.t('input')}: {user_input}\")\n        print(f\"💡 {self.t('hint_resume')}\")\n        print(f\"{'='*80}\\n\")\n        \n        # 使用当前 Python 解释器调用 start.py（避免 venv 路径问题）\n        start_py = Path(__file__).parent.parent / \"start.py\"\n        \n        # Windows 需要特殊的进程创建标志以支持信号处理\n        popen_kwargs = {\n            'stdout': subprocess.PIPE,\n            'stderr': subprocess.PIPE,\n            'stdin': subprocess.PIPE,\n            'text': True,\n            'encoding': 'utf-8',\n            'errors': 'replace',\n            'bufsize': 0  # 无缓冲，实时输出\n        }\n        \n        if sys.platform == 'win32':\n            # Windows: 创建新的进程组，允许发送 Ctrl+Break\n            popen_kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP\n        \n        # 构建命令参数（使用 Python 解释器直接运行 start.py）\n        cmd_args = [\n            sys.executable,\n            str(start_py),\n                '--task_id', self.task_id,\n                '--agent_name', agent_name,\n                '--user_input', user_input,\n                '--agent_system', self.agent_system,\n                '--jsonl',  # JSONL 模式，实时流式输出\n                '--direct-tools',\n        ]\n        \n        # 添加权限模式参数\n        if self.auto_mode is not None:\n            cmd_args.extend(['--auto-mode', 'true' if self.auto_mode else 'false'])\n        \n        # 启动子进程（JSONL模式 - 实时流式输出）\n        self.current_process = subprocess.Popen(\n            cmd_args,\n            **popen_kwargs\n        )\n        \n        # 后台线程读取输出（JSONL 模式，解析并显示）\n        def read_output():\n            try:\n                import json\n                RESET = \"\\033[0m\"\n                THINKING_COLOR = \"\\033[94m\"\n                REASONING_COLOR = \"\\033[95m\"\n                TOOL_PENDING_COLOR = \"\\033[33m\"\n                TOOL_SUCCESS_COLOR = \"\\033[32m\"\n                TOOL_ERROR_COLOR = \"\\033[31m\"\n                stream_kind = None\n\n                def push_output_line(text: str):\n                    self.output_lines.append(text)\n                    if len(self.output_lines) > self.max_output_lines:\n                        self.output_lines.pop(0)\n\n                def flush_stream(force_newline: bool = True):\n                    nonlocal stream_kind\n                    if stream_kind is not None and force_newline:\n                        sys.stdout.write(\"\\n\")\n                        sys.stdout.flush()\n                    stream_kind = None\n\n                def write_stream(text: str, kind: str):\n                    nonlocal stream_kind\n                    if not text:\n                        return\n                    if stream_kind != kind:\n                        flush_stream(force_newline=(stream_kind is not None))\n                        if kind == \"reasoning\":\n                            sys.stdout.write(f\"{REASONING_COLOR}[Model reasoning]{RESET}\\n\")\n                        elif kind == \"thinking\":\n                            sys.stdout.write(f\"{THINKING_COLOR}[Thinking agent]{RESET}\\n\")\n                        stream_kind = kind\n                    color = THINKING_COLOR if kind == \"thinking\" else (REASONING_COLOR if kind == \"reasoning\" else \"\")\n                    sys.stdout.write(f\"{color}{text}{RESET if color else ''}\")\n                    sys.stdout.flush()\n\n                for line in self.current_process.stdout:\n                    if not line:\n                        continue\n                    line = line.rstrip('\\n')\n                    if not line.strip():\n                        continue\n                    \n                    try:\n                        # 解析 JSONL 事件\n                        event = json.loads(line)\n                        \n                        # 显示所有事件（不截断）\n                        if event['type'] == 'token':\n                            text = event['text']\n                            write_stream(text, \"token\")\n\n                        elif event['type'] == 'thinking_token':\n                            text = event.get('text', '')\n                            if text:\n                                write_stream(text, \"thinking\")\n\n                        elif event['type'] == 'reasoning_token':\n                            text = event.get('text', '')\n                            if text:\n                                write_stream(text, \"reasoning\")\n\n                        elif event['type'] == 'agent_start':\n                            flush_stream()\n                            agent = event.get('agent', '')\n                            task = event.get('task', '')\n                            display_line = f\"🤖 Agent开始: {agent}\"\n                            push_output_line(display_line)\n                            print(display_line)\n                            if task:\n                                print(f\"   任务: {task}\")\n\n                        elif event['type'] == 'agent_end':\n                            flush_stream()\n                            status = event.get('status', 'unknown')\n                            display_line = f\"🏁 Agent结束: {status}\"\n                            push_output_line(display_line)\n                            print(display_line)\n\n                        elif event['type'] == 'thinking_start':\n                            # Thinking 已按 token 流式显示，这里不再额外插入分隔标题\n                            flush_stream(force_newline=False)\n\n                        elif event['type'] == 'thinking_end':\n                            # Thinking 已在流式 token 中完整输出，结束时只换行，避免重复显示\n                            flush_stream()\n\n                        elif event['type'] == 'tool_call':\n                            flush_stream()\n                            name = event.get('name', '')\n                            arguments = event.get('arguments', {}) or {}\n                            display_line = f\"🔧 工具调用: {name}\"\n                            push_output_line(display_line)\n                            print(f\"{TOOL_PENDING_COLOR}{display_line}{RESET}\")\n                            if arguments:\n                                for key, value in arguments.items():\n                                    value_str = str(value)\n                                    if len(value_str) > 200:\n                                        value_str = value_str[:200] + \"...\"\n                                    print(f\"   {key}: {value_str}\")\n\n                        elif event['type'] == 'tool_result':\n                            flush_stream()\n                            name = event.get('name', '')\n                            status = event.get('status', 'unknown')\n                            error_text = event.get('error', '') or ''\n                            preview = event.get('output_preview', '') or ''\n                            status_icon = \"✅\" if status == \"success\" else \"❌\"\n                            display_line = f\"{status_icon} 工具结果: {name} ({status})\"\n                            push_output_line(display_line)\n                            color = TOOL_SUCCESS_COLOR if status == \"success\" else TOOL_ERROR_COLOR\n                            print(f\"{color}{display_line}{RESET}\")\n                            if error_text:\n                                print(f\"   error: {error_text}\")\n                            elif preview:\n                                print(f\"   output: {preview}\")\n                        \n                        elif event['type'] == 'result':\n                            flush_stream()\n                            # 显示完整结果\n                            summary = event.get('summary', '')\n                            \n                            print(f\"\\n{'='*80}\")\n                            print(\"📊 执行结果:\")\n                            print(f\"{'='*80}\")\n                            print(summary)  # 完整显示\n                            print(f\"{'='*80}\\n\")\n                            \n                            # 简短摘要到输出历史\n                            push_output_line(f\"📊 结果: {summary[:100]}...\")\n                        \n                        elif event['type'] == 'end':\n                            flush_stream()\n                            status_icon = \"✅\" if event.get('status') == 'ok' else \"❌\"\n                            duration_sec = event.get('duration_ms', 0) / 1000\n                            display_line = f\"{status_icon} 任务完成 ({duration_sec:.1f}s)\"\n                            push_output_line(display_line)\n                            print(display_line)\n                            print()\n\n                        elif event['type'] == 'human_in_loop':\n                            flush_stream()\n                            self.pending_hil = {\n                                \"found\": True,\n                                \"hil_id\": event.get(\"hil_id\", \"\"),\n                                \"instruction\": event.get(\"message\", \"\"),\n                                \"task_id\": self.task_id,\n                            }\n                            print(\"\\n\\n\\a\")\n                            print(\"\\n\" + \"=\"*80)\n                            print(f\"🔔🔔🔔 {self.t('hil_detected')} 🔔🔔🔔\")\n                            print(\"=\"*80 + \"\\n\")\n                            instruction = event.get(\"message\", \"\") or \"\"\n                            if instruction:\n                                print(instruction)\n                                print()\n\n                        elif event['type'] == 'tool_confirmation':\n                            flush_stream()\n                            self.pending_tool_confirmation = {\n                                \"found\": True,\n                                \"confirm_id\": event.get(\"confirm_id\", \"\"),\n                                \"tool_name\": event.get(\"tool_name\", \"\"),\n                                \"arguments\": event.get(\"arguments\", {}) or {},\n                                \"task_id\": self.task_id,\n                            }\n                            print(\"\\n\\n\\a\")\n                            print(\"\\n\" + \"=\"*80)\n                            print(f\"⚠️⚠️⚠️ {self.t('tool_confirm_detected')} ⚠️⚠️⚠️\")\n                            print(\"=\"*80 + \"\\n\")\n                            tool_name = event.get(\"tool_name\", \"\")\n                            arguments = event.get(\"arguments\", {}) or {}\n                            if tool_name:\n                                print(f\"Tool: {tool_name}\")\n                            if arguments:\n                                for key, value in arguments.items():\n                                    value_str = str(value)\n                                    if len(value_str) > 200:\n                                        value_str = value_str[:200] + \"...\"\n                                    print(f\"  {key}: {value_str}\")\n                                print()\n                        \n                        elif event['type'] == 'error':\n                            flush_stream()\n                            # 错误事件 - 完整显示错误信息\n                            error_text = event.get('text', '')\n                            print(error_text)\n                            push_output_line(\"❌ 发生错误\")\n\n                        elif event['type'] == 'warn':\n                            flush_stream()\n                            warn_text = event.get('text', '')\n                            print(f\"⚠️ {warn_text}\")\n                            push_output_line(\"⚠️ 警告\")\n\n                        elif event['type'] == 'notice':\n                            flush_stream()\n                            notice_text = event.get('text', '')\n                            print(f\"ℹ️ {notice_text}\")\n                            push_output_line(\"ℹ️ 通知\")\n                    \n                    except json.JSONDecodeError:\n                        # 不是有效的 JSON，跳过\n                        pass\n            except Exception:\n                pass\n        \n        thread = threading.Thread(target=read_output, daemon=True)\n        thread.start()\n\n        # 读取 stderr，防止管道阻塞（但不显示，因为 JSONL 模式下 print 被重定向到 stderr）\n        def read_stderr():\n            try:\n                for err in self.current_process.stderr:\n                    if not err:\n                        continue\n                    # 静默消费 stderr，防止管道写满阻塞\n                    # 只在遇到真正的错误关键词时才显示\n                    err = err.rstrip('\\n')\n                    if any(keyword in err for keyword in ['Error:', 'Exception:', 'Traceback', 'CRITICAL', 'FATAL']):\n                        error_line = f\"⚠️ {err[:200]}\"\n                        self.output_lines.append(error_line)\n                        if len(self.output_lines) > self.max_output_lines:\n                            self.output_lines.pop(0)\n                        print(error_line)\n            except Exception:\n                pass\n\n        thread_err = threading.Thread(target=read_stderr, daemon=True)\n        thread_err.start()\n    \n    def get_bottom_toolbar(self):\n        \"\"\"获取底部工具栏文本\"\"\"\n        if self.pending_hil:\n            return HTML(\n                f'<style bg=\"ansired\" fg=\"ansiwhite\"> 🔔 {self.t(\"toolbar_hil\")} </style>'\n            )\n        \n        return HTML(\n            f'<style bg=\"ansiblue\" fg=\"ansiwhite\"> 💡 {self.t(\"toolbar\")} </style>'\n        )\n    \n    def run(self):\n        \"\"\"运行交互式 CLI\"\"\"\n        self.show_banner()\n        \n        # 询问用户选择权限模式\n        print(\"\\n\" + \"=\"*80)\n        print(f\"🔐 {self.t('select_mode')}\")\n        print(\"=\"*80)\n        print(f\"1. {self.t('auto_mode')}\")\n        print(f\"2. {self.t('manual_mode')}\")\n        print(\"=\"*80)\n        \n        while self.auto_mode is None:\n            mode_input = input(f\"{self.t('invalid_choice')} [1/2] ({self.t('default')}: 2): \").strip()\n            if not mode_input or mode_input == '2':\n                self.auto_mode = False\n                print(f\"✅ {self.t('mode_set_manual')}\\n\")\n            elif mode_input == '1':\n                self.auto_mode = True\n                print(f\"✅ {self.t('mode_set_auto')}\\n\")\n            else:\n                print(f\"❌ {self.t('invalid_choice')} 1 {self.t('default')} 2\\n\")\n        \n        # 使用 prompt_toolkit（如果可用）\n        if PROMPT_TOOLKIT_AVAILABLE:\n            # 创建自动补全\n            agent_completions = ['@' + agent for agent in self.available_agents]\n            completer = WordCompleter(\n                agent_completions + ['/quit', '/exit', '/help', '/agents', '/resume', '/zh', '/en'],\n                ignore_case=True,\n                sentence=True\n            )\n            \n            session = PromptSession(\n                completer=completer,\n                bottom_toolbar=self.get_bottom_toolbar\n            )\n        \n        while True:\n            try:\n                # 检查是否有待处理的 HIL 任务（由后台线程检测到的）\n                if self.pending_hil:\n                    hil_task = self.pending_hil\n                    self.pending_hil = None  # 清除标志\n                    self.hil_processing = True  # 标记正在处理，避免后台线程重复检测\n                    \n                    # 进入 HIL 响应模式\n                    hil_id = hil_task[\"hil_id\"]\n                    instruction = hil_task[\"instruction\"]\n                    \n                    # 显示 HIL 任务信息\n                    self._show_hil_prompt(hil_id, instruction)\n                    \n                    # 等待用户响应\n                    if PROMPT_TOOLKIT_AVAILABLE:\n                        with patch_stdout():\n                            user_response = session.prompt(f\"[{self.current_agent}] HIL响应 > \").strip()\n                    else:\n                        user_response = input(f\"[{self.current_agent}] HIL响应 > \").strip()\n                    \n                    if not user_response:\n                        print(f\"⚠️  {self.t('response_empty')}\")\n                        self.pending_hil = hil_task  # 恢复任务，下次继续处理\n                        self.hil_processing = False  # 清除处理标志\n                        continue\n                    \n                    if user_response == '/skip':\n                        print(f\"⏭️  {self.t('hil_skipped')}\\n\")\n                        self.hil_processing = False  # 清除处理标志\n                        continue\n                    \n                    # 提交响应\n                    if self._respond_hil_task(hil_id, user_response):\n                        print(f\"✅ {self.t('hil_responded')}\")\n                        print(f\"   {self.t('content')}: {user_response[:100]}{'...' if len(user_response) > 100 else ''}\\n\")\n                    else:\n                        print(f\"❌ {self.t('hil_response_failed')}\\n\")\n                    \n                    self.hil_processing = False  # 清除处理标志，允许检测新的 HIL 任务\n                    continue\n                \n                # 检查是否有待处理的工具确认请求\n                if self.pending_tool_confirmation:\n                    tool_confirmation = self.pending_tool_confirmation\n                    self.pending_tool_confirmation = None  # 清除标志\n                    self.tool_confirmation_processing = True  # 标记正在处理\n                    \n                    # 获取确认信息\n                    confirm_id = tool_confirmation[\"confirm_id\"]\n                    tool_name = tool_confirmation[\"tool_name\"]\n                    arguments = tool_confirmation[\"arguments\"]\n                    \n                    # 显示工具确认界面\n                    self._show_tool_confirmation_prompt(confirm_id, tool_name, arguments)\n                    \n                    # 等待用户选择\n                    if PROMPT_TOOLKIT_AVAILABLE:\n                        with patch_stdout():\n                            user_choice = session.prompt(f\"[{self.current_agent}] 确认 [yes/no] > \").strip().lower()\n                    else:\n                        user_choice = input(f\"[{self.current_agent}] 确认 [yes/no] > \").strip().lower()\n                    \n                    if not user_choice:\n                        print(f\"⚠️  {self.t('invalid_choice_yn')}\")\n                        self.pending_tool_confirmation = tool_confirmation  # 恢复任务\n                        self.tool_confirmation_processing = False\n                        continue\n                    \n                    # 处理用户选择\n                    if user_choice in ['yes', 'y']:\n                        # 批准执行\n                        if self._respond_tool_confirmation(confirm_id, True):\n                            print(f\"✅ {self.t('tool_approved')}: {tool_name}\\n\")\n                        else:\n                            print(f\"❌ {self.t('hil_response_failed')}\\n\")\n                    elif user_choice in ['no', 'n']:\n                        # 拒绝执行\n                        if self._respond_tool_confirmation(confirm_id, False):\n                            print(f\"❌ {self.t('tool_rejected')}: {tool_name}\\n\")\n                        else:\n                            print(f\"❌ {self.t('hil_response_failed')}\\n\")\n                    else:\n                        print(f\"⚠️  {self.t('invalid_choice_yn')}\")\n                        self.pending_tool_confirmation = tool_confirmation  # 恢复任务\n                        self.tool_confirmation_processing = False\n                        continue\n                    \n                    self.tool_confirmation_processing = False\n                    continue\n                \n                # 正常模式：显示提示符\n                if PROMPT_TOOLKIT_AVAILABLE:\n                    # 使用 patch_stdout 确保任务输出不影响输入\n                    with patch_stdout():\n                        user_input = session.prompt(f\"[{self.current_agent}] > \").strip()\n                else:\n                    user_input = input(f\"[{self.current_agent}] > \").strip()\n                \n                if not user_input:\n                    continue\n                \n                # 处理管理命令（优先处理，不受待处理任务影响）\n                if user_input in ['/quit', '/exit', '/q']:\n                    # 停止 HIL 检查线程\n                    self.stop_hil_checker = True\n                    \n                    # 终止运行中的任务\n                    if self.current_process and self.current_process.poll() is None:\n                        print(\"\\n⏹️  正在停止运行中的任务...\")\n                        try:\n                            if sys.platform == 'win32':\n                                self.current_process.send_signal(signal.CTRL_BREAK_EVENT)\n                                try:\n                                    self.current_process.wait(timeout=2)\n                                except subprocess.TimeoutExpired:\n                                    self.current_process.terminate()\n                                    self.current_process.wait(timeout=1)\n                            else:\n                                self.current_process.terminate()\n                                self.current_process.wait(timeout=3)\n                            print(\"✅ 任务已停止\")\n                        except (subprocess.TimeoutExpired, ProcessLookupError):\n                            try:\n                                self.current_process.kill()\n                                print(\"✅ 任务已强制终止\")\n                            except (ProcessLookupError, PermissionError):\n                                pass\n                    print(\"\\n👋 再见！\\n\")\n                    break\n                \n                if user_input == '/help':\n                    # 清屏并重新显示 banner\n                    os.system('clear' if os.name != 'nt' else 'cls')\n                    print(self.get_banner_text())\n                    continue\n                \n                if user_input == '/agents':\n                    print(\"\\n📋 可用 Agents:\")\n                    for i, agent in enumerate(self.available_agents, 1):\n                        mark = \" (当前)\" if agent == self.current_agent else \"\"\n                        print(f\"  {i}. {agent}{mark}\")\n                    print()\n                    continue\n                \n                if user_input == '/resume':\n                    # 恢复中断的任务\n                    print(f\"\\n🔍 {self.t('checking_task')}\")\n                    interrupted = self._get_interrupted_task()\n                    \n                    if not interrupted[\"found\"]:\n                        print(f\"❌ {interrupted['message']}\\n\")\n                        continue\n                    \n                    # 显示任务信息\n                    print(f\"\\n{'='*80}\")\n                    print(f\"📋 {self.t('task_found')}\")\n                    print(f\"{'='*80}\")\n                    print(f\"🤖 {self.t('agent')}: {interrupted['agent_name']}\")\n                    print(f\"📝 {self.t('task')}: {interrupted['user_input'][:100]}{'...' if len(interrupted['user_input']) > 100 else ''}\")\n                    print(f\"⏸️  {self.t('interrupted_at')}: {interrupted['interrupted_at']}\")\n                    print(f\"📊 {self.t('stack_depth')}: {interrupted['stack_depth']}\")\n                    print(f\"{'='*80}\\n\")\n                    \n                    # 确认恢复\n                    confirm = input(f\"{self.t('resume_confirm')} \").strip().lower()\n                    if confirm not in ['y', 'yes']:\n                        print(f\"⏭️  {self.t('resume_cancelled')}\\n\")\n                        continue\n                    \n                    # 恢复任务\n                    print(f\"\\n▶️  {self.t('resuming_task')}\\n\")\n                    self.run_task(interrupted['agent_name'], interrupted['user_input'])\n                    continue\n                \n                if user_input == '/zh':\n                    # 切换到中文\n                    self.language = 'zh'\n                    print(\"\\n✅ 已切换到中文\\n\")\n                    continue\n                \n                if user_input == '/en':\n                    # 切换到英文\n                    self.language = 'en'\n                    print(\"\\n✅ Switched to English\\n\")\n                    continue\n                \n                # 在执行新任务前，检查是否有待处理的 HIL 或工具确认\n                # 防止用户不小心输入内容而不是按回车处理待处理任务\n                if self.pending_hil or self.pending_tool_confirmation:\n                    print(\"\\n\" + \"=\"*80)\n                    print(f\"⚠️  {self.t('pending_task_warning')}\")\n                    print(\"=\"*80)\n                    if self.pending_hil:\n                        print(f\"📌 {self.t('hil_pending')}\")\n                    if self.pending_tool_confirmation:\n                        print(f\"📌 {self.t('tool_confirm_pending')}\")\n                    print(\"=\"*80)\n                    print(f\"💡 {self.t('press_enter_hint')}\")\n                    print(\"=\"*80 + \"\\n\")\n                    continue\n                \n                # 解析输入\n                agent_name, task = self.parse_input(user_input)\n                \n                if agent_name and task:\n                    # 在任务末尾添加时间戳\n                    timestamp = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n                    task_with_timestamp = f\"{task} [时间: {timestamp}]\"\n                    \n                    # 执行任务\n                    self.run_task(agent_name, task_with_timestamp)\n                \n            except KeyboardInterrupt:\n                # Ctrl+C: 终止当前任务但不退出 CLI\n                if self.current_process and self.current_process.poll() is None:\n                    print(\"\\n\\n⚠️  正在中断任务...\")\n                    try:\n                        if sys.platform == 'win32':\n                            # Windows: 发送 Ctrl+Break 信号\n                            self.current_process.send_signal(signal.CTRL_BREAK_EVENT)\n                            try:\n                                self.current_process.wait(timeout=2)\n                            except subprocess.TimeoutExpired:\n                                self.current_process.terminate()\n                                try:\n                                    self.current_process.wait(timeout=1)\n                                except (subprocess.TimeoutExpired, ProcessLookupError):\n                                    self.current_process.kill()\n                        else:\n                            # Unix/Mac: 使用 terminate\n                            self.current_process.terminate()\n                            try:\n                                self.current_process.wait(timeout=2)\n                            except subprocess.TimeoutExpired:\n                                self.current_process.kill()\n                    except Exception:\n                        try:\n                            self.current_process.kill()\n                        except (ProcessLookupError, PermissionError):\n                            pass\n                    print(\"✅ 任务已中断\\n\")\n                    print(\"💡 输入/resume回车可续跑，输入新内容开始新任务\\n\")\n                else:\n                    print(\"\\n\\n💡 没有运行中的任务。输入 /quit 退出 CLI\\n\")\n                continue\n            except EOFError:\n                # Ctrl+D: 退出\n                # 停止 HIL 检查线程\n                self.stop_hil_checker = True\n                \n                if self.current_process and self.current_process.poll() is None:\n                    print(\"\\n\\n⏹️  正在停止运行中的任务...\")\n                    try:\n                        if sys.platform == 'win32':\n                            self.current_process.send_signal(signal.CTRL_BREAK_EVENT)\n                            try:\n                                self.current_process.wait(timeout=2)\n                            except subprocess.TimeoutExpired:\n                                self.current_process.terminate()\n                                self.current_process.wait(timeout=1)\n                        else:\n                            self.current_process.terminate()\n                            self.current_process.wait(timeout=3)\n                    except (subprocess.TimeoutExpired, ProcessLookupError, PermissionError):\n                        try:\n                            self.current_process.kill()\n                        except (ProcessLookupError, PermissionError):\n                            pass\n                print(\"\\n\\n👋 再见！\\n\")\n                break\n\n\ndef get_available_agent_systems():\n    \"\"\"获取可用的 Agent 系统列表\"\"\"\n    try:\n        systems = []\n\n        for item in get_user_agent_library_root().iterdir():\n            if item.is_dir() and not item.name.startswith('.'):\n                systems.append(item.name)\n\n        return sorted(systems) if systems else [\"Test_agent\"]\n    \n    except Exception:\n        return [\"Test_agent\"]\n\n\ndef start_cli_mode(agent_system: str = None, language: str = 'en'):\n    \"\"\"启动交互式 CLI 模式\"\"\"\n    # task_id = 当前目录\n    task_id = os.path.abspath(os.getcwd())\n    \n    # 如果没有指定 agent_system，让用户选择\n    if agent_system is None:\n        available_systems = get_available_agent_systems()\n        \n        print(\"\\n\" + \"=\"*80)\n        print(f\"🤖 {t('select_agent_system', language)}\")\n        print(\"=\"*80)\n        \n        for i, system in enumerate(available_systems, 1):\n            print(f\"{i}. {system}\")\n        \n        print(\"=\"*80)\n        \n        while True:\n            choice = input(f\"{t('invalid_choice', language)} [1-{len(available_systems)}] ({t('default', language)}: 1): \").strip()\n            \n            if not choice:\n                agent_system = available_systems[0]\n                break\n            \n            try:\n                idx = int(choice) - 1\n                if 0 <= idx < len(available_systems):\n                    agent_system = available_systems[idx]\n                    break\n                else:\n                    print(f\"❌ {t('invalid_choice', language)} 1-{len(available_systems)}\\n\")\n            except ValueError:\n                print(f\"❌ {t('invalid_choice', language)} 1-{len(available_systems)}\\n\")\n        \n        if language == 'zh':\n            print(f\"✅ 已选择: {agent_system}\\n\")\n        else:\n            print(f\"✅ Selected: {agent_system}\\n\")\n    \n    cli = InteractiveCLI(task_id, agent_system)\n    cli.language = language  # 设置语言\n    cli.run()\n\n\nif __name__ == \"__main__\":\n    start_cli_mode()\n"
  },
  {
    "path": "utils/config_loader.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n配置加载器 - 读取agent_library中的配置文件\n\"\"\"\n\nimport os\nimport yaml\nfrom typing import Dict, List, Any\nfrom pathlib import Path\n\nfrom utils.user_paths import get_project_root, get_user_data_root\n\n\nclass ConfigLoader:\n    \"\"\"配置加载器，负责读取和合并agent配置\"\"\"\n    \n    def __init__(self, agent_system_name: str = \"infiHelper\", agent_library_root: str | None = None):\n        \"\"\"\n        初始化配置加载器\n        \n        Args:\n            agent_system_name: Agent系统名称，对应agent_library下的文件夹\n            agent_library_root: 可选。显式指定用户 agent_library 根目录（其下应包含 agent_library/<system>）\n        \"\"\"\n        self.agent_system_name = agent_system_name\n        self.agent_library_root = str(agent_library_root).strip() if agent_library_root else \"\"\n        \n        # 查找配置目录（支持：项目内 config + 用户导入目录）\n        # - 项目内: <project_root>/config/agent_library/<system>\n        # - 用户导入: $MLA_AGENT_LIBRARY_DIR/agent_library/<system>\n        self.config_root = self._find_config_root()\n        self.agent_config_dir = self._find_agent_system_dir(agent_system_name)\n        \n        if not os.path.exists(self.agent_config_dir):\n            raise FileNotFoundError(f\"Agent配置目录不存在: {self.agent_config_dir}\")\n        \n        # 加载所有配置\n        self.general_prompts = self._load_general_prompts()\n        self.all_tools = self._load_all_tools()\n        self._inject_framework_default_tools()\n        \n    def _find_config_root(self) -> str:\n        \"\"\"查找配置根目录\"\"\"\n        mla_v3_config = get_project_root() / \"config\"\n\n        if not mla_v3_config.exists():\n            raise FileNotFoundError(f\"配置目录不存在: {mla_v3_config}\")\n        \n        return str(mla_v3_config)\n\n    def _find_agent_system_dir(self, agent_system_name: str) -> str:\n        \"\"\"按优先级查找 agent_system 配置目录\"\"\"\n        candidates = []\n\n        # 1) 用户导入目录（用于桌面端打包后的可扩展配置）\n        # 约定：MLA_AGENT_LIBRARY_DIR 指向包含 agent_library/ 的根目录（例如 ~/mla_v3）\n        user_root = self.agent_library_root or os.environ.get(\"MLA_AGENT_LIBRARY_DIR\", \"\").strip()\n        if not user_root:\n            user_root = str(get_user_data_root())\n        candidates.append(Path(user_root) / \"agent_library\" / agent_system_name)\n\n        # 2) 项目内 config\n        candidates.append(Path(self.config_root) / \"agent_library\" / agent_system_name)\n\n        for p in candidates:\n            if p.exists():\n                return str(p)\n\n        # 默认回退到项目路径（抛错由上层处理）\n        return str(candidates[-1])\n    \n    def _load_general_prompts(self) -> Dict:\n        \"\"\"\n        加载通用提示词配置\n        \n        注意：general_prompts.yaml 现在使用 XML 格式\n        由 ContextBuilder 直接读取，此方法保留为兼容性\n        \"\"\"\n        prompts_file = os.path.join(self.agent_config_dir, \"general_prompts.yaml\")\n        if not os.path.exists(prompts_file):\n            return {}\n        \n        with open(prompts_file, 'r', encoding='utf-8') as f:\n            data = yaml.safe_load(f)\n            # 兼容旧格式\n            return data.get(\"general_prompts\", {})\n    \n    def _load_all_tools(self) -> Dict[str, Dict]:\n        \"\"\"加载所有工具和Agent配置\"\"\"\n        all_tools = {}\n        \n        # 查找所有level配置文件\n        for filename in os.listdir(self.agent_config_dir):\n            if filename.startswith(\"level_\") and filename.endswith(\".yaml\"):\n                filepath = os.path.join(self.agent_config_dir, filename)\n                with open(filepath, 'r', encoding='utf-8') as f:\n                    data = yaml.safe_load(f)\n                    tools = data.get(\"tools\", {})\n                    all_tools.update(tools)\n        \n        return all_tools\n\n    def _inject_framework_default_tools(self):\n        \"\"\"注入框架级默认工具，无需逐个 agent_system 重复声明。\"\"\"\n        self.all_tools.setdefault(\n            \"task_history_search\",\n            {\n                \"level\": 0,\n                \"type\": \"tool_call_agent\",\n                \"name\": \"task_history_search\",\n                \"description\": \"检索当前用户数据根目录下的历史任务数据库。支持 sql 和 semantic 两种模式。sql 模式推荐把 SELECT 语句放在 sql 字段，也支持直接把 SELECT 写进 query 字段；可查询只读视图 task_history。semantic 模式会返回与查询语义最接近的历史 instruction bundle / task summary。\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"keyword\": {\n                            \"type\": \"string\",\n                            \"description\": \"关键词检索文本。适合精确查找文件名、任务关键词、输出中的关键短语。\",\n                        },\n                        \"relevance_query_text\": {\n                            \"type\": \"string\",\n                            \"description\": \"相关性检索文本。只有在 enable_vector_search=true 时才会生效，用于语义匹配历史任务。\",\n                        },\n                        \"start_time_from\": {\n                            \"type\": \"string\",\n                            \"description\": \"可选。历史任务开始时间下界（ISO 时间字符串）。\",\n                        },\n                        \"start_time_to\": {\n                            \"type\": \"string\",\n                            \"description\": \"可选。历史任务开始时间上界（ISO 时间字符串）。\",\n                        },\n                        \"start_round\": {\n                            \"type\": \"integer\",\n                            \"description\": \"可选。从第几条历史任务开始检索，按历史顺序从 1 开始计数。\",\n                        },\n                        \"enable_vector_search\": {\n                            \"type\": \"boolean\",\n                            \"default\": False,\n                            \"description\": \"是否启用向量/语义检索。关闭时 relevance_query_text 会被忽略。\",\n                        },\n                    },\n                    \"required\": [],\n                },\n            },\n        )\n    \n    def get_tool_config(self, tool_name: str) -> Dict:\n        \"\"\"\n        获取指定工具的配置，并处理available_tool_level字段\n        \n        Args:\n            tool_name: 工具名称\n            \n        Returns:\n            工具配置字典\n        \"\"\"\n        if tool_name not in self.all_tools:\n            raise KeyError(f\"工具 {tool_name} 不存在于配置中\")\n        \n        config = self.all_tools[tool_name].copy()\n        config = self._normalize_agent_runtime_config(config)\n        \n        # 处理available_tool_level（特殊情况：judge_agent）\n        if \"available_tool_level\" in config and \"available_tools\" not in config:\n            tool_level = config[\"available_tool_level\"]\n            # 获取该level的所有工具\n            level_tools = self.get_available_tools_by_level(tool_level)\n            config[\"available_tools\"] = level_tools\n            print(f\"✅ 为{tool_name}自动生成工具列表（Level {tool_level}）: {len(level_tools)}个工具\")\n        \n        return config\n\n    def _normalize_agent_runtime_config(self, config: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"兼容旧 agent YAML，并补齐新的运行时字段。\"\"\"\n        normalized = dict(config)\n\n        execution_model = (\n            normalized.get(\"execution_model\")\n            or normalized.get(\"model\")\n            or normalized.get(\"model_type\")\n            or \"\"\n        )\n        if execution_model:\n            normalized[\"execution_model\"] = execution_model\n\n        alias_fields = {\n            \"thinking_model\": [\"thinking_model\"],\n            \"compressor_model\": [\"compressor_model\"],\n            \"image_generation_model\": [\"image_generation_model\", \"figure_model\", \"generate_figure_model\"],\n            \"read_figure_model\": [\"read_figure_model\", \"vision_model\"],\n            \"max_tokens\": [\"max_tokens\"],\n            \"action_window_steps\": [\"action_window_steps\"],\n            \"thinking_interval\": [\"thinking_interval\"],\n            \"thinking_steps\": [\"thinking_steps\", \"thinking_interval\", \"action_window_steps\"],\n            \"thinking_enabled\": [\"thinking_enabled\"],\n            \"no_tool_retry_limit\": [\"no_tool_retry_limit\"],\n        }\n\n        for canonical_name, aliases in alias_fields.items():\n            if normalized.get(canonical_name) not in (None, \"\"):\n                continue\n            for alias in aliases:\n                value = normalized.get(alias)\n                if value not in (None, \"\"):\n                    normalized[canonical_name] = value\n                    break\n\n        return normalized\n    \n    def build_agent_system_prompt(self, agent_config: Dict) -> str:\n        \"\"\"\n        ⚠️ 已废弃：此方法不再使用\n        \n        上下文构建已移至 ContextBuilder.build_context()\n        该方法负责读取 general_prompts.yaml（XML格式）并构建完整上下文\n        \"\"\"\n        # 保留此方法仅为向后兼容\n        return \"\"\n    \n    def get_available_tools_by_level(self, level: int) -> List[str]:\n        \"\"\"\n        获取指定level的所有工具名称\n        \n        Args:\n            level: 工具级别\n            \n        Returns:\n            工具名称列表\n        \"\"\"\n        tools = []\n        for tool_name, tool_config in self.all_tools.items():\n            if tool_config.get(\"level\") == level:\n                tools.append(tool_name)\n        return tools\n\n\nif __name__ == \"__main__\":\n    # 测试配置加载\n    loader = ConfigLoader(\"infiHelper\")\n    print(f\"✅ 成功加载配置系统: {loader.agent_system_name}\")\n    print(f\"📁 配置目录: {loader.agent_config_dir}\")\n    print(f\"🔧 总共加载 {len(loader.all_tools)} 个工具/Agent\")\n    print(f\"\\nLevel 0 工具数量: {len(loader.get_available_tools_by_level(0))}\")\n    print(f\"Level 1 Agent数量: {len(loader.get_available_tools_by_level(1))}\")\n"
  },
  {
    "path": "utils/config_manager.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n配置管理工具\n\"\"\"\n\nimport yaml\nimport json\nfrom pathlib import Path\n\nfrom utils.user_paths import ensure_user_llm_config_exists, get_user_llm_config_path\n\n\ndef get_config_path(config_name: str = \"llm_config\") -> Path:\n    \"\"\"获取配置文件路径（用户目录）。\"\"\"\n    if config_name != \"llm_config\":\n        raise ValueError(f\"暂不支持的配置文件类型: {config_name}\")\n    ensure_user_llm_config_exists()\n    return get_user_llm_config_path()\n\n\ndef show_config(config_name: str = \"llm_config\"):\n    \"\"\"显示配置\"\"\"\n    config_file = get_config_path(config_name)\n    \n    if not config_file.exists():\n        print(f\"❌ 配置文件不存在: {config_file}\")\n        return\n    \n    with open(config_file, 'r', encoding='utf-8') as f:\n        config = yaml.safe_load(f)\n    \n    print(f\"\\n📋 配置文件: {config_file}\")\n    print(f\"{'='*80}\")\n    print(yaml.dump(config, allow_unicode=True, default_flow_style=False))\n    print(f\"{'='*80}\\n\")\n\n\ndef set_config(key: str, value: str, config_name: str = \"llm_config\"):\n    \"\"\"\n    设置配置项\n    \n    Args:\n        key: 配置键，支持点号分隔（如 llm.api_key）\n        value: 配置值\n        config_name: 配置文件名\n    \"\"\"\n    config_file = get_config_path(config_name)\n    \n    if not config_file.exists():\n        print(f\"❌ 配置文件不存在: {config_file}\")\n        return\n    \n    # 读取配置\n    with open(config_file, 'r', encoding='utf-8') as f:\n        config = yaml.safe_load(f) or {}\n    \n    # 解析键路径\n    keys = key.split('.')\n    current = config\n    \n    for k in keys[:-1]:\n        if k not in current:\n            current[k] = {}\n        current = current[k]\n    \n    # 设置值（尝试智能转换类型）\n    final_key = keys[-1]\n    \n    # 尝试转换类型\n    if value.lower() in ['true', 'false']:\n        current[final_key] = value.lower() == 'true'\n    elif value.isdigit():\n        current[final_key] = int(value)\n    elif value.replace('.', '', 1).isdigit():\n        current[final_key] = float(value)\n    elif value.startswith('[') and value.endswith(']'):\n        # 列表格式：尝试作为 JSON 解析\n        try:\n            # 首先尝试作为标准 JSON 数组解析\n            current[final_key] = json.loads(value)\n        except json.JSONDecodeError:\n            # 如果失败，按简单逗号分割处理\n            items = value[1:-1].split(',')\n            current[final_key] = [item.strip().strip('\"').strip(\"'\") for item in items if item.strip()]\n    else:\n        current[final_key] = value\n    \n    # 写回配置\n    with open(config_file, 'w', encoding='utf-8') as f:\n        yaml.dump(config, f, allow_unicode=True, default_flow_style=False, sort_keys=False)\n    \n    print(f\"✅ 配置已更新: {key} = {current[final_key]}\")\n    print(f\"   配置文件: {config_file}\")\n\n\ndef reset_config(config_name: str = \"llm_config\"):\n    \"\"\"重置配置（显示路径，让用户手动编辑）\"\"\"\n    config_file = get_config_path(config_name)\n    print(f\"\\n📄 配置文件位置: {config_file}\")\n    print(f\"💡 您可以直接编辑此文件，或使用:\")\n    print(f\"   mla-agent --config-set KEY VALUE\")\n    print(f\"\\n常用配置:\")\n    print(f\"   --config-set api_key \\\"YOUR_KEY\\\"\")\n    print(f\"   --config-set base_url \\\"https://api.openai.com/v1\\\"\")\n    print(f\"   --config-set models \\\"[gpt-4o,gpt-4o-mini]\\\"\")\n    print()\n\n\nif __name__ == \"__main__\":\n    # 测试\n    print(\"查看配置:\")\n    show_config()\n    \n    print(\"\\n设置 API key:\")\n    set_config(\"api_key\", \"test-key-123\")\n    \n    print(\"\\n再次查看:\")\n    show_config()\n\n"
  },
  {
    "path": "utils/context_hooks.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom __future__ import annotations\n\nimport importlib\nimport importlib.util\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import Any, Dict, List\n\n\ndef _load_callback(callback_spec: str):\n    callback_spec = str(callback_spec or \"\").strip()\n    if \":\" not in callback_spec:\n        raise ValueError(f\"invalid callback spec: {callback_spec}\")\n    module_spec, func_name = callback_spec.rsplit(\":\", 1)\n    module_spec = module_spec.strip()\n    func_name = func_name.strip()\n    if module_spec.endswith(\".py\") or module_spec.startswith(\"/\"):\n        path = Path(module_spec).expanduser().resolve()\n        module_name = f\"context_hook_{path.stem}_{abs(hash(str(path)))}\"\n        spec = importlib.util.spec_from_file_location(module_name, path)\n        if spec is None or spec.loader is None:\n            raise ImportError(f\"cannot load context hook module: {path}\")\n        module = importlib.util.module_from_spec(spec)\n        spec.loader.exec_module(module)\n    else:\n        module = importlib.import_module(module_spec)\n    callback = getattr(module, func_name, None)\n    if callback is None or not callable(callback):\n        raise AttributeError(f\"callback not found: {callback_spec}\")\n    return callback\n\n\ndef _load_context_hooks() -> List[Dict[str, Any]]:\n    raw = os.environ.get(\"MLA_CONTEXT_HOOKS_JSON\", \"\").strip()\n    if not raw:\n        return []\n    try:\n        payload = json.loads(raw)\n    except Exception:\n        return []\n    return payload if isinstance(payload, list) else []\n\n\ndef apply_context_hooks(\n    *,\n    stage: str,\n    task_id: str,\n    agent_id: str,\n    agent_name: str,\n    task_input: str,\n    context_data: Dict[str, Any],\n    context_text: str,\n) -> str:\n    updated_context = str(context_text or \"\")\n    for hook in _load_context_hooks():\n        when = str(hook.get(\"when\") or \"after_build\").strip()\n        if when not in {stage, \"both\"}:\n            continue\n        callback_spec = str(hook.get(\"callback\") or \"\").strip()\n        if not callback_spec:\n            continue\n        try:\n            callback = _load_callback(callback_spec)\n            payload = {\n                \"hook_name\": str(hook.get(\"name\") or \"\"),\n                \"stage\": stage,\n                \"task_id\": task_id,\n                \"agent_id\": agent_id,\n                \"agent_name\": agent_name,\n                \"task_input\": task_input,\n                \"context_data\": context_data,\n                \"context_text\": updated_context,\n            }\n            result = callback(payload)\n            if isinstance(result, str):\n                updated_context = result\n            elif isinstance(result, dict):\n                if \"context_text\" in result and result[\"context_text\"] is not None:\n                    updated_context = str(result[\"context_text\"])\n        except Exception:\n            continue\n    return updated_context\n"
  },
  {
    "path": "utils/conversation_storage.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n对话历史存储 - 简化版\n只保存action_history，不保存传统的user/assistant对话\n\"\"\"\n\nimport json\nimport hashlib\nfrom pathlib import Path\nfrom typing import Dict, List\nfrom datetime import datetime\n\nfrom utils.user_paths import get_user_conversations_dir\n\n\nclass ConversationStorage:\n    \"\"\"对话历史存储器\"\"\"\n    \n    def __init__(self, task_id: str = None):\n        \"\"\"初始化存储器 - 使用用户主目录（跨平台）\"\"\"\n        self.conversations_dir = get_user_conversations_dir()\n        self.conversations_dir.mkdir(parents=True, exist_ok=True)\n        self.task_id = task_id\n    \n    def _generate_filename(self, task_id: str, agent_id: str) -> str:\n        \"\"\"生成对话文件名：hash + 最后文件夹名 + agent_id\"\"\"\n        from pathlib import Path\n        import hashlib\n        \n        task_hash = hashlib.md5(task_id.encode()).hexdigest()[:8]\n        # 跨平台路径处理：检查是否是路径（包含/或\\）\n        import os\n        task_folder = Path(task_id).name if (os.sep in task_id or '/' in task_id or '\\\\' in task_id) else task_id\n        task_name = f\"{task_hash}_{task_folder}\"\n        \n        return str(self.conversations_dir / f\"{task_name}_{agent_id}_actions.json\")\n    \n    def save_actions(self, task_id: str, agent_id: str, agent_name: str, \n                    task_input: str, action_history: List[Dict], current_turn: int,\n                    latest_thinking: str = \"\", first_thinking_done: bool = False,\n                    tool_call_counter: int = 0, system_prompt: str = \"\",\n                    action_history_fact: List[Dict] = None,\n                    pending_tools: List[Dict] = None,\n                    llm_turn_counter: int = 0):\n        \"\"\"\n        保存动作历史和完整状态\n        \n        Args:\n            task_id: 任务ID\n            agent_id: Agent ID\n            agent_name: Agent名称\n            task_input: 任务输入\n            action_history: 动作历史列表（含新字段：_turn, tool_call_id, assistant_content, \n                           _has_image, _image_base64 等）\n            current_turn: 当前执行轮次\n            latest_thinking: 最新的thinking内容\n            first_thinking_done: 是否已完成首次thinking\n            tool_call_counter: 工具调用计数\n            system_prompt: 完整的system_prompt（包含XML上下文，用于调试参考）\n            action_history_fact: 完整动作轨迹（不含 base64 图片数据）\n            pending_tools: 待执行的工具列表\n            llm_turn_counter: LLM 调用轮次计数器（用于消息分组）\n        \"\"\"\n        try:\n            filepath = self._generate_filename(task_id, agent_id)\n            \n            data = {\n                \"task_id\": task_id,\n                \"agent_id\": agent_id,\n                \"agent_name\": agent_name,\n                \"task_input\": task_input,\n                \"current_turn\": current_turn,\n                \"action_history\": action_history,  # 含 base64 图片数据（用于 messages 重建）\n                \"action_history_fact\": action_history_fact if action_history_fact else action_history,  # 完整轨迹（不含 base64）\n                \"pending_tools\": pending_tools if pending_tools else [],\n                \"latest_thinking\": latest_thinking,\n                \"first_thinking_done\": first_thinking_done,\n                \"tool_call_counter\": tool_call_counter,\n                \"llm_turn_counter\": llm_turn_counter,\n                \"system_prompt\": system_prompt,\n                \"last_updated\": datetime.now().isoformat()\n            }\n            \n            with open(filepath, 'w', encoding='utf-8') as f:\n                json.dump(data, f, indent=2, ensure_ascii=False)\n        \n        except Exception as e:\n            print(f\"⚠️ 保存对话历史失败: {e}\")\n    \n    def load_actions(self, task_id: str, agent_id: str) -> Dict:\n        \"\"\"\n        加载动作历史\n        \n        Args:\n            task_id: 任务ID\n            agent_id: Agent ID\n            \n        Returns:\n            动作历史数据，如果不存在则返回None\n        \"\"\"\n        try:\n            filepath = self._generate_filename(task_id, agent_id)\n            \n            if not Path(filepath).exists():\n                return None\n            \n            with open(filepath, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n            \n            print(f\"📂 已加载动作历史: 第{data.get('current_turn', 0)}轮, {len(data.get('action_history', []))}个动作\")\n            return data\n        \n        except Exception as e:\n            print(f\"⚠️ 加载对话历史失败: {e}\")\n            return None\n\n\nif __name__ == \"__main__\":\n    # 测试存储器\n    storage = ConversationStorage()\n    \n    # 测试保存\n    storage.save_actions(\n        task_id=\"test\",\n        agent_id=\"agent_123\",\n        agent_name=\"test_agent\",\n        task_input=\"测试任务\",\n        action_history=[\n            {\"tool_name\": \"file_read\", \"arguments\": {}, \"result\": {}}\n        ],\n        current_turn=1\n    )\n    \n    # 测试加载\n    data = storage.load_actions(\"test\", \"agent_123\")\n    print(f\"✅ 加载的数据: {data}\")\n\n"
  },
  {
    "path": "utils/event_emitter.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nJSONL 事件输出工具 - 用于 VS Code 插件集成\n\"\"\"\n\nimport sys\nimport json\nimport time\nfrom typing import Dict, Any, Optional, List\n\n\nclass EventEmitter:\n    \"\"\"JSONL 事件发射器\"\"\"\n    \n    def __init__(self, enabled: bool = False):\n        \"\"\"\n        Args:\n            enabled: 是否启用 JSONL 输出模式\n        \"\"\"\n        self.enabled = enabled\n        self.call_id = None\n        self.start_time = None\n    \n    def emit(self, event: Dict[str, Any]):\n        \"\"\"发射一个事件（JSONL格式）\"\"\"\n        if not self.enabled:\n            return\n        \n        # 直接写到原始 stdout（不受重定向影响）\n        if hasattr(sys, 'stdout_orig'):\n            sys.stdout_orig.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n            sys.stdout_orig.flush()\n        else:\n            sys.stdout.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n            sys.stdout.flush()\n    \n    def start(self, call_id: str, project: str, agent: str, task: str):\n        \"\"\"任务开始\"\"\"\n        self.call_id = call_id\n        self.start_time = time.time()\n        self.emit({\n            \"type\": \"start\",\n            \"call_id\": call_id,\n            \"project\": project,\n            \"agent\": agent,\n            \"task\": task\n        })\n    \n    def token(self, text: str):\n        \"\"\"流式文本输出\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"token\",\n            \"call_id\": self.call_id,\n            \"text\": text\n        })\n    \n    def progress(self, phase: str, pct: int):\n        \"\"\"进度更新\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"progress\",\n            \"call_id\": self.call_id,\n            \"phase\": phase,\n            \"pct\": pct\n        })\n    \n    def notice(self, text: str):\n        \"\"\"通知\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"notice\",\n            \"call_id\": self.call_id,\n            \"text\": text\n        })\n    \n    def warn(self, text: str):\n        \"\"\"警告\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"warn\",\n            \"call_id\": self.call_id,\n            \"text\": text\n        })\n    \n    def error(self, text: str):\n        \"\"\"错误\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"error\",\n            \"call_id\": self.call_id,\n            \"text\": text\n        })\n    \n    def artifact(self, kind: str, path: Optional[str] = None, \n                summary: Optional[str] = None, preview: Optional[str] = None):\n        \"\"\"产物\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"artifact\",\n            \"call_id\": self.call_id,\n            \"kind\": kind,\n            \"path\": path,\n            \"summary\": summary,\n            \"preview\": preview\n        })\n    \n    def human_in_loop(self, hil_id: str, title: str, message: str,\n                     ui: Dict[str, Any], timeout_sec: int = 1800,\n                     resume_hint: Optional[str] = None):\n        \"\"\"人机交互\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"human_in_loop\",\n            \"call_id\": self.call_id,\n            \"hil_id\": hil_id,\n            \"title\": title,\n            \"message\": message,\n            \"ui\": ui,\n            \"timeout_sec\": timeout_sec,\n            \"resume_hint\": resume_hint\n        })\n    \n    def result(self, ok: bool, summary: str, artifacts: Optional[List[str]] = None):\n        \"\"\"最终结果\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"result\",\n            \"call_id\": self.call_id,\n            \"ok\": ok,\n            \"summary\": summary,\n            \"artifacts\": artifacts or []\n        })\n    \n    def tool_call(self, tool_name: str, parameters: Dict[str, Any]):\n        \"\"\"工具调用事件\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"tool_call\",\n            \"call_id\": self.call_id,\n            \"tool_name\": tool_name,\n            \"parameters\": parameters\n        })\n    \n    def agent_call(self, agent_name: str, parameters: Dict[str, Any]):\n        \"\"\"子 Agent 调用事件\"\"\"\n        if not self.call_id:\n            return\n        self.emit({\n            \"type\": \"agent_call\",\n            \"call_id\": self.call_id,\n            \"agent_name\": agent_name,\n            \"parameters\": parameters\n        })\n    \n    def end(self, status: str, extra: Optional[Dict] = None):\n        \"\"\"任务结束\"\"\"\n        if not self.call_id:\n            return\n        \n        duration_ms = int((time.time() - self.start_time) * 1000) if self.start_time else 0\n        \n        event = {\n            \"type\": \"end\",\n            \"call_id\": self.call_id,\n            \"status\": status,\n            \"duration_ms\": duration_ms\n        }\n        \n        if extra:\n            event.update(extra)\n        \n        self.emit(event)\n\n\n# 全局实例\n_event_emitter = EventEmitter(enabled=False)\n\n\ndef init_event_emitter(enabled: bool = False):\n    \"\"\"初始化全局事件发射器\"\"\"\n    global _event_emitter\n    _event_emitter = EventEmitter(enabled=enabled)\n    return _event_emitter\n\n\ndef get_event_emitter() -> EventEmitter:\n    \"\"\"获取全局事件发射器\"\"\"\n    return _event_emitter\n\n"
  },
  {
    "path": "utils/llm_config_builder.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\n结构化模型配置 -> 兼容 llm_config.yaml 的构建器。\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom copy import deepcopy\nfrom typing import Any, Dict, Optional\n\n\nMODEL_SLOT_TO_CONFIG_KEY = {\n    \"main\": \"models\",\n    \"execution\": \"models\",\n    \"figure\": \"figure_models\",\n    \"image_generation\": \"figure_models\",\n    \"compressor\": \"compressor_models\",\n    \"read_figure\": \"read_figure_models\",\n    \"thinking\": \"thinking_models\",\n}\n\n\ndef normalize_provider_kind(value: Optional[str]) -> str:\n    raw = str(value or \"\").strip().lower().replace(\"-\", \"_\")\n    aliases = {\n        \"openai\": \"openai_official\",\n        \"openai_official\": \"openai_official\",\n        \"openai_compatible\": \"openai_compatible\",\n        \"openrouter\": \"openrouter\",\n        \"google\": \"google_official\",\n        \"google_official\": \"google_official\",\n        \"anthropic\": \"anthropic_official\",\n        \"anthropic_official\": \"anthropic_official\",\n        \"local\": \"local_openai_compatible\",\n        \"local_openai_compatible\": \"local_openai_compatible\",\n    }\n    return aliases.get(raw, raw or \"openai_compatible\")\n\n\ndef normalize_model_name(provider_kind: str, model_name: str) -> str:\n    provider_kind = normalize_provider_kind(provider_kind)\n    raw_name = str(model_name or \"\").strip()\n    if not raw_name:\n        return \"\"\n\n    prefixes = (\"openrouter/\", \"openai/\", \"google/\", \"anthropic/\")\n    if raw_name.startswith(prefixes):\n        return raw_name\n\n    prefix_map = {\n        \"openrouter\": \"openrouter/\",\n        \"openai_compatible\": \"openai/\",\n        \"openai_official\": \"openai/\",\n        \"google_official\": \"google/\",\n        \"anthropic_official\": \"anthropic/\",\n        \"local_openai_compatible\": \"openai/\",\n    }\n    prefix = prefix_map.get(provider_kind, \"openai/\")\n    return f\"{prefix}{raw_name}\"\n\n\ndef build_model_entry(profile: Dict[str, Any]) -> Dict[str, Any] | str:\n    provider_kind = normalize_provider_kind(profile.get(\"provider\"))\n    model_name = normalize_model_name(provider_kind, profile.get(\"model\") or profile.get(\"name\") or \"\")\n    if not model_name:\n        return \"\"\n\n    entry: Dict[str, Any] = {\"name\": model_name}\n    base_url = str(profile.get(\"base_url\") or \"\").strip()\n    api_key = str(profile.get(\"api_key\") or \"\").strip()\n    tool_choice = str(profile.get(\"tool_choice\") or \"\").strip().lower()\n\n    if base_url:\n        entry[\"base_url\"] = base_url\n    if api_key:\n        entry[\"api_key\"] = api_key\n    if tool_choice in {\"required\", \"auto\", \"none\"}:\n        entry[\"tool_choice\"] = tool_choice\n\n    extra_provider = profile.get(\"provider_options\")\n    if isinstance(extra_provider, dict) and extra_provider:\n        entry[\"provider\"] = deepcopy(extra_provider)\n\n    if set(entry.keys()) == {\"name\"}:\n        return model_name\n    return entry\n\n\ndef build_llm_config_from_profiles(\n    payload: Dict[str, Any],\n    *,\n    base_config: Optional[Dict[str, Any]] = None,\n) -> Dict[str, Any]:\n    config = deepcopy(base_config or {})\n    payload = deepcopy(payload or {})\n\n    scalar_keys = [\n        \"temperature\",\n        \"max_tokens\",\n        \"max_context_window\",\n        \"timeout\",\n        \"stream_timeout\",\n        \"first_chunk_timeout\",\n        \"multimodal\",\n        \"compressor_multimodal\",\n    ]\n    for key in scalar_keys:\n        if key in payload and payload[key] is not None:\n            config[key] = payload[key]\n\n    config.setdefault(\"base_url\", \"\")\n    config.setdefault(\"api_key\", \"\")\n\n    mode = str(payload.get(\"mode\") or \"unified\").strip().lower()\n    use_unified = mode != \"split\"\n\n    shared_profile = payload.get(\"unified\") if isinstance(payload.get(\"unified\"), dict) else None\n\n    slot_sources = {\n        \"main\": payload.get(\"main\"),\n        \"figure\": payload.get(\"figure\"),\n        \"compressor\": payload.get(\"compressor\"),\n        \"read_figure\": payload.get(\"read_figure\"),\n        \"thinking\": payload.get(\"thinking\"),\n    }\n\n    for slot_name, config_key in MODEL_SLOT_TO_CONFIG_KEY.items():\n        if slot_name not in {\"main\", \"figure\", \"compressor\", \"read_figure\", \"thinking\"}:\n            continue\n        slot_profile = shared_profile if use_unified else slot_sources.get(slot_name)\n        if not isinstance(slot_profile, dict):\n            continue\n        entry = build_model_entry(slot_profile)\n        if entry:\n            config[config_key] = [entry]\n\n    return config\n"
  },
  {
    "path": "utils/mcp_manager.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nMCP 运行时管理。\n\n说明：\n- MCP server 本身不是一个本地工具类\n- 但 MCP server 暴露出来的 tools 需要以 OpenAI tool schema 的形式提供给模型\n- ToolExecutor 在运行时根据 tool_name 路由到 MCP client 执行\n\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport json\nimport re\nimport traceback\nfrom contextlib import asynccontextmanager\nfrom datetime import timedelta\nfrom typing import Any, Dict, List, Tuple\n\nfrom utils.user_paths import get_mcp_settings\n\nHAS_MCP = True\nMCP_IMPORT_ERROR = \"\"\ntry:\n    from mcp import ClientSession, StdioServerParameters\n    from mcp.client.sse import sse_client\n    from mcp.client.stdio import stdio_client\n    from mcp.client.streamable_http import streamablehttp_client\nexcept Exception as exc:  # pragma: no cover - depends on interpreter/platform\n    HAS_MCP = False\n    MCP_IMPORT_ERROR = str(exc)\n\n\ndef _sanitize_name(name: str) -> str:\n    s = re.sub(r\"[^a-zA-Z0-9_]+\", \"_\", str(name or \"\").strip())\n    s = s.strip(\"_\")\n    return s or \"mcp\"\n\n\ndef _normalize_server_entry(raw: Any) -> Dict[str, Any] | None:\n    if isinstance(raw, str):\n        raw = raw.strip()\n        if not raw:\n            return None\n        return {\n            \"name\": _sanitize_name(raw.rsplit(\"/\", 1)[-1] or \"server\"),\n            \"transport\": \"streamable_http\",\n            \"url\": raw,\n            \"enabled\": True,\n        }\n\n    if not isinstance(raw, dict):\n        return None\n\n    if raw.get(\"enabled\", True) is False:\n        return None\n\n    transport = str(raw.get(\"transport\") or (\"stdio\" if raw.get(\"command\") else \"streamable_http\")).strip().lower()\n    name = _sanitize_name(raw.get(\"name\") or raw.get(\"server_name\") or raw.get(\"url\") or raw.get(\"command\") or \"server\")\n\n    entry: Dict[str, Any] = {\n        \"name\": name,\n        \"transport\": transport,\n        \"enabled\": True,\n        \"headers\": raw.get(\"headers\") if isinstance(raw.get(\"headers\"), dict) else {},\n        \"timeout\": raw.get(\"timeout\", 30),\n        \"sse_read_timeout\": raw.get(\"sse_read_timeout\", 300),\n    }\n    if transport in {\"streamable_http\", \"sse\"}:\n        entry[\"url\"] = str(raw.get(\"url\") or \"\").strip()\n        if not entry[\"url\"]:\n            return None\n    elif transport == \"stdio\":\n        entry[\"command\"] = str(raw.get(\"command\") or \"\").strip()\n        entry[\"args\"] = [str(x) for x in (raw.get(\"args\") or [])]\n        entry[\"env\"] = {str(k): str(v) for k, v in (raw.get(\"env\") or {}).items()} if isinstance(raw.get(\"env\"), dict) else None\n        entry[\"cwd\"] = raw.get(\"cwd\")\n        if not entry[\"command\"]:\n            return None\n    else:\n        return None\n    return entry\n\n\ndef get_mcp_servers() -> List[Dict[str, Any]]:\n    settings = get_mcp_settings()\n    servers = settings.get(\"servers\", []) if isinstance(settings, dict) else []\n    if not isinstance(servers, list):\n        return []\n    out = []\n    for item in servers:\n        normalized = _normalize_server_entry(item)\n        if normalized:\n            out.append(normalized)\n    return out\n\n\n@asynccontextmanager\nasync def _open_session(server: Dict[str, Any]):\n    if not HAS_MCP:\n        raise RuntimeError(f\"MCP Python client is unavailable: {MCP_IMPORT_ERROR}\")\n    transport = server[\"transport\"]\n    if transport == \"stdio\":\n        params = StdioServerParameters(\n            command=server[\"command\"],\n            args=server.get(\"args\", []),\n            env=server.get(\"env\"),\n            cwd=server.get(\"cwd\"),\n        )\n        async with stdio_client(params) as (read, write):\n            async with ClientSession(read, write, read_timeout_seconds=timedelta(seconds=float(server.get(\"timeout\", 30)))) as session:\n                await session.initialize()\n                yield session\n        return\n\n    if transport == \"sse\":\n        async with sse_client(\n            server[\"url\"],\n            headers=server.get(\"headers\") or None,\n            timeout=float(server.get(\"timeout\", 30)),\n            sse_read_timeout=float(server.get(\"sse_read_timeout\", 300)),\n        ) as (read, write):\n            async with ClientSession(read, write, read_timeout_seconds=timedelta(seconds=float(server.get(\"timeout\", 30)))) as session:\n                await session.initialize()\n                yield session\n        return\n\n    async with streamablehttp_client(\n        server[\"url\"],\n        headers=server.get(\"headers\") or None,\n        timeout=float(server.get(\"timeout\", 30)),\n        sse_read_timeout=float(server.get(\"sse_read_timeout\", 300)),\n    ) as (read, write, _get_session_id):\n        async with ClientSession(read, write, read_timeout_seconds=timedelta(seconds=float(server.get(\"timeout\", 30)))) as session:\n            await session.initialize()\n            yield session\n\n\ndef _dump_model(obj: Any) -> Any:\n    if hasattr(obj, \"model_dump\"):\n        try:\n            return obj.model_dump()\n        except Exception:\n            pass\n    if isinstance(obj, list):\n        return [_dump_model(x) for x in obj]\n    if isinstance(obj, dict):\n        return {k: _dump_model(v) for k, v in obj.items()}\n    return obj\n\n\ndef _format_tool_contents(contents: List[Any]) -> str:\n    parts = []\n    for item in contents or []:\n        data = _dump_model(item)\n        if isinstance(data, dict):\n            if \"text\" in data and data[\"text\"] is not None:\n                parts.append(str(data[\"text\"]))\n            else:\n                parts.append(json.dumps(data, ensure_ascii=False, indent=2))\n        else:\n            parts.append(str(data))\n    return \"\\n\".join(p for p in parts if p).strip()\n\n\n_mcp_tool_cache: Dict[str, Dict[str, Any]] | None = None\n_mcp_failures_cache: List[Dict[str, Any]] | None = None\n\n\nasync def _discover_mcp_tools_async() -> Tuple[Dict[str, Dict[str, Any]], List[Dict[str, Any]]]:\n    tools: Dict[str, Dict[str, Any]] = {}\n    failures: List[Dict[str, Any]] = []\n    if not HAS_MCP:\n        if get_mcp_servers():\n            failures.append({\n                \"server\": \"mcp_runtime\",\n                \"error\": f\"MCP Python client is unavailable: {MCP_IMPORT_ERROR}\",\n                \"traceback\": \"\",\n            })\n        return tools, failures\n    for server in get_mcp_servers():\n        try:\n            async with _open_session(server) as session:\n                result = await session.list_tools()\n                for tool in getattr(result, \"tools\", []) or []:\n                    raw_name = getattr(tool, \"name\", \"\") or \"\"\n                    synthetic_name = f\"mcp__{server['name']}__{_sanitize_name(raw_name)}\"\n                    tools[synthetic_name] = {\n                        \"type\": \"tool_call_agent\",\n                        \"name\": synthetic_name,\n                        \"description\": f\"[MCP:{server['name']}] {getattr(tool, 'description', '') or raw_name}\",\n                        \"parameters\": getattr(tool, \"inputSchema\", None) or {\"type\": \"object\", \"properties\": {}},\n                        \"_mcp\": {\n                            \"server\": server,\n                            \"server_name\": server[\"name\"],\n                            \"tool_name\": raw_name,\n                        }\n                    }\n        except Exception as exc:\n            failures.append({\n                \"server\": server.get(\"name\", \"unknown\"),\n                \"error\": str(exc),\n                \"traceback\": traceback.format_exc(),\n            })\n    return tools, failures\n\n\ndef reload_mcp_tools() -> Tuple[Dict[str, Dict[str, Any]], List[Dict[str, Any]]]:\n    global _mcp_tool_cache, _mcp_failures_cache\n    _mcp_tool_cache, _mcp_failures_cache = asyncio.run(_discover_mcp_tools_async())\n    return _mcp_tool_cache, _mcp_failures_cache\n\n\ndef get_mcp_tools(force_reload: bool = False) -> Dict[str, Dict[str, Any]]:\n    global _mcp_tool_cache\n    if force_reload or _mcp_tool_cache is None:\n        reload_mcp_tools()\n    return dict(_mcp_tool_cache or {})\n\n\ndef get_mcp_failures(force_reload: bool = False) -> List[Dict[str, Any]]:\n    global _mcp_failures_cache\n    if force_reload or _mcp_failures_cache is None:\n        reload_mcp_tools()\n    return list(_mcp_failures_cache or [])\n\n\nasync def _call_mcp_tool_async(tool_config: Dict[str, Any], arguments: Dict[str, Any]) -> Dict[str, Any]:\n    mcp_meta = tool_config.get(\"_mcp\", {}) if isinstance(tool_config, dict) else {}\n    server = mcp_meta.get(\"server\")\n    tool_name = mcp_meta.get(\"tool_name\")\n    if not server or not tool_name:\n        raise ValueError(\"无效的 MCP 工具配置\")\n\n    async with _open_session(server) as session:\n        result = await session.call_tool(tool_name, arguments=arguments)\n        contents = getattr(result, \"content\", []) or []\n        is_error = bool(getattr(result, \"isError\", False))\n        output_text = _format_tool_contents(contents)\n        return {\n            \"status\": \"error\" if is_error else \"success\",\n            \"output\": output_text,\n            \"error\": output_text if is_error else \"\",\n            \"_mcp_server\": server.get(\"name\"),\n            \"_mcp_tool_name\": tool_name,\n            \"_mcp_raw\": _dump_model(result),\n        }\n\n\ndef call_mcp_tool(tool_config: Dict[str, Any], arguments: Dict[str, Any]) -> Dict[str, Any]:\n    return asyncio.run(_call_mcp_tool_async(tool_config, arguments))\n"
  },
  {
    "path": "utils/runtime_control.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\n运行时控制信号。\n\n目前用于：\n- 外部 fresh 请求（支持按 task_id 定向）\n- 运行中 task 注册（支持跨进程查询某个 task 是否仍在运行）\n\"\"\"\n\nfrom __future__ import annotations\n\nimport hashlib\nimport json\nimport os\nimport threading\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import Dict, Optional\n\nfrom utils.user_paths import get_user_runtime_dir\n\n_lock = threading.Lock()\n_local_task_refcounts: Dict[str, int] = {}\n\n\ndef _runtime_root() -> Path:\n    root = get_user_runtime_dir()\n    root.mkdir(parents=True, exist_ok=True)\n    return root\n\n\ndef _fresh_request_dir() -> Path:\n    path = _runtime_root() / \"fresh_requests\"\n    path.mkdir(parents=True, exist_ok=True)\n    return path\n\n\ndef _running_task_dir() -> Path:\n    path = _runtime_root() / \"running_tasks\"\n    path.mkdir(parents=True, exist_ok=True)\n    return path\n\n\ndef _task_key(task_id: str) -> str:\n    task_id = str(task_id or \"\").strip()\n    task_hash = hashlib.md5(task_id.encode(\"utf-8\")).hexdigest()[:8]\n    task_name = Path(task_id).name or \"task\"\n    return f\"{task_hash}_{task_name}\"\n\n\ndef _fresh_request_file(task_id: Optional[str]) -> Path:\n    if task_id:\n        return _fresh_request_dir() / f\"{_task_key(task_id)}.json\"\n    return _fresh_request_dir() / \"_broadcast.json\"\n\n\ndef _running_task_file(task_id: str) -> Path:\n    return _running_task_dir() / f\"{_task_key(task_id)}.json\"\n\n\ndef _write_json_atomic(path: Path, payload: Dict):\n    tmp = path.with_suffix(path.suffix + f\".{os.getpid()}.tmp\")\n    with open(tmp, \"w\", encoding=\"utf-8\") as f:\n        json.dump(payload, f, indent=2, ensure_ascii=False)\n    os.replace(tmp, path)\n\n\ndef _read_json(path: Path) -> Optional[Dict]:\n    if not path.exists():\n        return None\n    try:\n        with open(path, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n        return data if isinstance(data, dict) else None\n    except Exception:\n        return None\n\n\ndef _is_pid_alive(pid: int) -> bool:\n    if pid <= 0:\n        return False\n    try:\n        os.kill(pid, 0)\n        return True\n    except ProcessLookupError:\n        return False\n    except PermissionError:\n        return True\n    except Exception:\n        return False\n\n\ndef request_fresh(reason: str = \"\", task_id: Optional[str] = None):\n    task_id = str(task_id or \"\").strip() or None\n    payload = {\n        \"reason\": str(reason or \"\").strip() or \"external fresh request\",\n        \"task_id\": task_id,\n        \"requested_at\": datetime.now().isoformat(),\n        \"requested_pid\": os.getpid(),\n    }\n    with _lock:\n        _write_json_atomic(_fresh_request_file(task_id), payload)\n\n\ndef pop_fresh_request(task_id: str) -> Optional[str]:\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return None\n\n    with _lock:\n        for path in (_fresh_request_file(task_id), _fresh_request_file(None)):\n            data = _read_json(path)\n            if not data:\n                continue\n            try:\n                path.unlink()\n            except FileNotFoundError:\n                pass\n            return str(data.get(\"reason\") or \"\").strip() or \"external fresh request\"\n    return None\n\n\ndef register_running_task(task_id: str, agent_name: str, user_input: str, agent_system: str):\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return\n\n    with _lock:\n        refcount = _local_task_refcounts.get(task_id, 0) + 1\n        _local_task_refcounts[task_id] = refcount\n        if refcount > 1:\n            return\n\n        payload = {\n            \"task_id\": task_id,\n            \"agent_name\": str(agent_name or \"\").strip(),\n            \"user_input\": str(user_input or \"\").strip(),\n            \"agent_system\": str(agent_system or \"\").strip(),\n            \"pid\": os.getpid(),\n            \"registered_at\": datetime.now().isoformat(),\n        }\n        _write_json_atomic(_running_task_file(task_id), payload)\n\n\ndef unregister_running_task(task_id: str):\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return\n\n    with _lock:\n        current = _local_task_refcounts.get(task_id, 0)\n        if current > 1:\n            _local_task_refcounts[task_id] = current - 1\n            return\n        _local_task_refcounts.pop(task_id, None)\n\n        path = _running_task_file(task_id)\n        data = _read_json(path)\n        if not data:\n            return\n        if int(data.get(\"pid\") or 0) != os.getpid():\n            return\n        try:\n            path.unlink()\n        except FileNotFoundError:\n            pass\n\n\ndef get_running_task(task_id: str) -> Optional[Dict]:\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return None\n\n    with _lock:\n        path = _running_task_file(task_id)\n        data = _read_json(path)\n        if not data:\n            return None\n\n        pid = int(data.get(\"pid\") or 0)\n        if _is_pid_alive(pid):\n            return data\n\n        try:\n            path.unlink()\n        except FileNotFoundError:\n            pass\n        return None\n\n\ndef is_task_running(task_id: str) -> bool:\n    return get_running_task(task_id) is not None\n"
  },
  {
    "path": "utils/skill_loader.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nSkill 加载器 - 遵循 Agent Skills 开放标准 (agentskills.io)\n\n职责：\n1. 扫描用户主 skills 目录发现所有 skills\n2. 解析 SKILL.md frontmatter（name + description）\n3. 生成 <available_skills> XML 片段注入 system prompt\n\"\"\"\n\nimport yaml\nimport json\nimport os\nfrom pathlib import Path\nfrom typing import List, Dict, Optional\n\nfrom utils.user_paths import get_user_skills_library_root\n\n\nclass SkillLoader:\n    \"\"\"Skill 加载器\"\"\"\n    \n    def __init__(self, skills_library_path: str = None):\n        \"\"\"\n        初始化\n        \n        Args:\n            skills_library_path: skills 仓库路径，默认 ~/.agent/skills\n        \"\"\"\n        if skills_library_path:\n            self.skills_library = Path(skills_library_path).expanduser().resolve()\n        else:\n            self.skills_library = get_user_skills_library_root()\n        \n        # 确保目录存在\n        self.skills_library.mkdir(parents=True, exist_ok=True)\n        \n        # 缓存已解析的 skill 元数据\n        self._metadata_cache: Optional[List[Dict]] = None\n    \n    def discover_skills(self) -> List[Dict]:\n        \"\"\"\n        扫描 skills 主目录，解析所有 SKILL.md 的 frontmatter\n        \n        Returns:\n            [{name, description, path, license?, compatibility?}, ...] 列表\n        \"\"\"\n        if self._metadata_cache is not None:\n            return self._metadata_cache\n        \n        skills = []\n        \n        if not self.skills_library.exists():\n            self._metadata_cache = skills\n            return skills\n        \n        # 扫描一级子目录\n        for skill_dir in sorted(self.skills_library.iterdir()):\n            if not skill_dir.is_dir():\n                continue\n            \n            skill_md = skill_dir / \"SKILL.md\"\n            if not skill_md.exists():\n                continue\n            \n            metadata = self._parse_frontmatter(skill_md)\n            if metadata:\n                metadata[\"path\"] = str(skill_dir)\n                metadata[\"skill_md_path\"] = str(skill_md)\n                skills.append(metadata)\n        \n        self._metadata_cache = skills\n        return skills\n    \n    def _parse_frontmatter(self, skill_md_path: Path) -> Optional[Dict]:\n        \"\"\"\n        解析 SKILL.md 的 YAML frontmatter\n        \n        Args:\n            skill_md_path: SKILL.md 文件路径\n            \n        Returns:\n            {name, description, ...} 或 None（解析失败时）\n        \"\"\"\n        try:\n            content = skill_md_path.read_text(encoding='utf-8')\n            \n            # 提取 YAML frontmatter（--- 包裹）\n            if not content.startswith('---'):\n                return None\n            \n            # 找到第二个 ---\n            end_idx = content.index('---', 3)\n            frontmatter_str = content[3:end_idx].strip()\n            \n            frontmatter = yaml.safe_load(frontmatter_str)\n            if not isinstance(frontmatter, dict):\n                return None\n            \n            # 验证必需字段\n            name = frontmatter.get(\"name\")\n            description = frontmatter.get(\"description\")\n            \n            if not name or not description:\n                return None\n            \n            result = {\n                \"name\": name,\n                \"description\": description\n            }\n            \n            # 可选字段\n            if frontmatter.get(\"license\"):\n                result[\"license\"] = frontmatter[\"license\"]\n            if frontmatter.get(\"compatibility\"):\n                result[\"compatibility\"] = frontmatter[\"compatibility\"]\n            \n            return result\n        \n        except Exception:\n            return None\n    \n    def build_available_skills_xml(self, visible_skill_names: Optional[List[str]] = None) -> str:\n        \"\"\"\n        生成 <available_skills> XML 片段，用于注入 system prompt\n        \n        遵循官方推荐格式：每个 skill ~100 tokens\n        \n        Returns:\n            XML 字符串，如果没有 skills 则返回空字符串\n        \"\"\"\n        skills = self.discover_skills()\n        if visible_skill_names is None:\n            env_json = os.environ.get(\"MLA_VISIBLE_SKILLS_JSON\", \"\").strip()\n            if env_json:\n                try:\n                    parsed = json.loads(env_json)\n                    if isinstance(parsed, list):\n                        visible_skill_names = [str(item).strip() for item in parsed if str(item).strip()]\n                except Exception:\n                    visible_skill_names = None\n        if visible_skill_names is not None:\n            allowed = {str(name).strip() for name in visible_skill_names if str(name).strip()}\n            skills = [skill for skill in skills if skill.get(\"name\") in allowed]\n        \n        if not skills:\n            return \"\"\n        \n        xml_parts = [\"<available_skills>\"]\n        for skill in skills:\n            xml_parts.append(f'  <skill>')\n            xml_parts.append(f'    <name>{skill[\"name\"]}</name>')\n            xml_parts.append(f'    <description>{skill[\"description\"]}</description>')\n            # location 用相对于 workspace 的 .skills/ 路径（部署后的位置）\n            xml_parts.append(f'    <location>.skills/{skill[\"name\"]}/SKILL.md</location>')\n            xml_parts.append(f'  </skill>')\n        xml_parts.append(\"</available_skills>\")\n        xml_parts.append(\"\")\n        xml_parts.append(\"提示：需要使用某个 skill 时，先调用 load_skill 工具将其部署到 workspace 并把对应 SKILL.md 注入当前上下文；当不再需要时，可调用 offload_skill 卸载该注入内容。\")\n        \n        return \"\\n\".join(xml_parts)\n    \n    def get_skill_source_path(self, skill_name: str) -> Optional[Path]:\n        \"\"\"\n        获取指定 skill 在 skills_library 中的源路径\n        \n        Args:\n            skill_name: skill 名称\n            \n        Returns:\n            skill 目录的 Path，不存在则返回 None\n        \"\"\"\n        skill_dir = self.skills_library / skill_name\n        skill_md = skill_dir / \"SKILL.md\"\n        \n        if skill_dir.is_dir() and skill_md.exists():\n            return skill_dir\n        \n        return None\n\n\n# 全局实例缓存\n_skill_loader_instance: Optional[SkillLoader] = None\n\n\ndef get_skill_loader(skills_library_path: str = None) -> SkillLoader:\n    \"\"\"获取全局 SkillLoader 实例\"\"\"\n    global _skill_loader_instance\n    if _skill_loader_instance is None:\n        _skill_loader_instance = SkillLoader(skills_library_path)\n    return _skill_loader_instance\n\n\ndef reset_skill_loader(skills_library_path: str = None) -> SkillLoader:\n    \"\"\"重置 SkillLoader 缓存（供 fresh 使用）。\"\"\"\n    global _skill_loader_instance\n    _skill_loader_instance = SkillLoader(skills_library_path)\n    return _skill_loader_instance\n"
  },
  {
    "path": "utils/task_history_index.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\n任务历史索引：\n- 持久化归档后的 task history 到 SQLite\n- 基于 instruction bundle 建立可检索 chunk\n- 提供 SQL / FTS / 可选 semantic 检索入口\n\"\"\"\n\nfrom __future__ import annotations\n\nimport hashlib\nimport json\nimport math\nimport sqlite3\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import Any, Dict, Iterable, List, Optional, Sequence\n\nfrom utils.user_paths import get_user_task_history_dir\n\n\ndef get_task_history_db_path() -> Path:\n    root = get_user_task_history_dir()\n    root.mkdir(parents=True, exist_ok=True)\n    return root / \"task_history.db\"\n\n\ndef _connect() -> sqlite3.Connection:\n    conn = sqlite3.connect(str(get_task_history_db_path()))\n    conn.row_factory = sqlite3.Row\n    _ensure_schema(conn)\n    return conn\n\n\ndef _ensure_schema(conn: sqlite3.Connection) -> None:\n    conn.executescript(\n        \"\"\"\n        CREATE TABLE IF NOT EXISTS indexed_entries (\n            entry_key TEXT PRIMARY KEY,\n            task_id TEXT NOT NULL,\n            entry_index INTEGER NOT NULL,\n            start_time TEXT,\n            completion_time TEXT,\n            agent_system TEXT,\n            agent_name TEXT,\n            indexed_at TEXT NOT NULL\n        );\n\n        CREATE TABLE IF NOT EXISTS history_chunks (\n            chunk_id TEXT PRIMARY KEY,\n            entry_key TEXT NOT NULL,\n            task_id TEXT NOT NULL,\n            entry_index INTEGER NOT NULL,\n            chunk_type TEXT NOT NULL,\n            instruction_index INTEGER,\n            instruction_text TEXT,\n            final_output TEXT,\n            latest_thinking TEXT,\n            text TEXT NOT NULL,\n            metadata_json TEXT,\n            created_at TEXT NOT NULL\n        );\n\n        CREATE VIRTUAL TABLE IF NOT EXISTS history_chunks_fts USING fts5(\n            chunk_id UNINDEXED,\n            text\n        );\n\n        CREATE VIEW IF NOT EXISTS task_history AS\n        SELECT\n            chunk_id,\n            task_id,\n            entry_index,\n            chunk_type,\n            instruction_index,\n            instruction_text,\n            final_output,\n            latest_thinking,\n            text,\n            json_extract(metadata_json, '$.start_time') AS start_time,\n            json_extract(metadata_json, '$.completion_time') AS completion_time,\n            json_extract(metadata_json, '$.agent_name') AS agent_name,\n            json_extract(metadata_json, '$.agent_system') AS agent_system,\n            metadata_json\n        FROM history_chunks;\n        \"\"\"\n    )\n    conn.commit()\n\n\ndef _json_dumps(value: Any) -> str:\n    return json.dumps(value, ensure_ascii=False, sort_keys=True)\n\n\ndef _entry_key(task_id: str, entry: Dict[str, Any]) -> str:\n    blob = _json_dumps({\n        \"task_id\": task_id,\n        \"entry\": entry,\n    })\n    return hashlib.md5(blob.encode(\"utf-8\")).hexdigest()\n\n\ndef _chunk_id(entry_key: str, chunk_type: str, instruction_index: int) -> str:\n    return f\"{entry_key}:{chunk_type}:{instruction_index}\"\n\n\ndef _extract_top_level_agents(entry: Dict[str, Any]) -> List[Dict[str, Any]]:\n    hierarchy = entry.get(\"hierarchy\", {}) if isinstance(entry, dict) else {}\n    agents_status = entry.get(\"agents_status\", {}) if isinstance(entry, dict) else {}\n    if not isinstance(hierarchy, dict) or not isinstance(agents_status, dict):\n        return []\n\n    top_level_ids = [\n        agent_id\n        for agent_id, node in hierarchy.items()\n        if isinstance(node, dict) and node.get(\"parent\") is None\n    ]\n    if not top_level_ids:\n        top_level_ids = list(agents_status.keys())\n\n    agents: List[Dict[str, Any]] = []\n    for agent_id in top_level_ids:\n        info = agents_status.get(agent_id)\n        if not isinstance(info, dict):\n            continue\n        if info.get(\"agent_name\") == \"judge_agent\":\n            continue\n        agents.append(info)\n    return agents\n\n\ndef _extract_entry_outputs(entry: Dict[str, Any]) -> Dict[str, str]:\n    agents = _extract_top_level_agents(entry)\n    final_output_parts: List[str] = []\n    thinking_parts: List[str] = []\n    agent_names: List[str] = []\n    for info in agents:\n        agent_name = str(info.get(\"agent_name\") or \"\").strip()\n        if agent_name:\n            agent_names.append(agent_name)\n        final_output = str(info.get(\"final_output\") or \"\").strip()\n        latest_thinking = str(info.get(\"latest_thinking\") or \"\").strip()\n        if final_output:\n            title = f\"[{agent_name}] \" if agent_name else \"\"\n            final_output_parts.append(f\"{title}{final_output}\")\n        if latest_thinking:\n            title = f\"[{agent_name}] \" if agent_name else \"\"\n            thinking_parts.append(f\"{title}{latest_thinking}\")\n\n    return {\n        \"agent_names\": \", \".join(agent_names),\n        \"final_output\": \"\\n\\n\".join(final_output_parts).strip(),\n        \"latest_thinking\": \"\\n\\n\".join(thinking_parts).strip(),\n    }\n\n\ndef _build_instruction_bundle_text(\n    *,\n    instruction_text: str,\n    final_output: str,\n    latest_thinking: str,\n    start_time: str,\n    completion_time: str,\n    agent_names: str,\n) -> str:\n    parts = []\n    if instruction_text:\n        parts.append(f\"Instruction:\\n{instruction_text}\")\n    if final_output:\n        parts.append(f\"Final Output:\\n{final_output}\")\n    if latest_thinking:\n        parts.append(f\"Latest Thinking:\\n{latest_thinking}\")\n    meta_lines = []\n    if start_time or completion_time:\n        meta_lines.append(f\"Time: {start_time or ''} -> {completion_time or ''}\".strip())\n    if agent_names:\n        meta_lines.append(f\"Top-level Agents: {agent_names}\")\n    if meta_lines:\n        parts.append(\"\\n\".join(meta_lines))\n    return \"\\n\\n\".join(part for part in parts if part).strip()\n\n\ndef _build_summary_text(\n    instructions: Sequence[str],\n    final_output: str,\n    latest_thinking: str,\n    start_time: str,\n    completion_time: str,\n    agent_names: str,\n) -> str:\n    parts = []\n    if instructions:\n        parts.append(\"Instructions:\\n\" + \"\\n\".join(f\"- {item}\" for item in instructions if item))\n    if final_output:\n        parts.append(f\"Final Output Summary:\\n{final_output}\")\n    if latest_thinking:\n        parts.append(f\"Thinking Summary:\\n{latest_thinking}\")\n    meta_lines = []\n    if start_time or completion_time:\n        meta_lines.append(f\"Time: {start_time or ''} -> {completion_time or ''}\".strip())\n    if agent_names:\n        meta_lines.append(f\"Top-level Agents: {agent_names}\")\n    if meta_lines:\n        parts.append(\"\\n\".join(meta_lines))\n    return \"\\n\\n\".join(part for part in parts if part).strip()\n\n\ndef _build_chunks(task_id: str, entry: Dict[str, Any], entry_index: int, runtime_meta: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]:\n    runtime_meta = runtime_meta or {}\n    entry_key = _entry_key(task_id, entry)\n    start_time = str(entry.get(\"start_time\") or \"\")\n    completion_time = str(entry.get(\"completion_time\") or \"\")\n    outputs = _extract_entry_outputs(entry)\n    instructions_raw = entry.get(\"instructions\", [])\n    instructions: List[str] = []\n    if isinstance(instructions_raw, list):\n        for item in instructions_raw:\n            if isinstance(item, dict):\n                text = str(item.get(\"instruction\") or \"\").strip()\n            else:\n                text = str(item or \"\").strip()\n            if text:\n                instructions.append(text)\n\n    metadata = {\n        \"task_id\": task_id,\n        \"entry_index\": entry_index,\n        \"start_time\": start_time,\n        \"completion_time\": completion_time,\n        \"agent_system\": str(runtime_meta.get(\"agent_system\") or \"\"),\n        \"agent_name\": str(runtime_meta.get(\"agent_name\") or outputs[\"agent_names\"] or \"\"),\n        \"top_level_agents\": outputs[\"agent_names\"],\n    }\n\n    chunks: List[Dict[str, Any]] = []\n    if instructions:\n        for instruction_index, instruction_text in enumerate(instructions):\n            text = _build_instruction_bundle_text(\n                instruction_text=instruction_text,\n                final_output=outputs[\"final_output\"],\n                latest_thinking=outputs[\"latest_thinking\"],\n                start_time=start_time,\n                completion_time=completion_time,\n                agent_names=outputs[\"agent_names\"],\n            )\n            chunks.append({\n                \"chunk_id\": _chunk_id(entry_key, \"instruction_bundle\", instruction_index),\n                \"entry_key\": entry_key,\n                \"task_id\": task_id,\n                \"entry_index\": entry_index,\n                \"chunk_type\": \"instruction_bundle\",\n                \"instruction_index\": instruction_index,\n                \"instruction_text\": instruction_text,\n                \"final_output\": outputs[\"final_output\"],\n                \"latest_thinking\": outputs[\"latest_thinking\"],\n                \"text\": text,\n                \"metadata_json\": _json_dumps(metadata),\n                \"created_at\": datetime.now().isoformat(),\n            })\n\n    summary_text = _build_summary_text(\n        instructions=instructions,\n        final_output=outputs[\"final_output\"],\n        latest_thinking=outputs[\"latest_thinking\"],\n        start_time=start_time,\n        completion_time=completion_time,\n        agent_names=outputs[\"agent_names\"],\n    )\n    if summary_text:\n        chunks.append({\n            \"chunk_id\": _chunk_id(entry_key, \"task_summary\", -1),\n            \"entry_key\": entry_key,\n            \"task_id\": task_id,\n            \"entry_index\": entry_index,\n            \"chunk_type\": \"task_summary\",\n            \"instruction_index\": None,\n            \"instruction_text\": \"\",\n            \"final_output\": outputs[\"final_output\"],\n            \"latest_thinking\": outputs[\"latest_thinking\"],\n            \"text\": summary_text,\n            \"metadata_json\": _json_dumps(metadata),\n            \"created_at\": datetime.now().isoformat(),\n        })\n\n    return chunks\n\n\ndef sync_task_history_from_context(task_id: str, context: Optional[Dict[str, Any]] = None) -> int:\n    if context is None:\n        from core.hierarchy_manager import get_hierarchy_manager\n        context = get_hierarchy_manager(task_id).get_context()\n\n    if not isinstance(context, dict):\n        return 0\n\n    history = context.get(\"history\", [])\n    runtime_meta = context.get(\"runtime\", {}) if isinstance(context.get(\"runtime\"), dict) else {}\n    if not isinstance(history, list) or not history:\n        return 0\n\n    indexed_count = 0\n    with _connect() as conn:\n        for entry_index, entry in enumerate(history):\n            if not isinstance(entry, dict):\n                continue\n            entry_key = _entry_key(task_id, entry)\n            exists = conn.execute(\n                \"SELECT 1 FROM indexed_entries WHERE entry_key = ?\",\n                (entry_key,),\n            ).fetchone()\n            if exists:\n                continue\n\n            chunks = _build_chunks(task_id, entry, entry_index, runtime_meta=runtime_meta)\n            if not chunks:\n                continue\n\n            conn.execute(\n                \"\"\"\n                INSERT OR REPLACE INTO indexed_entries\n                (entry_key, task_id, entry_index, start_time, completion_time, agent_system, agent_name, indexed_at)\n                VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n                \"\"\",\n                (\n                    entry_key,\n                    task_id,\n                    entry_index,\n                    str(entry.get(\"start_time\") or \"\"),\n                    str(entry.get(\"completion_time\") or \"\"),\n                    str(runtime_meta.get(\"agent_system\") or \"\"),\n                    str(runtime_meta.get(\"agent_name\") or \"\"),\n                    datetime.now().isoformat(),\n                ),\n            )\n            for chunk in chunks:\n                conn.execute(\n                    \"\"\"\n                    INSERT OR REPLACE INTO history_chunks\n                    (chunk_id, entry_key, task_id, entry_index, chunk_type, instruction_index, instruction_text,\n                     final_output, latest_thinking, text, metadata_json, created_at)\n                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n                    \"\"\",\n                    (\n                        chunk[\"chunk_id\"],\n                        chunk[\"entry_key\"],\n                        chunk[\"task_id\"],\n                        chunk[\"entry_index\"],\n                        chunk[\"chunk_type\"],\n                        chunk[\"instruction_index\"],\n                        chunk[\"instruction_text\"],\n                        chunk[\"final_output\"],\n                        chunk[\"latest_thinking\"],\n                        chunk[\"text\"],\n                        chunk[\"metadata_json\"],\n                        chunk[\"created_at\"],\n                    ),\n                )\n                conn.execute(\n                    \"INSERT OR REPLACE INTO history_chunks_fts (rowid, chunk_id, text) VALUES ((SELECT rowid FROM history_chunks WHERE chunk_id = ?), ?, ?)\",\n                    (chunk[\"chunk_id\"], chunk[\"chunk_id\"], chunk[\"text\"]),\n                )\n                indexed_count += 1\n        conn.commit()\n\n    return indexed_count\n\n\ndef search_task_history_sql(\n    *,\n    sql: Optional[str] = None,\n    query: Optional[str] = None,\n    task_id: Optional[str] = None,\n    limit: int = 10,\n) -> List[Dict[str, Any]]:\n    limit = max(1, min(int(limit or 10), 50))\n    with _connect() as conn:\n        if sql:\n            normalized = str(sql or \"\").strip()\n            if not normalized.lower().startswith(\"select\"):\n                raise ValueError(\"只允许执行只读 SELECT 语句\")\n            rows = conn.execute(normalized).fetchmany(limit)\n        else:\n            search_query = str(query or \"\").strip()\n            if not search_query:\n                raise ValueError(\"sql 模式至少需要 query 或 sql\")\n            base_sql = \"\"\"\n                SELECT c.*\n                FROM history_chunks_fts f\n                JOIN history_chunks c ON c.rowid = f.rowid\n                WHERE history_chunks_fts MATCH ?\n            \"\"\"\n            params: List[Any] = [search_query]\n            if task_id:\n                base_sql += \" AND c.task_id = ?\"\n                params.append(str(task_id))\n            base_sql += \" ORDER BY rank LIMIT ?\"\n            params.append(limit)\n            rows = conn.execute(base_sql, params).fetchall()\n\n    return [_row_to_result(row) for row in rows]\n\n\ndef _simple_cosine_similarity(vec_a: Sequence[float], vec_b: Sequence[float]) -> float:\n    if not vec_a or not vec_b or len(vec_a) != len(vec_b):\n        return 0.0\n    dot = sum(a * b for a, b in zip(vec_a, vec_b))\n    norm_a = math.sqrt(sum(a * a for a in vec_a))\n    norm_b = math.sqrt(sum(b * b for b in vec_b))\n    if norm_a <= 0 or norm_b <= 0:\n        return 0.0\n    return dot / (norm_a * norm_b)\n\n\ndef search_task_history_semantic(\n    *,\n    query: str,\n    task_id: Optional[str] = None,\n    limit: int = 10,\n) -> Dict[str, Any]:\n    limit = max(1, min(int(limit or 10), 50))\n    query = str(query or \"\").strip()\n    if not query:\n        raise ValueError(\"semantic 模式需要 query\")\n\n    try:\n        from sentence_transformers import SentenceTransformer\n    except Exception as exc:\n        return {\n            \"mode\": \"semantic\",\n            \"fallback\": \"unavailable\",\n            \"error\": f\"sentence_transformers 不可用: {exc}\",\n            \"results\": [],\n        }\n\n    model_name = \"all-MiniLM-L6-v2\"\n    try:\n        model = SentenceTransformer(model_name)\n    except Exception as exc:\n        return {\n            \"mode\": \"semantic\",\n            \"fallback\": \"unavailable\",\n            \"error\": f\"语义检索模型加载失败: {exc}\",\n            \"results\": [],\n        }\n\n    with _connect() as conn:\n        sql = \"SELECT * FROM history_chunks\"\n        params: List[Any] = []\n        if task_id:\n            sql += \" WHERE task_id = ?\"\n            params.append(str(task_id))\n        sql += \" ORDER BY entry_index DESC LIMIT 300\"\n        rows = conn.execute(sql, params).fetchall()\n\n    if not rows:\n        return {\"mode\": \"semantic\", \"fallback\": None, \"error\": \"\", \"results\": []}\n\n    texts = [str(row[\"text\"] or \"\") for row in rows]\n    embeddings = model.encode([query] + texts, normalize_embeddings=True)\n    query_embedding = embeddings[0]\n    scored = []\n    for row, emb in zip(rows, embeddings[1:]):\n        score = _simple_cosine_similarity(query_embedding, emb)\n        scored.append((score, row))\n    scored.sort(key=lambda item: item[0], reverse=True)\n\n    results = []\n    for score, row in scored[:limit]:\n        item = _row_to_result(row)\n        item[\"score\"] = float(score)\n        results.append(item)\n    return {\"mode\": \"semantic\", \"fallback\": None, \"error\": \"\", \"results\": results}\n\n\ndef _row_to_result(row: sqlite3.Row | Dict[str, Any]) -> Dict[str, Any]:\n    data = dict(row)\n    metadata_raw = data.get(\"metadata_json\")\n    try:\n        metadata = json.loads(metadata_raw) if metadata_raw else {}\n    except Exception:\n        metadata = {}\n    return {\n        \"chunk_id\": data.get(\"chunk_id\", \"\"),\n        \"task_id\": data.get(\"task_id\", \"\"),\n        \"entry_index\": data.get(\"entry_index\"),\n        \"chunk_type\": data.get(\"chunk_type\", \"\"),\n        \"instruction_index\": data.get(\"instruction_index\"),\n        \"instruction_text\": data.get(\"instruction_text\", \"\"),\n        \"final_output\": data.get(\"final_output\", \"\"),\n        \"latest_thinking\": data.get(\"latest_thinking\", \"\"),\n        \"text\": data.get(\"text\", \"\"),\n        \"metadata\": metadata,\n    }\n\n\ndef _load_entry_chunks(conn: sqlite3.Connection, entry_key: str) -> List[sqlite3.Row]:\n    return conn.execute(\n        \"\"\"\n        SELECT *\n        FROM history_chunks\n        WHERE entry_key = ?\n        ORDER BY\n          CASE WHEN chunk_type = 'instruction_bundle' THEN 0 ELSE 1 END,\n          instruction_index ASC\n        \"\"\",\n        (entry_key,),\n    ).fetchall()\n\n\ndef _entry_to_task_result(entry_row: sqlite3.Row, chunk_rows: Sequence[sqlite3.Row]) -> Dict[str, Any]:\n    instructions: List[str] = []\n    final_output = \"\"\n    latest_thinking = \"\"\n    summary_text = \"\"\n    matched_texts: List[str] = []\n\n    for chunk in chunk_rows:\n        instruction_text = str(chunk[\"instruction_text\"] or \"\").strip()\n        if instruction_text:\n            instructions.append(instruction_text)\n        if not final_output:\n            final_output = str(chunk[\"final_output\"] or \"\").strip()\n        if not latest_thinking:\n            latest_thinking = str(chunk[\"latest_thinking\"] or \"\").strip()\n        if chunk[\"chunk_type\"] == \"task_summary\" and not summary_text:\n            summary_text = str(chunk[\"text\"] or \"\").strip()\n        text = str(chunk[\"text\"] or \"\").strip()\n        if text:\n            matched_texts.append(text[:800])\n\n    return {\n        \"task_id\": str(entry_row[\"task_id\"] or \"\"),\n        \"entry_index\": int(entry_row[\"entry_index\"] or 0),\n        \"round\": int(entry_row[\"entry_index\"] or 0) + 1,\n        \"start_time\": str(entry_row[\"start_time\"] or \"\"),\n        \"completion_time\": str(entry_row[\"completion_time\"] or \"\"),\n        \"agent_system\": str(entry_row[\"agent_system\"] or \"\"),\n        \"agent_name\": str(entry_row[\"agent_name\"] or \"\"),\n        \"instructions\": instructions,\n        \"final_output\": final_output,\n        \"latest_thinking\": latest_thinking,\n        \"summary_text\": summary_text,\n        \"matched_texts\": matched_texts[:3],\n    }\n\n\ndef search_task_history_records(\n    *,\n    task_id: str,\n    keyword: str = \"\",\n    relevance_query_text: str = \"\",\n    start_time_from: str = \"\",\n    start_time_to: str = \"\",\n    start_round: int = 0,\n    enable_vector_search: bool = False,\n) -> Dict[str, Any]:\n    task_id = str(task_id or \"\").strip()\n    keyword = str(keyword or \"\").strip()\n    relevance_query_text = str(relevance_query_text or \"\").strip()\n    start_time_from = str(start_time_from or \"\").strip()\n    start_time_to = str(start_time_to or \"\").strip()\n    start_round = max(0, int(start_round or 0))\n\n    with _connect() as conn:\n        entry_keys_filter: Optional[set[str]] = None\n        if keyword:\n            rows = conn.execute(\n                \"\"\"\n                SELECT DISTINCT c.entry_key\n                FROM history_chunks_fts f\n                JOIN history_chunks c ON c.rowid = f.rowid\n                WHERE c.task_id = ? AND history_chunks_fts MATCH ?\n                \"\"\",\n                (task_id, keyword),\n            ).fetchall()\n            entry_keys_filter = {str(row[\"entry_key\"]) for row in rows}\n\n        semantic_scores: Dict[str, float] = {}\n        semantic_error = \"\"\n        if enable_vector_search and relevance_query_text:\n            semantic_payload = search_task_history_semantic(\n                query=relevance_query_text,\n                task_id=task_id,\n                limit=50,\n            )\n            semantic_error = str(semantic_payload.get(\"error\") or \"\")\n            for item in semantic_payload.get(\"results\", []):\n                chunk_id = str(item.get(\"chunk_id\") or \"\")\n                if not chunk_id:\n                    continue\n                entry_key = chunk_id.split(\":\", 1)[0]\n                semantic_scores[entry_key] = max(float(item.get(\"score\") or 0.0), semantic_scores.get(entry_key, 0.0))\n            if entry_keys_filter is None and semantic_scores:\n                entry_keys_filter = set(semantic_scores.keys())\n            elif entry_keys_filter is not None and semantic_scores:\n                entry_keys_filter &= set(semantic_scores.keys())\n\n        sql = \"\"\"\n            SELECT *\n            FROM indexed_entries\n            WHERE task_id = ?\n        \"\"\"\n        params: List[Any] = [task_id]\n        if start_time_from:\n            sql += \" AND (start_time IS NULL OR start_time >= ?)\"\n            params.append(start_time_from)\n        if start_time_to:\n            sql += \" AND (start_time IS NULL OR start_time <= ?)\"\n            params.append(start_time_to)\n        if start_round > 0:\n            sql += \" AND entry_index >= ?\"\n            params.append(start_round - 1)\n        sql += \" ORDER BY start_time ASC, entry_index ASC\"\n        rows = conn.execute(sql, params).fetchall()\n\n        results: List[Dict[str, Any]] = []\n        for row in rows:\n            entry_key = str(row[\"entry_key\"])\n            if entry_keys_filter is not None and entry_key not in entry_keys_filter:\n                continue\n            chunk_rows = _load_entry_chunks(conn, entry_key)\n            item = _entry_to_task_result(row, chunk_rows)\n            if entry_key in semantic_scores:\n                item[\"score\"] = semantic_scores[entry_key]\n            results.append(item)\n\n    return {\n        \"task_id\": task_id,\n        \"keyword\": keyword,\n        \"relevance_query_text\": relevance_query_text,\n        \"start_time_from\": start_time_from,\n        \"start_time_to\": start_time_to,\n        \"start_round\": start_round,\n        \"enable_vector_search\": bool(enable_vector_search),\n        \"semantic_error\": semantic_error,\n        \"results\": results,\n    }\n"
  },
  {
    "path": "utils/task_runtime.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\nTask 运行时辅助：\n- 读取 task 的可恢复元数据\n- 当目标 task 不在运行时，按 fresh 语义重载配置并后台 resume\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport signal\nimport subprocess\nimport sys\nimport threading\nimport traceback\nimport hashlib\nfrom pathlib import Path\nfrom typing import Any, Dict, Optional, Tuple\nfrom datetime import datetime\n\nfrom core.hierarchy_manager import get_hierarchy_manager\nfrom utils.mcp_manager import reload_mcp_tools\nfrom utils.skill_loader import reset_skill_loader\nfrom utils.runtime_control import get_running_task, is_task_running\nfrom utils.user_paths import (\n    get_user_conversations_dir,\n    get_user_runtime_logs_dir,\n    runtime_env_scope,\n)\nfrom utils.windows_compat import safe_print\n\n_launch_lock = threading.Lock()\n_launching_tasks: set[str] = set()\n\n\ndef _task_file_prefix(task_id: str) -> str:\n    task_hash = hashlib.md5(task_id.encode(\"utf-8\")).hexdigest()[:8]\n    task_name = Path(task_id).name or \"task\"\n    return f\"{task_hash}_{task_name}\"\n\n\ndef load_task_resume_meta(task_id: str, fallback_agent_system: Optional[str] = None) -> Tuple[Optional[Dict], str]:\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return None, \"缺少 task_id\"\n\n    manager = get_hierarchy_manager(task_id)\n    stack = manager._load_stack()\n    if not stack:\n        return None, f\"任务 {task_id} 没有可恢复的栈，无法 resume。\"\n\n    bottom = stack[0] or {}\n    context = manager._load_context()\n    runtime_meta = context.get(\"runtime\", {})\n    if not isinstance(runtime_meta, dict):\n        runtime_meta = {}\n\n    agent_name = str(bottom.get(\"agent_name\") or runtime_meta.get(\"agent_name\") or \"\").strip()\n    user_input = str(bottom.get(\"user_input\") or runtime_meta.get(\"user_input\") or \"\").strip()\n    agent_system = str(runtime_meta.get(\"agent_system\") or fallback_agent_system or \"\").strip()\n\n    if not agent_name:\n        return None, f\"任务 {task_id} 的恢复信息缺少 agent_name。\"\n    if not user_input:\n        return None, f\"任务 {task_id} 的恢复信息缺少 user_input。\"\n    if not agent_system:\n        return None, f\"任务 {task_id} 的恢复信息缺少 agent_system。\"\n\n    return {\n        \"task_id\": task_id,\n        \"agent_name\": agent_name,\n        \"user_input\": user_input,\n        \"agent_system\": agent_system,\n    }, \"\"\n\n\ndef load_task_launch_meta(\n    task_id: str,\n    fallback_agent_system: Optional[str] = None,\n    fallback_agent_name: Optional[str] = None,\n) -> Tuple[Optional[Dict], str]:\n    \"\"\"\n    读取“可新启动”所需的最小 task 元信息。\n\n    与 resume 不同，这里不要求 stack 非空。\n    \"\"\"\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return None, \"缺少 task_id\"\n\n    manager = get_hierarchy_manager(task_id)\n    runtime_meta = manager.get_runtime_metadata()\n    if not isinstance(runtime_meta, dict):\n        runtime_meta = {}\n\n    agent_name = str(runtime_meta.get(\"agent_name\") or fallback_agent_name or \"alpha_agent\").strip()\n    agent_system = str(runtime_meta.get(\"agent_system\") or fallback_agent_system or \"OpenCowork\").strip()\n\n    if not agent_name:\n        return None, f\"任务 {task_id} 的启动信息缺少 agent_name。\"\n    if not agent_system:\n        return None, f\"任务 {task_id} 的启动信息缺少 agent_system。\"\n\n    return {\n        \"task_id\": task_id,\n        \"agent_name\": agent_name,\n        \"agent_system\": agent_system,\n    }, \"\"\n\n\ndef _parse_env_flag(value: Any) -> Optional[bool]:\n    if value is None:\n        return None\n    text = str(value).strip().lower()\n    if text in {\"1\", \"true\", \"yes\", \"on\"}:\n        return True\n    if text in {\"0\", \"false\", \"no\", \"off\"}:\n        return False\n    return None\n\n\ndef _build_launch_config_from_env_overrides(env_overrides: Optional[Dict[str, Any]]) -> Dict[str, Any]:\n    overrides = dict(env_overrides or {})\n    config: Dict[str, Any] = {}\n\n    mapping = {\n        \"MLA_USER_DATA_ROOT\": \"user_data_root\",\n        \"MLA_LLM_CONFIG_PATH\": \"llm_config_path\",\n        \"MLA_AGENT_LIBRARY_DIR\": \"agent_library_dir\",\n        \"MLA_SKILLS_LIBRARY_DIR\": \"skills_dir\",\n        \"MLA_TOOLS_LIBRARY_DIR\": \"tools_dir\",\n    }\n    for env_key, config_key in mapping.items():\n        value = overrides.get(env_key)\n        if value:\n            config[config_key] = value\n\n    int_mapping = {\n        \"MLA_ACTION_WINDOW_STEPS\": \"action_window_steps\",\n        \"MLA_THINKING_INTERVAL\": \"thinking_interval\",\n        \"MLA_THINKING_STEPS\": \"thinking_steps\",\n        \"MLA_NO_TOOL_RETRY_LIMIT\": \"no_tool_retry_limit\",\n        \"MLA_MAX_TURNS\": \"max_turns\",\n        \"MLA_FRESH_INTERVAL_SEC\": \"fresh_interval_sec\",\n    }\n    for env_key, config_key in int_mapping.items():\n        value = overrides.get(env_key)\n        if value is None or value == \"\":\n            continue\n        try:\n            config[config_key] = int(value)\n        except Exception:\n            pass\n\n    fresh_enabled = _parse_env_flag(overrides.get(\"MLA_FRESH_ENABLED\"))\n    if fresh_enabled is not None:\n        config[\"fresh_enabled\"] = fresh_enabled\n\n    thinking_enabled = _parse_env_flag(overrides.get(\"MLA_THINKING_ENABLED\"))\n    if thinking_enabled is not None:\n        config[\"thinking_enabled\"] = thinking_enabled\n\n    seed_builtin = _parse_env_flag(overrides.get(\"MLA_SEED_BUILTIN_RESOURCES\"))\n    if seed_builtin is not None:\n        config[\"seed_builtin_resources\"] = seed_builtin\n\n    json_mapping = {\n        \"MLA_TOOL_HOOKS_JSON\": \"tool_hooks\",\n        \"MLA_CONTEXT_HOOKS_JSON\": \"context_hooks\",\n    }\n    for env_key, config_key in json_mapping.items():\n        value = overrides.get(env_key)\n        if not value:\n            continue\n        try:\n            config[config_key] = json.loads(value)\n        except Exception:\n            pass\n\n    mcp_config = overrides.get(\"MLA_MCP_CONFIG_JSON\")\n    if mcp_config:\n        try:\n            parsed = json.loads(mcp_config)\n            if isinstance(parsed, dict) and isinstance(parsed.get(\"servers\"), list):\n                config[\"mcp_servers\"] = parsed[\"servers\"]\n        except Exception:\n            pass\n\n    context_int_mapping = {\n        \"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\": \"user_history_compress_threshold_tokens\",\n        \"MLA_USER_HISTORY_RECENT_ITEMS\": \"user_history_recent_items\",\n        \"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_AGENTS\": \"structured_call_info_compress_threshold_agents\",\n        \"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_TOKENS\": \"structured_call_info_compress_threshold_tokens\",\n    }\n    for env_key, config_key in context_int_mapping.items():\n        value = overrides.get(env_key)\n        if value is None or value == \"\":\n            continue\n        try:\n            config[config_key] = int(value)\n        except Exception:\n            pass\n\n    return config\n\n\ndef resume_task_with_fresh(\n    task_id: str,\n    reason: str = \"\",\n    fallback_agent_system: Optional[str] = None,\n    direct_tools: bool = True,\n    env_overrides: Optional[Dict[str, Any]] = None,\n) -> Tuple[bool, str]:\n    meta, error = load_task_resume_meta(task_id, fallback_agent_system=fallback_agent_system)\n    if not meta:\n        return False, error\n\n    with _launch_lock:\n        if task_id in _launching_tasks:\n            return True, f\"任务 {task_id} 已在后台启动中。\"\n        _launching_tasks.add(task_id)\n\n    def _runner():\n        try:\n            with runtime_env_scope(env_overrides):\n                from tool_server_lite.registry import reload_runtime_registry\n                reset_skill_loader()\n                reload_runtime_registry()\n                reload_mcp_tools()\n\n                from core.agent_executor import AgentExecutor\n                from utils.config_loader import ConfigLoader\n\n                config_loader = ConfigLoader(meta[\"agent_system\"])\n                hierarchy_manager = get_hierarchy_manager(meta[\"task_id\"])\n\n                agent_config = config_loader.get_tool_config(meta[\"agent_name\"])\n                if agent_config.get(\"type\") != \"llm_call_agent\":\n                    safe_print(\n                        f\"❌ 后台恢复失败: {meta['agent_name']} 不是 LLM Agent \"\n                        f\"(task_id={meta['task_id']})\"\n                    )\n                    return\n\n                safe_print(\n                    f\"🔄 后台恢复任务: {meta['task_id']} | \"\n                    f\"system={meta['agent_system']} | agent={meta['agent_name']} | reason={reason or 'fresh request'}\"\n                )\n\n                agent = AgentExecutor(\n                    agent_name=meta[\"agent_name\"],\n                    agent_config=agent_config,\n                    config_loader=config_loader,\n                    hierarchy_manager=hierarchy_manager,\n                    direct_tools=direct_tools,\n                )\n                agent.run(meta[\"task_id\"], meta[\"user_input\"])\n        except Exception as e:\n            safe_print(f\"❌ 后台恢复任务失败: {task_id} -> {e}\")\n            traceback.print_exc()\n        finally:\n            with _launch_lock:\n                _launching_tasks.discard(task_id)\n\n    thread = threading.Thread(\n        target=_runner,\n        daemon=True,\n        name=f\"mla-resume-{abs(hash(task_id)) % 1000000}\"\n    )\n    thread.start()\n\n    return True, f\"目标任务未在运行，已重载配置并在后台 resume: {task_id}\"\n\n\ndef append_task_message(\n    task_id: str,\n    message: str,\n    source: str = \"agent\",\n    resume_if_needed: bool = False,\n    fallback_agent_system: Optional[str] = None,\n    direct_tools: bool = True,\n    env_overrides: Optional[Dict[str, Any]] = None,\n) -> Tuple[bool, Dict]:\n    task_id = str(task_id or \"\").strip()\n    message = str(message or \"\").strip()\n    if not task_id:\n        return False, {\"error\": \"缺少 task_id\"}\n    if not message:\n        return False, {\"error\": \"缺少 message\"}\n\n    manager = get_hierarchy_manager(task_id)\n    instruction_id = manager.append_instruction(message, dedupe=False, source=source)\n    stack = manager._load_stack()\n    payload = {\n        \"task_id\": task_id,\n        \"instruction_id\": instruction_id,\n        \"share_context_path\": str(manager.context_file),\n        \"stack_path\": str(manager.stack_file),\n        \"running\": is_task_running(task_id),\n        \"resumed\": False,\n        \"launched\": False,\n    }\n\n    if payload[\"running\"]:\n        payload[\"message\"] = \"消息已追加，目标 task 将在下一轮上下文构建时看到该消息。\"\n        return True, payload\n\n    if resume_if_needed:\n        if stack:\n            ok, resume_msg = resume_task_with_fresh(\n                task_id=task_id,\n                reason=f\"resume after add_message: {message[:80]}\",\n                fallback_agent_system=fallback_agent_system,\n                direct_tools=direct_tools,\n                env_overrides=env_overrides,\n            )\n            payload[\"resumed\"] = ok\n            payload[\"message\"] = resume_msg\n            if not ok:\n                payload[\"error\"] = resume_msg\n                return False, payload\n            return True, payload\n\n        launch_meta, launch_error = load_task_launch_meta(\n            task_id,\n            fallback_agent_system=fallback_agent_system,\n        )\n        if not launch_meta:\n            payload[\"message\"] = launch_error\n            payload[\"error\"] = launch_error\n            return False, payload\n\n        ok, launch_payload = launch_task_process(\n            task_id=task_id,\n            user_input=message,\n            agent_system=launch_meta[\"agent_system\"],\n            agent_name=launch_meta[\"agent_name\"],\n            config=_build_launch_config_from_env_overrides(env_overrides),\n            force_new=False,\n            direct_tools=direct_tools,\n        )\n        payload[\"launched\"] = ok\n        payload[\"message\"] = launch_payload.get(\"message\") if isinstance(launch_payload, dict) else \"\"\n        if isinstance(launch_payload, dict):\n            payload.update({\n                \"pid\": launch_payload.get(\"pid\"),\n                \"log_path\": launch_payload.get(\"log_path\", \"\"),\n                \"agent_system\": launch_payload.get(\"agent_system\", launch_meta[\"agent_system\"]),\n                \"agent_name\": launch_payload.get(\"agent_name\", launch_meta[\"agent_name\"]),\n            })\n        if not ok:\n            payload[\"error\"] = (launch_payload or {}).get(\"error\") if isinstance(launch_payload, dict) else \"后台启动失败\"\n            return False, payload\n        return True, payload\n\n    payload[\"message\"] = \"消息已追加，但目标 task 当前未运行。\"\n    return True, payload\n\n\ndef get_task_share_paths(task_id: str) -> Dict[str, str]:\n    manager = get_hierarchy_manager(str(task_id or \"\").strip())\n    return {\n        \"task_id\": manager.task_id,\n        \"share_context_path\": str(manager.context_file),\n        \"stack_path\": str(manager.stack_file),\n    }\n\n\ndef list_known_tasks(only_running: bool = False) -> Dict[str, list]:\n    conversations_dir = get_user_conversations_dir()\n    tasks = []\n    seen = set()\n\n    if conversations_dir.exists():\n        for path in sorted(conversations_dir.glob(\"*_share_context.json\")):\n            try:\n                data = json.loads(path.read_text(encoding=\"utf-8\"))\n            except Exception:\n                continue\n            task_id = str(data.get(\"task_id\") or \"\").strip()\n            if not task_id or task_id in seen:\n                continue\n            seen.add(task_id)\n            running = is_task_running(task_id)\n            if only_running and not running:\n                continue\n            task_path = Path(task_id)\n            tasks.append({\n                \"task_id\": task_id,\n                \"task_name\": task_path.name or task_id,\n                \"share_context_path\": str(path),\n                \"stack_path\": str(get_hierarchy_manager(task_id).stack_file),\n                \"running\": running,\n            })\n\n    tasks.sort(key=lambda item: (not item[\"running\"], item[\"task_name\"], item[\"task_id\"]))\n    return {\"tasks\": tasks}\n\n\ndef reset_task_state(\n    task_id: str,\n    preserve_history: bool = True,\n    kill_background_processes: bool = True,\n    reason: str = \"\",\n) -> Tuple[bool, Dict[str, Any]]:\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return False, {\"error\": \"缺少 task_id\"}\n\n    manager = get_hierarchy_manager(task_id)\n    context = manager._load_context()\n    if not isinstance(context, dict):\n        context = {\"task_id\": task_id, \"runtime\": {}, \"current\": {}, \"history\": []}\n\n    current = context.get(\"current\", {})\n    if not isinstance(current, dict):\n        current = {}\n\n    if preserve_history and (\n        current.get(\"instructions\")\n        or current.get(\"hierarchy\")\n        or current.get(\"agents_status\")\n    ):\n        history_entry = {\n            \"archived_at\": datetime.now().isoformat(),\n            \"type\": \"task_reset\",\n            \"reason\": reason or \"manual reset\",\n            \"instructions\": current.get(\"instructions\", []),\n            \"hierarchy\": current.get(\"hierarchy\", {}),\n            \"agents_status\": current.get(\"agents_status\", {}),\n            \"start_time\": current.get(\"start_time\", \"\"),\n            \"last_updated\": current.get(\"last_updated\", \"\"),\n        }\n        history = context.get(\"history\", [])\n        if not isinstance(history, list):\n            history = []\n        history.append(history_entry)\n        context[\"history\"] = history\n\n    runtime = context.get(\"runtime\", {})\n    if not isinstance(runtime, dict):\n        runtime = {}\n    runtime[\"last_reset_at\"] = datetime.now().isoformat()\n    runtime[\"last_reset_reason\"] = reason or \"manual reset\"\n    context[\"runtime\"] = runtime\n    context[\"current\"] = {\n        \"instructions\": [],\n        \"hierarchy\": {},\n        \"agents_status\": {},\n        \"start_time\": datetime.now().isoformat(),\n        \"last_updated\": datetime.now().isoformat(),\n    }\n    manager._save_context(context)\n    manager._save_stack([])\n\n    conversations_dir = get_user_conversations_dir()\n    prefix = _task_file_prefix(task_id)\n    removed_action_files = []\n    for path in conversations_dir.glob(f\"{prefix}_*_actions.json\"):\n        try:\n            path.unlink()\n            removed_action_files.append(str(path))\n        except FileNotFoundError:\n            pass\n\n    killed_pid = None\n    running_meta = get_running_task(task_id)\n    if kill_background_processes and running_meta:\n        pid = int(running_meta.get(\"pid\") or 0)\n        if pid > 0:\n            try:\n                os.kill(pid, signal.SIGTERM)\n                killed_pid = pid\n            except ProcessLookupError:\n                pass\n            except Exception:\n                pass\n\n    return True, {\n        \"task_id\": task_id,\n        \"preserve_history\": bool(preserve_history),\n        \"kill_background_processes\": bool(kill_background_processes),\n        \"killed_pid\": killed_pid,\n        \"share_context_path\": str(manager.context_file),\n        \"stack_path\": str(manager.stack_file),\n        \"removed_action_files\": removed_action_files,\n        \"message\": f\"已重置任务状态: {task_id}\",\n    }\n\n\ndef _as_root_dir(path: Optional[str], expected_leaf: Optional[str] = None) -> Optional[str]:\n    if not path:\n        return None\n    p = Path(path).expanduser().resolve()\n    if expected_leaf and p.name == expected_leaf:\n        return str(p.parent)\n    return str(p)\n\n\ndef _runtime_logs_dir() -> Path:\n    path = get_user_runtime_logs_dir()\n    path.mkdir(parents=True, exist_ok=True)\n    return path\n\n\ndef launch_task_process(\n    *,\n    task_id: str,\n    user_input: str,\n    agent_system: str = \"OpenCowork\",\n    agent_name: str = \"alpha_agent\",\n    config: Optional[Dict] = None,\n    force_new: bool = False,\n    direct_tools: bool = True,\n) -> Tuple[bool, Dict]:\n    task_id = str(task_id or \"\").strip()\n    user_input = str(user_input or \"\").strip()\n    agent_system = str(agent_system or \"OpenCowork\").strip() or \"OpenCowork\"\n    agent_name = str(agent_name or \"alpha_agent\").strip() or \"alpha_agent\"\n    config = config if isinstance(config, dict) else {}\n\n    if not task_id:\n        return False, {\"error\": \"缺少 task_id\"}\n    if not user_input:\n        return False, {\"error\": \"缺少 user_input\"}\n    with _launch_lock:\n        if task_id in _launching_tasks:\n            return False, {\"error\": f\"任务正在启动中: {task_id}\"}\n        if is_task_running(task_id):\n            return False, {\"error\": f\"任务已在运行: {task_id}\"}\n        _launching_tasks.add(task_id)\n\n    try:\n        start_py = Path(__file__).resolve().parent.parent / \"start.py\"\n        if not start_py.exists():\n            return False, {\"error\": f\"start.py 不存在: {start_py}\"}\n\n        task_path = str(Path(task_id).expanduser().resolve())\n        Path(task_path).mkdir(parents=True, exist_ok=True)\n        user_data_root = config.get(\"user_data_root\")\n        resolved_user_data_root = str(Path(user_data_root).expanduser().resolve()) if user_data_root else None\n\n        effective_agent_library_dir = config.get(\"agent_library_dir\") or config.get(\"library_dir\")\n        inferred_root = _as_root_dir(effective_agent_library_dir, \"agent_library\") if effective_agent_library_dir else None\n        log_scope_root = resolved_user_data_root or inferred_root\n        with runtime_env_scope({\"MLA_USER_DATA_ROOT\": log_scope_root} if log_scope_root else None):\n            log_path = _runtime_logs_dir() / f\"{Path(task_path).name or 'task'}_{abs(hash((task_path, user_input))) % 100000000}.log\"\n\n        env = dict(os.environ)\n        env[\"PYTHONUNBUFFERED\"] = \"1\"\n        if resolved_user_data_root:\n            env[\"MLA_USER_DATA_ROOT\"] = resolved_user_data_root\n\n        llm_config_path = config.get(\"llm_config_path\")\n        if llm_config_path:\n            env[\"MLA_LLM_CONFIG_PATH\"] = str(Path(llm_config_path).expanduser().resolve())\n\n        if inferred_root:\n            if not env.get(\"MLA_USER_DATA_ROOT\"):\n                env[\"MLA_USER_DATA_ROOT\"] = inferred_root\n            env[\"MLA_AGENT_LIBRARY_DIR\"] = inferred_root\n\n        if config.get(\"skills_dir\"):\n            env[\"MLA_SKILLS_LIBRARY_DIR\"] = str(Path(config[\"skills_dir\"]).expanduser().resolve())\n        if config.get(\"tools_dir\"):\n            env[\"MLA_TOOLS_LIBRARY_DIR\"] = str(Path(config[\"tools_dir\"]).expanduser().resolve())\n        if config.get(\"action_window_steps\") is not None:\n            env[\"MLA_ACTION_WINDOW_STEPS\"] = str(max(1, int(config[\"action_window_steps\"])))\n        if config.get(\"thinking_interval\") is not None:\n            env[\"MLA_THINKING_INTERVAL\"] = str(max(1, int(config[\"thinking_interval\"])))\n        if config.get(\"thinking_steps\") is not None:\n            env[\"MLA_THINKING_STEPS\"] = str(max(1, int(config[\"thinking_steps\"])))\n        if config.get(\"thinking_enabled\") is not None:\n            env[\"MLA_THINKING_ENABLED\"] = \"true\" if bool(config[\"thinking_enabled\"]) else \"false\"\n        if config.get(\"no_tool_retry_limit\") is not None:\n            env[\"MLA_NO_TOOL_RETRY_LIMIT\"] = str(max(1, int(config[\"no_tool_retry_limit\"])))\n        if config.get(\"max_turns\") is not None:\n            env[\"MLA_MAX_TURNS\"] = str(max(1, int(config[\"max_turns\"])))\n        if config.get(\"fresh_enabled\") is not None:\n            env[\"MLA_FRESH_ENABLED\"] = \"true\" if bool(config[\"fresh_enabled\"]) else \"false\"\n        if config.get(\"fresh_interval_sec\") is not None:\n            env[\"MLA_FRESH_INTERVAL_SEC\"] = str(max(0, int(config[\"fresh_interval_sec\"])))\n        if config.get(\"mcp_servers\") is not None:\n            env[\"MLA_MCP_CONFIG_JSON\"] = json.dumps({\"servers\": config[\"mcp_servers\"]}, ensure_ascii=False)\n        if config.get(\"tool_hooks\") is not None:\n            env[\"MLA_TOOL_HOOKS_JSON\"] = json.dumps(config[\"tool_hooks\"], ensure_ascii=False)\n        if config.get(\"context_hooks\") is not None:\n            env[\"MLA_CONTEXT_HOOKS_JSON\"] = json.dumps(config[\"context_hooks\"], ensure_ascii=False)\n        if config.get(\"visible_skills\") is not None:\n            env[\"MLA_VISIBLE_SKILLS_JSON\"] = json.dumps(config[\"visible_skills\"], ensure_ascii=False)\n        if config.get(\"user_history_compress_threshold_tokens\") is not None:\n            env[\"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\"] = str(max(0, int(config[\"user_history_compress_threshold_tokens\"])))\n        if config.get(\"user_history_recent_items\") is not None:\n            env[\"MLA_USER_HISTORY_RECENT_ITEMS\"] = str(max(0, int(config[\"user_history_recent_items\"])))\n        if config.get(\"structured_call_info_compress_threshold_agents\") is not None:\n            env[\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_AGENTS\"] = str(max(1, int(config[\"structured_call_info_compress_threshold_agents\"])))\n        if config.get(\"structured_call_info_compress_threshold_tokens\") is not None:\n            env[\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_TOKENS\"] = str(max(0, int(config[\"structured_call_info_compress_threshold_tokens\"])))\n        if config.get(\"seed_builtin_resources\") is not None:\n            env[\"MLA_SEED_BUILTIN_RESOURCES\"] = \"true\" if bool(config[\"seed_builtin_resources\"]) else \"false\"\n\n        args = [\n            sys.executable,\n            str(start_py),\n            \"--task_id\", task_path,\n            \"--agent_system\", agent_system,\n            \"--agent_name\", agent_name,\n            \"--user_input\", user_input,\n        ]\n        if force_new or bool(config.get(\"force_new\")):\n            args.append(\"--force-new\")\n        if direct_tools or bool(config.get(\"direct_tools\")):\n            args.append(\"--direct-tools\")\n        if config.get(\"auto_mode\") is not None:\n            args.extend([\"--auto-mode\", \"true\" if bool(config.get(\"auto_mode\")) else \"false\"])\n\n        with open(log_path, \"a\", encoding=\"utf-8\") as log_file:\n            log_file.write(\n                f\"[launch] task_id={task_path} agent_system={agent_system} agent_name={agent_name}\\n\"\n            )\n            process = subprocess.Popen(\n                args,\n                cwd=str(start_py.parent),\n                env=env,\n                stdout=log_file,\n                stderr=subprocess.STDOUT,\n                stdin=subprocess.DEVNULL,\n                start_new_session=True,\n            )\n\n        return True, {\n            \"task_id\": task_path,\n            \"agent_system\": agent_system,\n            \"agent_name\": agent_name,\n            \"pid\": process.pid,\n            \"log_path\": str(log_path),\n            \"message\": f\"已在后台启动任务: {task_path}\",\n        }\n    finally:\n        def _release_launch_flag():\n            with _launch_lock:\n                _launching_tasks.discard(task_id)\n\n        timer = threading.Timer(5.0, _release_launch_flag)\n        timer.daemon = True\n        timer.start()\n"
  },
  {
    "path": "utils/tool_hooks.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom __future__ import annotations\n\nimport importlib\nimport importlib.util\nimport json\nimport os\nfrom functools import lru_cache\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom utils.windows_compat import safe_print\n\n\ndef _load_hooks_config() -> List[Dict[str, Any]]:\n    raw = os.environ.get(\"MLA_TOOL_HOOKS_JSON\", \"\").strip()\n    if not raw:\n        return []\n    try:\n        payload = json.loads(raw)\n    except Exception as exc:\n        safe_print(f\"⚠️  解析 MLA_TOOL_HOOKS_JSON 失败: {exc}\")\n        return []\n    if not isinstance(payload, list):\n        return []\n    hooks: List[Dict[str, Any]] = []\n    for item in payload:\n        if not isinstance(item, dict):\n            continue\n        callback = str(item.get(\"callback\") or \"\").strip()\n        if not callback:\n            continue\n        when = str(item.get(\"when\") or \"after\").strip().lower()\n        if when not in {\"before\", \"after\", \"both\"}:\n            when = \"after\"\n        tool_names = item.get(\"tool_names\")\n        if isinstance(tool_names, str):\n            tool_names = [tool_names]\n        if not isinstance(tool_names, list) or not tool_names:\n            tool_names = [\"*\"]\n        hooks.append({\n            \"name\": str(item.get(\"name\") or callback).strip(),\n            \"callback\": callback,\n            \"when\": when,\n            \"tool_names\": [str(name).strip() for name in tool_names if str(name).strip()],\n            \"include_arguments\": bool(item.get(\"include_arguments\", True)),\n            \"include_result\": bool(item.get(\"include_result\", True)),\n            \"argument_filters\": item.get(\"argument_filters\") if isinstance(item.get(\"argument_filters\"), dict) else {},\n            \"result_filters\": item.get(\"result_filters\") if isinstance(item.get(\"result_filters\"), dict) else {},\n        })\n    return hooks\n\n\ndef _lookup_path(payload: Any, dotted_path: str) -> Any:\n    current = payload\n    for part in str(dotted_path or \"\").split(\".\"):\n        if not part:\n            continue\n        if isinstance(current, dict) and part in current:\n            current = current[part]\n            continue\n        if isinstance(current, list):\n            try:\n                current = current[int(part)]\n                continue\n            except Exception:\n                return None\n        return None\n    return current\n\n\ndef _match_filters(payload: Dict[str, Any], filters: Dict[str, Any]) -> bool:\n    if not filters:\n        return True\n    for dotted_path, expected in filters.items():\n        actual = _lookup_path(payload, dotted_path)\n        if isinstance(expected, list):\n            if actual not in expected:\n                return False\n        else:\n            if actual != expected:\n                return False\n    return True\n\n\n@lru_cache(maxsize=64)\ndef _resolve_callback(spec: str) -> Callable[[Dict[str, Any]], Any]:\n    target, sep, func_name = spec.rpartition(\":\")\n    if not sep or not target or not func_name:\n        raise ValueError(f\"无效 callback 规范: {spec}\")\n\n    if target.endswith(\".py\") and Path(target).expanduser().exists():\n        path = Path(target).expanduser().resolve()\n        module_name = f\"mla_tool_hook_{abs(hash((str(path), func_name))) % 100000000}\"\n        module_spec = importlib.util.spec_from_file_location(module_name, path)\n        if module_spec is None or module_spec.loader is None:\n            raise ValueError(f\"无法加载 hook 文件: {path}\")\n        module = importlib.util.module_from_spec(module_spec)\n        module_spec.loader.exec_module(module)\n    else:\n        module = importlib.import_module(target)\n\n    callback = getattr(module, func_name, None)\n    if callback is None or not callable(callback):\n        raise ValueError(f\"hook 回调不存在或不可调用: {spec}\")\n    return callback\n\n\ndef trigger_tool_hooks(\n    *,\n    when: str,\n    tool_name: str,\n    task_id: str,\n    arguments: Optional[Dict[str, Any]] = None,\n    result: Optional[Dict[str, Any]] = None,\n    agent_id: str = \"\",\n    agent_name: str = \"\",\n    agent_level: Optional[int] = None,\n) -> None:\n    when = str(when or \"\").strip().lower()\n    if when not in {\"before\", \"after\"}:\n        return\n    hooks = _load_hooks_config()\n    if not hooks:\n        return\n\n    arguments = arguments if isinstance(arguments, dict) else {}\n    result = result if isinstance(result, dict) else {}\n\n    for hook in hooks:\n        hook_when = hook.get(\"when\", \"after\")\n        if hook_when not in {when, \"both\"}:\n            continue\n        tool_names = hook.get(\"tool_names\") or [\"*\"]\n        if \"*\" not in tool_names and tool_name not in tool_names:\n            continue\n        if not _match_filters(arguments, hook.get(\"argument_filters\") or {}):\n            continue\n        if when == \"after\" and not _match_filters(result, hook.get(\"result_filters\") or {}):\n            continue\n\n        payload: Dict[str, Any] = {\n            \"hook_name\": hook.get(\"name\") or hook.get(\"callback\"),\n            \"when\": when,\n            \"tool_name\": tool_name,\n            \"task_id\": task_id,\n            \"agent_id\": agent_id,\n            \"agent_name\": agent_name,\n            \"agent_level\": agent_level,\n        }\n        if hook.get(\"include_arguments\", True):\n            payload[\"arguments\"] = arguments\n        if when == \"after\" and hook.get(\"include_result\", True):\n            payload[\"result\"] = result\n\n        try:\n            callback = _resolve_callback(str(hook[\"callback\"]))\n            callback(payload)\n        except Exception as exc:\n            safe_print(f\"⚠️  tool hook 执行失败 {hook.get('name') or hook.get('callback')}: {exc}\")\n"
  },
  {
    "path": "utils/user_paths.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n用户目录路径与运行时配置辅助函数。\n\n统一约定：\n- 用户数据根目录默认在 ~/mla_v3\n- 可通过环境变量 MLA_USER_DATA_ROOT 覆盖\n- CLI / Desktop / 打包后的 Python 后端都应优先读取这里的配置和扩展资源\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport shutil\nimport sys\nimport hashlib\nfrom contextlib import contextmanager\nfrom pathlib import Path\nfrom typing import Any, Dict, Iterator, List, Optional\n\nimport yaml\n\n\ndef get_project_root() -> Path:\n    \"\"\"获取当前 Python 后端项目根目录或安装后的资源根目录。\"\"\"\n    source_root = Path(__file__).resolve().parent.parent\n    if (source_root / \"config\").exists() or (source_root / \"skills\").exists():\n        return source_root\n\n    install_root = Path(sys.prefix).resolve()\n    if (install_root / \"config\").exists() or (install_root / \"skills\").exists():\n        return install_root\n\n    return source_root\n\n\ndef get_user_data_root() -> Path:\n    \"\"\"获取用户数据根目录，默认 ~/mla_v3。\"\"\"\n    env_root = os.environ.get(\"MLA_USER_DATA_ROOT\", \"\").strip()\n    if env_root:\n        return Path(env_root).expanduser().resolve()\n    return (Path.home() / \"mla_v3\").resolve()\n\n\ndef get_user_config_dir() -> Path:\n    return get_user_data_root() / \"config\"\n\n\ndef get_user_llm_config_path() -> Path:\n    env_path = os.environ.get(\"MLA_LLM_CONFIG_PATH\", \"\").strip()\n    if env_path:\n        return Path(env_path).expanduser().resolve()\n    return get_user_config_dir() / \"llm_config.yaml\"\n\n\ndef get_user_app_config_path() -> Path:\n    return get_user_config_dir() / \"app_config.json\"\n\n\ndef get_user_agent_library_root() -> Path:\n    return get_user_data_root() / \"agent_library\"\n\n\ndef get_agent_hidden_root() -> Path:\n    \"\"\"主流 agent 生态通用目录：~/.agent/\"\"\"\n    return (Path.home() / \".agent\").resolve()\n\n\ndef get_user_skills_library_root() -> Path:\n    env_path = os.environ.get(\"MLA_SKILLS_LIBRARY_DIR\", \"\").strip()\n    if env_path:\n        return Path(env_path).expanduser().resolve()\n    return get_agent_hidden_root() / \"skills\"\n\n\ndef get_user_tools_library_root() -> Path:\n    env_path = os.environ.get(\"MLA_TOOLS_LIBRARY_DIR\", \"\").strip()\n    if env_path:\n        return Path(env_path).expanduser().resolve()\n    return get_user_data_root() / \"tools_library\"\n\n\ndef get_user_conversations_dir() -> Path:\n    return get_user_data_root() / \"conversations\"\n\n\ndef get_user_logs_dir() -> Path:\n    return get_user_data_root() / \"logs\"\n\n\ndef get_user_runtime_dir() -> Path:\n    return get_user_data_root() / \"runtime\"\n\n\ndef get_user_runtime_logs_dir() -> Path:\n    return get_user_runtime_dir() / \"launched_tasks\"\n\n\ndef get_user_runtime_events_dir() -> Path:\n    return get_user_runtime_dir() / \"task_events\"\n\n\ndef get_user_task_history_dir() -> Path:\n    return get_user_runtime_dir() / \"task_history\"\n\n\ndef get_task_file_prefix(task_id: str) -> str:\n    \"\"\"生成 task 相关文件的统一前缀：hash + 最后一级目录名。\"\"\"\n    task_id = str(task_id or \"\").strip()\n    if not task_id:\n        return \"task\"\n    task_hash = hashlib.md5(task_id.encode(\"utf-8\")).hexdigest()[:8]\n    task_name = Path(task_id).name or \"task\"\n    return f\"{task_hash}_{task_name}\"\n\n\ndef ensure_user_data_root_scaffold() -> None:\n    \"\"\"确保用户目录结构存在。\"\"\"\n    for path in [\n        get_user_data_root(),\n        get_agent_hidden_root(),\n        get_user_config_dir(),\n        get_user_agent_library_root(),\n        get_user_skills_library_root(),\n        get_user_tools_library_root(),\n        get_user_conversations_dir(),\n        get_user_logs_dir(),\n        get_user_runtime_dir(),\n        get_user_runtime_events_dir(),\n    ]:\n        path.mkdir(parents=True, exist_ok=True)\n\n\ndef _seed_directory_children(src_root: Path, dest_root: Path) -> None:\n    if not src_root.exists():\n        return\n    dest_root.mkdir(parents=True, exist_ok=True)\n    for entry in src_root.iterdir():\n        if not entry.is_dir() or entry.name.startswith(\".\"):\n            continue\n        dest = dest_root / entry.name\n        if dest.exists():\n            continue\n        shutil.copytree(entry, dest)\n\n\ndef seed_user_resources_if_missing() -> None:\n    \"\"\"\n    将项目内置的默认 agent systems / skills 种到用户目录。\n    仅在目标缺失时复制，不覆盖用户已有资源。\n    \"\"\"\n    ensure_user_data_root_scaffold()\n    project_root = get_project_root()\n    _seed_directory_children(project_root / \"config\" / \"agent_library\", get_user_agent_library_root())\n    # 兼容旧目录：若 ~/.agent/skills 为空，则将 ~/mla_v3/skills_library 中内容迁移/补齐过去\n    old_skills_root = get_user_data_root() / \"skills_library\"\n    if old_skills_root.exists():\n        _seed_directory_children(old_skills_root, get_user_skills_library_root())\n    _seed_directory_children(project_root / \"skills\", get_user_skills_library_root())\n\n\ndef _blank_api_keys(value: Any) -> Any:\n    if isinstance(value, dict):\n        result = {}\n        for k, v in value.items():\n            if str(k).strip().lower() == \"api_key\":\n                result[k] = \"\"\n            else:\n                result[k] = _blank_api_keys(v)\n        return result\n    if isinstance(value, list):\n        return [_blank_api_keys(v) for v in value]\n    return value\n\n\ndef ensure_user_llm_config_exists() -> Path:\n    \"\"\"\n    确保用户目录中的 llm_config.yaml 存在。\n    优先从 llm_config.example.yaml 复制；若不存在则写入最小配置。\n    \"\"\"\n    ensure_user_data_root_scaffold()\n    config_path = get_user_llm_config_path()\n    config_path.parent.mkdir(parents=True, exist_ok=True)\n    if config_path.exists():\n        return config_path\n\n    project_root = get_project_root()\n    example_path = project_root / \"config\" / \"run_env_config\" / \"llm_config.example.yaml\"\n\n    if example_path.exists():\n        try:\n            raw = example_path.read_text(encoding=\"utf-8\")\n            parsed = yaml.safe_load(raw)\n            if parsed is None:\n                config_path.write_text(raw, encoding=\"utf-8\")\n            else:\n                sanitized = _blank_api_keys(parsed)\n                config_path.write_text(\n                    yaml.safe_dump(sanitized, allow_unicode=True, sort_keys=False),\n                    encoding=\"utf-8\",\n                )\n            return config_path\n        except Exception:\n            pass\n\n    minimal = \"\\n\".join([\n        \"temperature: 0\",\n        \"max_tokens: 0\",\n        \"max_context_window: 200000\",\n        'base_url: \"\"',\n        'api_key: \"\"',\n        \"models:\",\n        \"  - openai/gpt-4o-mini\",\n        \"multimodal: false\",\n        \"compressor_multimodal: false\",\n        \"\",\n    ])\n    config_path.write_text(minimal, encoding=\"utf-8\")\n    return config_path\n\n\ndef ensure_user_app_config_exists() -> Path:\n    \"\"\"确保用户目录中的 app_config.json 存在。\"\"\"\n    ensure_user_data_root_scaffold()\n    config_path = get_user_app_config_path()\n    config_path.parent.mkdir(parents=True, exist_ok=True)\n    if config_path.exists():\n        return config_path\n\n    default_payload = {\n        \"runtime\": {\n            \"action_window_steps\": 30,\n            \"thinking_interval\": 30,\n            \"thinking_enabled\": True,\n            \"thinking_steps\": 30,\n            \"no_tool_retry_limit\": 7,\n            \"max_turns\": 100000,\n            \"fresh_enabled\": False,\n            \"fresh_interval_sec\": 0,\n        },\n        \"env\": {\n            \"command_mode\": \"direct\",\n            \"seed_builtin_resources\": True,\n        },\n        \"context\": {\n            \"user_history_compress_threshold_tokens\": 1500,\n            \"user_history_recent_items\": 0,\n            \"structured_call_info_compress_threshold_agents\": 10,\n            \"structured_call_info_compress_threshold_tokens\": 2200,\n        },\n    }\n    config_path.write_text(json.dumps(default_payload, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    return config_path\n\n\ndef load_user_app_config() -> Dict[str, Any]:\n    \"\"\"读取用户 app_config.json；不存在或解析失败时返回空 dict。\"\"\"\n    path = get_user_app_config_path()\n    if not path.exists():\n        return {}\n    try:\n        data = json.loads(path.read_text(encoding=\"utf-8\"))\n        return data if isinstance(data, dict) else {}\n    except Exception:\n        return {}\n\n\ndef get_mcp_settings() -> Dict[str, Any]:\n    \"\"\"\n    读取 MCP 配置。\n    优先级：\n    1. MLA_MCP_CONFIG_JSON 环境变量（JSON 字符串）\n    2. app_config.json 中 mcp 字段\n    \"\"\"\n    env_json = os.environ.get(\"MLA_MCP_CONFIG_JSON\", \"\").strip()\n    if env_json:\n        try:\n            data = json.loads(env_json)\n            if isinstance(data, dict):\n                return data\n        except Exception:\n            pass\n\n    cfg = load_user_app_config()\n    mcp = cfg.get(\"mcp\", {}) if isinstance(cfg, dict) else {}\n    return mcp if isinstance(mcp, dict) else {}\n\n\ndef get_runtime_settings() -> Dict[str, Any]:\n    \"\"\"\n    读取运行时配置。\n    统一管理：\n    - 动作窗口步长\n    - thinking 间隔\n    - fresh 是否启用\n    - fresh 定时触发间隔（秒）\n    \"\"\"\n    cfg = load_user_app_config()\n    runtime = cfg.get(\"runtime\", {}) if isinstance(cfg, dict) else {}\n\n    env_action_window = os.environ.get(\"MLA_ACTION_WINDOW_STEPS\", \"\").strip()\n    env_thinking_interval = os.environ.get(\"MLA_THINKING_INTERVAL\", \"\").strip()\n    env_thinking_steps = os.environ.get(\"MLA_THINKING_STEPS\", \"\").strip()\n    env_thinking_enabled = os.environ.get(\"MLA_THINKING_ENABLED\", \"\").strip().lower()\n    env_no_tool_retry_limit = os.environ.get(\"MLA_NO_TOOL_RETRY_LIMIT\", \"\").strip()\n    env_visible_skills = os.environ.get(\"MLA_VISIBLE_SKILLS_JSON\", \"\").strip()\n    env_max_turns = os.environ.get(\"MLA_MAX_TURNS\", \"\").strip()\n    env_fresh_enabled = os.environ.get(\"MLA_FRESH_ENABLED\", \"\").strip().lower()\n    env_fresh_interval = os.environ.get(\"MLA_FRESH_INTERVAL_SEC\", \"\").strip()\n\n    action_window_steps = int(env_action_window or runtime.get(\"action_window_steps\", 30) or 30)\n    thinking_steps = int(\n        env_thinking_steps\n        or runtime.get(\"thinking_steps\", runtime.get(\"thinking_interval\", action_window_steps))\n        or action_window_steps\n    )\n    thinking_interval = int(env_thinking_interval or runtime.get(\"thinking_interval\", thinking_steps) or thinking_steps)\n    thinking_enabled = (\n        env_thinking_enabled in {\"1\", \"true\", \"yes\", \"on\"}\n        if env_thinking_enabled\n        else bool(runtime.get(\"thinking_enabled\", True))\n    )\n    no_tool_retry_limit = int(env_no_tool_retry_limit or runtime.get(\"no_tool_retry_limit\", 7) or 7)\n    visible_skills = runtime.get(\"visible_skills\")\n    if env_visible_skills:\n        try:\n            parsed = json.loads(env_visible_skills)\n            if isinstance(parsed, list):\n                visible_skills = [str(item).strip() for item in parsed if str(item).strip()]\n        except Exception:\n            pass\n    max_turns = int(env_max_turns or runtime.get(\"max_turns\", 100000) or 100000)\n    fresh_enabled = (env_fresh_enabled in {\"1\", \"true\", \"yes\", \"on\"}) if env_fresh_enabled else bool(runtime.get(\"fresh_enabled\", False))\n    fresh_interval_sec = int(env_fresh_interval or runtime.get(\"fresh_interval_sec\", 0) or 0)\n    return {\n        \"action_window_steps\": max(1, action_window_steps),\n        \"thinking_interval\": max(1, thinking_interval),\n        \"thinking_steps\": max(1, thinking_steps),\n        \"thinking_enabled\": bool(thinking_enabled),\n        \"no_tool_retry_limit\": max(1, no_tool_retry_limit),\n        \"visible_skills\": visible_skills if isinstance(visible_skills, list) else None,\n        \"max_turns\": max(1, max_turns),\n        \"fresh_enabled\": fresh_enabled,\n        \"fresh_interval_sec\": max(0, fresh_interval_sec),\n    }\n\n\ndef get_context_settings() -> Dict[str, Any]:\n    \"\"\"读取上下文构建相关配置。\"\"\"\n    cfg = load_user_app_config()\n    context = cfg.get(\"context\", {}) if isinstance(cfg, dict) else {}\n    env_history_threshold = os.environ.get(\"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\", \"\").strip()\n    env_history_recent_items = os.environ.get(\"MLA_USER_HISTORY_RECENT_ITEMS\", \"\").strip()\n    env_structured_agent_threshold = os.environ.get(\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_AGENTS\", \"\").strip()\n    env_structured_token_threshold = os.environ.get(\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_TOKENS\", \"\").strip()\n    return {\n        \"user_history_compress_threshold_tokens\": max(0, int(env_history_threshold or context.get(\"user_history_compress_threshold_tokens\", 1500) or 1500)),\n        \"user_history_recent_items\": max(0, int(env_history_recent_items or context.get(\"user_history_recent_items\", 0) or 0)),\n        \"structured_call_info_compress_threshold_agents\": max(1, int(env_structured_agent_threshold or context.get(\"structured_call_info_compress_threshold_agents\", 10) or 10)),\n        \"structured_call_info_compress_threshold_tokens\": max(0, int(env_structured_token_threshold or context.get(\"structured_call_info_compress_threshold_tokens\", 2200) or 2200)),\n    }\n\n\n\ndef get_default_command_mode() -> str:\n    \"\"\"\n    获取 execute_command 默认模式。\n    优先级：\n    1. MLA_EXECUTE_COMMAND_MODE 环境变量\n    2. ~/mla_v3/config/app_config.json 中 env.command_mode\n    3. direct\n    \"\"\"\n    env_mode = os.environ.get(\"MLA_EXECUTE_COMMAND_MODE\", \"\").strip().lower()\n    if env_mode:\n        return env_mode\n\n    cfg = load_user_app_config()\n    mode = str(cfg.get(\"env\", {}).get(\"command_mode\", \"\")).strip().lower()\n    return mode or \"direct\"\n\n\ndef get_seed_builtin_resources_enabled() -> bool:\n    env_value = os.environ.get(\"MLA_SEED_BUILTIN_RESOURCES\", \"\").strip().lower()\n    if env_value:\n        return env_value in {\"1\", \"true\", \"yes\", \"on\"}\n    cfg = load_user_app_config()\n    return bool(cfg.get(\"env\", {}).get(\"seed_builtin_resources\", True))\n\n\ndef apply_runtime_env_defaults() -> None:\n    \"\"\"\n    为 Python 运行时补齐统一环境变量。\n    让 CLI / Desktop / 打包后端都默认指向用户目录，而非仓库本地目录。\n    \"\"\"\n    ensure_user_data_root_scaffold()\n    ensure_user_app_config_exists()\n    if get_seed_builtin_resources_enabled():\n        seed_user_resources_if_missing()\n    os.environ[\"MLA_USER_DATA_ROOT\"] = str(get_user_data_root())\n    os.environ[\"MLA_LLM_CONFIG_PATH\"] = str(ensure_user_llm_config_exists())\n    agent_library_root = os.environ.get(\"MLA_AGENT_LIBRARY_DIR\", \"\").strip()\n    if agent_library_root:\n        os.environ[\"MLA_AGENT_LIBRARY_DIR\"] = str(Path(agent_library_root).expanduser().resolve())\n    else:\n        os.environ[\"MLA_AGENT_LIBRARY_DIR\"] = str(get_user_data_root())\n    os.environ[\"MLA_SKILLS_LIBRARY_DIR\"] = str(get_user_skills_library_root())\n    os.environ[\"MLA_TOOLS_LIBRARY_DIR\"] = str(get_user_tools_library_root())\n    os.environ[\"MLA_EXECUTE_COMMAND_MODE\"] = get_default_command_mode()\n    os.environ[\"MLA_SEED_BUILTIN_RESOURCES\"] = \"true\" if get_seed_builtin_resources_enabled() else \"false\"\n    runtime = get_runtime_settings()\n    context = get_context_settings()\n    os.environ[\"MLA_ACTION_WINDOW_STEPS\"] = str(runtime[\"action_window_steps\"])\n    os.environ[\"MLA_THINKING_INTERVAL\"] = str(runtime[\"thinking_interval\"])\n    os.environ[\"MLA_THINKING_STEPS\"] = str(runtime[\"thinking_steps\"])\n    os.environ[\"MLA_THINKING_ENABLED\"] = \"true\" if runtime[\"thinking_enabled\"] else \"false\"\n    os.environ[\"MLA_NO_TOOL_RETRY_LIMIT\"] = str(runtime[\"no_tool_retry_limit\"])\n    if runtime.get(\"visible_skills\") is not None:\n        os.environ[\"MLA_VISIBLE_SKILLS_JSON\"] = json.dumps(runtime[\"visible_skills\"], ensure_ascii=False)\n    os.environ[\"MLA_MAX_TURNS\"] = str(runtime[\"max_turns\"])\n    os.environ[\"MLA_FRESH_ENABLED\"] = \"true\" if runtime[\"fresh_enabled\"] else \"false\"\n    os.environ[\"MLA_FRESH_INTERVAL_SEC\"] = str(runtime[\"fresh_interval_sec\"])\n    os.environ[\"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\"] = str(context[\"user_history_compress_threshold_tokens\"])\n    os.environ[\"MLA_USER_HISTORY_RECENT_ITEMS\"] = str(context[\"user_history_recent_items\"])\n    os.environ[\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_AGENTS\"] = str(context[\"structured_call_info_compress_threshold_agents\"])\n    os.environ[\"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_TOKENS\"] = str(context[\"structured_call_info_compress_threshold_tokens\"])\n    mcp = get_mcp_settings()\n    if mcp:\n        os.environ[\"MLA_MCP_CONFIG_JSON\"] = json.dumps(mcp, ensure_ascii=False)\n\n\n@contextmanager\ndef runtime_env_scope(overrides: Optional[Dict[str, Any]] = None) -> Iterator[None]:\n    \"\"\"\n    在一个受控作用域内切换运行时环境变量，并自动恢复现场。\n\n    适用于 SDK 多实例场景，避免一个实例污染另一个实例的 user_data_root / 配置路径。\n    \"\"\"\n    overrides = overrides or {}\n    tracked_keys = {\n        \"MLA_USER_DATA_ROOT\",\n        \"MLA_LLM_CONFIG_PATH\",\n        \"MLA_AGENT_LIBRARY_DIR\",\n        \"MLA_SKILLS_LIBRARY_DIR\",\n        \"MLA_TOOLS_LIBRARY_DIR\",\n        \"MLA_ACTION_WINDOW_STEPS\",\n        \"MLA_THINKING_INTERVAL\",\n        \"MLA_THINKING_STEPS\",\n        \"MLA_THINKING_ENABLED\",\n        \"MLA_NO_TOOL_RETRY_LIMIT\",\n        \"MLA_MAX_TURNS\",\n        \"MLA_FRESH_ENABLED\",\n        \"MLA_FRESH_INTERVAL_SEC\",\n        \"MLA_USER_HISTORY_COMPRESS_THRESHOLD_TOKENS\",\n        \"MLA_USER_HISTORY_RECENT_ITEMS\",\n        \"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_AGENTS\",\n        \"MLA_STRUCTURED_CALL_INFO_COMPRESS_THRESHOLD_TOKENS\",\n        \"MLA_MCP_CONFIG_JSON\",\n        \"MLA_EXECUTE_COMMAND_MODE\",\n        \"MLA_SEED_BUILTIN_RESOURCES\",\n        \"MLA_CONTEXT_HOOKS_JSON\",\n        \"MLA_VISIBLE_SKILLS_JSON\",\n    }\n    tracked_keys.update(str(key) for key in overrides.keys())\n    previous = {key: os.environ.get(key) for key in tracked_keys}\n\n    try:\n        for key, value in overrides.items():\n            if value is None:\n                os.environ.pop(str(key), None)\n            else:\n                os.environ[str(key)] = str(value)\n        apply_runtime_env_defaults()\n        yield\n    finally:\n        for key, value in previous.items():\n            if value is None:\n                os.environ.pop(key, None)\n            else:\n                os.environ[key] = value\n"
  },
  {
    "path": "utils/windows_compat.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nWindows兼容性工具\n确保emoji和中文字符能在Windows控制台正常显示\n\"\"\"\nimport sys\n\n\ndef setup_console_encoding():\n    \"\"\"设置控制台为UTF-8编码（Windows专用），并启用实时输出\"\"\"\n    if sys.platform == 'win32':\n        try:\n            import io\n            # 强制行缓冲和立即写入，避免输出延迟\n            if hasattr(sys.stdout, 'buffer'):\n                sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', line_buffering=True, write_through=True)\n            if hasattr(sys.stderr, 'buffer'):\n                sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', line_buffering=True, write_through=True)\n        except Exception:\n            # 如果设置失败，不影响程序运行\n            pass\n\n\ndef safe_print(*args, **kwargs):\n    \"\"\"\n    安全的print函数，自动flush避免Windows缓冲区问题\n    \"\"\"\n    print(*args, **kwargs)\n    if sys.platform == 'win32':\n        try:\n            sys.stdout.flush()\n            sys.stderr.flush()\n        except Exception:\n            pass\n\n\n# 自动设置（导入时执行）\nsetup_console_encoding()\n\n"
  },
  {
    "path": "web_ui/README.md",
    "content": "# MLA-V3 Web UI\n\n这是一个简单的 Web 前端界面，用于与 MLA-V3 框架进行交互。\n\n## 功能特性\n\n- 🎨 现代化的对话界面\n- 🤖 显示当前执行的 Agent（带头像）\n- 📂 显示 Task ID 和 Workspace 路径\n- 🧭 **可视化入口 Agent 选择器**：在 Task ID 左侧选择对话入口智能体，并实时展示该智能体为根的 Agent Tree\n- 📊 实时流式输出（JSONL 事件流）\n- 🔔 **Human-in-Loop (HIL) 交互支持**：自动检测并响应 Agent 的人类交互任务\n- 💬 支持多行输入和 Enter 发送\n- 💾 对话历史自动保存到 `task_id/conversations/` 目录\n- 📁 集成文件浏览器，可查看和管理任务文件\n\n## 安装依赖\n\n```bash\npip install flask flask-cors\n```\n\n或者添加到 `requirements.txt`：\n\n```\nflask\nflask-cors\n```\n\n## 启动方式\n\n### 方法 1：使用便捷脚本（推荐）\n\n**注意**：当前版本使用进程内 `direct-tools` 运行时，不需要单独启动工具服务器。首次运行时会询问您设置工作空间路径（Workspace Root）。\n\n1. 启动服务器（会自动启动 Web UI 服务并调用 Python 后端）：\n   - 首次运行时会提示输入工作空间路径\n   - 直接回车将使用当前目录作为工作空间（与 CLI 模式相同）\n   - 或输入绝对路径指定自定义工作空间\n   ```bash\n   cd web_ui/server\n   ./start.sh\n   ```\n   或者使用统一管理脚本：\n   ```bash\n   cd web_ui/server\n   ./server start\n   ```\n\n2. 停止服务器：\n   ```bash\n   cd web_ui/server\n   ./stop.sh\n   ```\n   或者：\n   ```bash\n   cd web_ui/server\n   ./server stop\n   ```\n\n3. 查看服务器状态：\n   ```bash\n   cd web_ui/server\n   ./server status\n   ```\n   会显示 Web UI 运行状态。\n\n4. 重启服务器：\n   ```bash\n   cd web_ui/server\n   ./server restart\n   ```\n\n5. 打开浏览器访问：\n   ```\n   http://localhost:22228\n   ```\n   \n   **服务器地址**：\n   - Web UI: http://localhost:22228\n\n### 方法 2：直接运行 Python（传统方式）\n\n**注意**：如果使用此方法，只需要启动 Web UI 服务；工具调用由 Python 后端进程内完成。\n\n1. 启动 Web UI 服务器：\n   ```bash\n   cd web_ui/server\n   python server.py\n   ```\n\n2. 打开浏览器访问：\n   ```\n   http://localhost:22228\n   ```\n\n### 端口配置\n\n- **Web UI 默认端口**: 22228（因为 macOS 的 AirPlay 可能占用 5000 端口）\n- 可以通过环境变量指定其他端口：\n  ```bash\n  cd web_ui/server\n  PORT=8080 ./start.sh\n  # 或\n  PORT=8080 ./server start\n  ```\n\n## 使用说明\n\n<p align=\"center\">\n  Web UI walkthrough video is distributed outside git to keep repository size under control.\n</p>\n\n### 1. 设置 Task ID\n\n在顶部的 \"Task ID\" 输入框中输入任务目录的绝对路径，例如：\n```\n/mla_task\n```\n或\n```\n/Users/username/Desktop/my_project\n```\n\n### 2. Agent 配置\n\n- **入口 Agent 选择**：\n  - 在 Task ID 左侧有一个 **Select Agent** 按钮，默认入口 Agent 为 `alpha_agent`\n  - 点击后会弹出 Agent 选择面板，左侧展示所有可用 Agent 列表，右侧展示以当前选中 Agent 作为根节点的 **Agent Tree**\n  - 你可以通过列表选择任意 Agent 作为本次对话的入口智能体，后续所有对话都会从该 Agent 开始编排调用\n  - 选择结果会保存在浏览器本地（localStorage），刷新页面后仍会保持\n- **Agent 系统**：\n  - 当前版本默认使用 `Researcher` 系统（`config/agent_library/Researcher`）\n  - Agent 体系结构请参考主仓库 `README` 中的配置说明\n\n### 3. 输入任务\n\n在底部的输入框中输入任务描述，例如：\n```\n帮我找一篇关于 ECM 的论文\n```\n\n然后点击 \"发送\" 按钮或按 Enter 键（Shift+Enter 换行）。\n\n### 4. 查看输出\n\nAgent 的执行输出会实时显示在对话窗口中：\n- 每条消息显示 Agent 头像和名称\n- 不同类型的消息有不同的颜色：\n  - 🔧 工具调用（tool_call）：青色\n  - 🤖 子 Agent 调用（agent_call）：蓝色\n  - ✅ 成功消息：青色\n  - ❌ 错误消息：红色\n  - ⚠️ 警告消息：黄色\n  - 📊 结果消息：橙色\n  - 💭 思考消息：紫色\n\n### 5. Human-in-Loop (HIL) 交互\n\n当 Agent 需要人工输入时：\n- 输入框会自动显示红色闪烁效果\n- 输入框 placeholder 会显示 Agent 的指令\n- Send 按钮自动启用（即使输入框为空）\n- 在输入框中输入响应并点击 Send\n- Agent 会继续执行任务\n\n**工作流程**：\n1. Agent 调用 `human_in_loop` 工具\n2. 前端自动检测到 HIL 任务\n3. 输入框显示红色闪烁提示\n4. 用户输入响应并发送\n5. Agent 继续执行\n\n## 界面说明\n\n### 顶部控制栏\n- **Select Agent**：入口智能体选择按钮，点击后可在弹窗中选择对话入口 Agent，并查看对应 Agent Tree\n- **Task ID**: 任务工作目录路径（支持任务选择下拉框）\n- **Agent**: 当前选中的入口 Agent（默认 `alpha_agent`）\n- **System**: 默认使用 `Researcher` 系统，可切换到 `OpenCowork`\n- **文件浏览器**: 右侧可浏览和管理任务文件\n\n### 对话窗口\n- 显示所有消息（用户输入和 Agent 输出）\n- 自动滚动到最新消息\n- 支持长文本和多行显示\n\n### 输入区域\n- 文本输入框（支持多行）\n  - 正常状态：蓝色边框\n  - HIL 等待状态：红色闪烁边框\n- 发送按钮\n  - 有内容时自动启用\n  - HIL 模式下始终启用\n- 状态栏（显示运行状态和 Workspace 路径）\n\n## 技术架构\n\n- **后端**: Flask + Server-Sent Events (SSE)\n- **前端**: 原生 HTML + CSS + JavaScript\n- **事件流**: 直接解析 JSONL 事件流（`--jsonl` 模式）\n- **流式传输**: 使用 SSE 实现实时输出\n- **HIL 支持**: 事件触发 + 智能轮询检测机制\n- **数据存储**: 对话历史存储在 `task_id/conversations/` 目录\n\n## 文件结构\n\n```\nweb_ui/\n├── server/                    # 服务器相关文件\n│   ├── server.py              # Flask 后端服务器\n│   ├── start.sh               # 启动脚本（支持 workspace 配置）\n│   ├── stop.sh                # 停止脚本\n│   └── users.yaml             # 用户认证配置\n├── index.html                 # 前端页面\n├── login.html                 # 登录页面\n├── static/                    # 静态资源\n│   ├── style.css             # 样式文件\n│   └── app.js                # JavaScript 逻辑（包含 HIL 检测）\n├── requirements.txt           # Python 依赖\n└── README.md                 # 使用说明\n```\n\n## 数据存储\n\n### 存储位置\n\n系统使用两个存储位置来管理不同类别的数据：\n\n#### 1. Workspace 目录 (`{task_id}/`)\n\n任务工作目录，存储任务相关的工作文件：\n\n```\n{task_id}/\n├── temp/                      # 临时文件目录\n├── code_run/                  # 代码执行目录\n├── code_env/                  # 代码环境目录\n├── reference.bib              # 参考文件\n├── chat_history.json          # Web UI 聊天记录（前端显示）\n└── latest_output.json         # 最新输出（用于快速预览）\n```\n\n**注意**：删除 `task_id` 目录会删除所有任务相关的工作文件和 Web UI 聊天记录。\n\n#### 2. 主目录 (`~/mla_v3/conversations/`)\n\nAgent 对话历史和状态存储位置：\n\n```\n~/mla_v3/conversations/\n├── {task_hash}_{task_folder}_stack.json           # Agent 调用栈\n├── {task_hash}_{task_folder}_share_context.json   # 共享上下文\n└── {task_hash}_{task_folder}_{agent_id}_actions.json  # Agent 动作历史\n```\n\n其中：\n- `task_hash`: task_id 的 MD5 前 8 位\n- `task_folder`: 如果 task_id 是路径，取最后一级文件夹名；否则使用 task_id 本身\n- `agent_id`: Agent 的唯一标识符\n\n**注意**：删除此目录会删除所有任务的 Agent 对话历史。如果要清理特定任务的历史，可以根据文件名前缀（`{task_hash}_{task_folder}`）来识别和删除。\n\n## 故障排除\n\n### 1. 无法连接到服务器\n- 检查服务器是否正在运行\n- 检查端口 5000 是否被占用\n- 查看服务器终端的错误信息\n\n### 2. Agent 执行失败\n- 检查 Task ID 路径是否正确\n- 检查工具服务器是否正常运行\n- 查看浏览器控制台的错误信息\n\n### 3. 输出不显示\n- 检查浏览器控制台是否有 JavaScript 错误\n- 检查 SSE 连接是否正常（Network 标签页）\n- 查看服务器日志\n\n### 4. HIL 任务无响应\n- 确认工具服务器正在运行（检查端口 8001/8002）\n- 检查浏览器控制台是否有错误信息\n- 刷新页面重试\n\n### 5. 工作空间路径问题\n- 确保路径是绝对路径\n- 检查路径是否有写权限\n- 重新运行 `start.sh` 配置正确的 workspace\n\n## 开发说明\n\n### 修改端口\n\n在 `server.py` 中修改：\n```python\nport = int(os.environ.get('PORT', 5000))\n```\n\n或通过环境变量：\n```bash\nPORT=8080 python server.py\n```\n\n### 添加新的 Agent 头像\n\n在 `app.js` 中的 `agentAvatars` 对象中添加：\n```javascript\nconst agentAvatars = {\n    'your_agent': '🎯',\n    // ...\n};\n```\n\n### 自定义样式\n\n修改 `static/style.css` 文件来自定义界面样式。\n\n## 许可证\n\n与主项目相同。\n"
  },
  {
    "path": "web_ui/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>MLA-V3 - Web UI</title>\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='style.css') }}?v=20260322-thinking-fix-2\">\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <div class=\"header-content\">\n                <h1>MLA-V3</h1>\n                <div style=\"display: flex; align-items: center; gap: 15px;\">\n                    <span id=\"username-display\" class=\"username-badge\"></span>\n                    <button id=\"users-btn\" class=\"btn-secondary\" title=\"User Management\" style=\"display:none;\"><i class=\"fas fa-users\"></i> Users</button>\n                    <button id=\"logout-btn\" class=\"btn-secondary logout-btn\">Logout</button>\n                </div>\n                <div class=\"controls\">\n                    <div class=\"control-group\">\n                        <label for=\"task-id\">Task ID:</label>\n                        <div style=\"display: flex; gap: 8px; align-items: stretch;\">\n                            <select id=\"agent-system-select\" class=\"btn-secondary\" title=\"Select Agent System\" style=\"min-width: 120px;\">\n                                <option value=\"Researcher\">Researcher</option>\n                            </select>\n                            <button id=\"agent-select-btn\" class=\"btn-secondary\" title=\"Select Agent\" style=\"min-width: 150px; white-space: nowrap;\">\n                                <i class=\"fas fa-robot\"></i> <span id=\"agent-select-text\">alpha_agent</span>\n                            </button>\n                            <select id=\"task-select\" style=\"min-width: 150px;\">\n                                <option value=\"\">Select existing task</option>\n                            </select>\n                            <input type=\"text\" id=\"task-id\" placeholder=\"task_name\" value=\"\" style=\"flex: 1;\">\n                            <button id=\"confirm-task-btn\" class=\"btn-primary\">Confirm</button>\n                            <button id=\"resume-task-btn\" class=\"btn-secondary\" title=\"Resume interrupted task\"><i class=\"fas fa-play-circle\"></i> Resume</button>\n                            <button id=\"clear-task-btn\" class=\"btn-danger\">Clear Task</button>\n                            <button id=\"copy-task-btn\" class=\"btn-secondary\">Copy Task</button>\n                            <button id=\"download-task-btn\" class=\"btn-secondary\">Download Task</button>\n                            <button id=\"config-btn\" class=\"btn-secondary\" title=\"Configuration\"><i class=\"fas fa-cog\"></i> Config</button>\n                            <button id=\"tools-btn\" class=\"btn-secondary\" title=\"Manage Python Tools\"><i class=\"fas fa-wrench\"></i> Tools</button>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n        <!-- Configuration Modal -->\n        <div id=\"config-modal\" class=\"config-modal\" style=\"display: none;\">\n            <div class=\"config-modal-content\">\n                <div class=\"config-modal-header\">\n                    <h2><i class=\"fas fa-cog\"></i> Configuration</h2>\n                    <button id=\"close-config-btn\" class=\"btn-icon\" title=\"Close\"><i class=\"fas fa-times\"></i></button>\n                </div>\n                <div class=\"config-modal-body\">\n                    <div class=\"config-sidebar\">\n                        <div class=\"config-section\">\n                            <div class=\"config-section-header\">\n                                <i class=\"fas fa-server\"></i> Run Environment Config\n                            </div>\n                            <div class=\"config-file-list\" id=\"run-env-config-list\">\n                                <!-- Files will be loaded dynamically -->\n                            </div>\n                        </div>\n                        <div class=\"config-section\">\n                            <div class=\"config-section-header\">\n                                <i class=\"fas fa-robot\"></i> Agent Config\n                            </div>\n                            <div class=\"config-file-list\" id=\"agent-config-list\">\n                                <!-- Files will be loaded dynamically -->\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"config-editor\">\n                        <div class=\"config-editor-header\">\n                            <div class=\"config-tabs\" id=\"config-tabs\">\n                                <button class=\"config-tab active\" data-tab=\"guided\">\n                                    <i class=\"fas fa-sliders-h\"></i> Beginner\n                                </button>\n                                <button class=\"config-tab\" data-tab=\"editor\">\n                                    <i class=\"fas fa-edit\"></i> Editor\n                                </button>\n                                <button class=\"config-tab\" data-tab=\"tree\" id=\"agent-tree-tab\">\n                                    <i class=\"fas fa-sitemap\"></i> Agent Tree\n                                </button>\n                            </div>\n                            <div class=\"config-editor-actions\" id=\"config-editor-actions\">\n                                <span id=\"config-file-name\" class=\"config-file-name\">llm_config.yaml</span>\n                                <div class=\"config-editor-buttons\">\n                                    <button id=\"save-config-btn\" class=\"btn-primary\"><i class=\"fas fa-save\"></i> Save</button>\n                                    <button id=\"reload-config-btn\" class=\"btn-secondary\"><i class=\"fas fa-sync-alt\"></i> Reload</button>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"config-editor-content\" id=\"config-editor-content\">\n                            <div class=\"config-tab-content active\" id=\"tab-guided\">\n                                <div class=\"config-guided-scroll\">\n                                    <div class=\"tools-help\" style=\"margin-bottom: 18px;\">\n                                        Beginner mode edits <code>llm_config.yaml</code> and <code>app_config.json</code> together.\n                                        Use it for provider selection, model slots, thinking mode, compression and history limits.\n                                        Advanced YAML/JSON edits are still available in the Editor tab.\n                                    </div>\n\n                                    <div class=\"guided-section-card\">\n                                        <h3><i class=\"fas fa-brain\"></i> Model Profiles</h3>\n                                        <div class=\"form-hint-block\" style=\"margin-bottom:12px;\">\n                                            Default <code>base_url</code> / <code>api_key</code> are configured below and reused by any row whose source is set to default.\n                                            Shared Models are materialized into all five model slots when saved.\n                                        </div>\n\n                                        <details class=\"tool-details\" open>\n                                            <summary class=\"tool-params-toggle\">Shared Models (apply to all slots)</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Add shared candidates once and they will appear in every slot.</span>\n                                                <button id=\"add-shared-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Shared Model</button>\n                                            </div>\n                                            <div id=\"model-shared-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <details class=\"tool-details\" open>\n                                            <summary class=\"tool-params-toggle\">Main Models</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Primary execution models.</span>\n                                                <button id=\"add-main-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Main Model</button>\n                                            </div>\n                                            <div id=\"model-main-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <details class=\"tool-details\">\n                                            <summary class=\"tool-params-toggle\">Read Figure Models</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Vision / image understanding models.</span>\n                                                <button id=\"add-read-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Read Figure Model</button>\n                                            </div>\n                                            <div id=\"model-read-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <details class=\"tool-details\">\n                                            <summary class=\"tool-params-toggle\">Figure Generation Models</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Image generation models.</span>\n                                                <button id=\"add-figure-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Figure Model</button>\n                                            </div>\n                                            <div id=\"model-figure-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <details class=\"tool-details\">\n                                            <summary class=\"tool-params-toggle\">Compressor Models</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Compression and summarization models.</span>\n                                                <button id=\"add-compressor-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Compressor Model</button>\n                                            </div>\n                                            <div id=\"model-compressor-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <details class=\"tool-details\">\n                                            <summary class=\"tool-params-toggle\">Thinking Models</summary>\n                                            <div class=\"model-slot-toolbar\">\n                                                <span class=\"form-hint\">Thinking Agent specific models.</span>\n                                                <button id=\"add-thinking-model-btn\" class=\"btn-secondary\" type=\"button\">+ Add Thinking Model</button>\n                                            </div>\n                                            <div id=\"model-thinking-list\" class=\"model-slot-list\"></div>\n                                        </details>\n\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Shared Base URL</label>\n                                                <input type=\"text\" id=\"guided-base-url\" class=\"form-input\" placeholder=\"Optional fallback base URL\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Shared API Key</label>\n                                                <input type=\"text\" id=\"guided-api-key\" class=\"form-input\" placeholder=\"Optional fallback API key\">\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Temperature</label>\n                                                <input type=\"number\" id=\"guided-temperature\" class=\"form-input\" step=\"0.1\" min=\"0\" max=\"2\" placeholder=\"0\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Max Tokens</label>\n                                                <input type=\"number\" id=\"guided-max-tokens\" class=\"form-input\" placeholder=\"0 = auto\">\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Max Context Window</label>\n                                                <input type=\"number\" id=\"guided-max-context\" class=\"form-input\" placeholder=\"500000\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Timeout (seconds)</label>\n                                                <input type=\"number\" id=\"guided-timeout\" class=\"form-input\" placeholder=\"600\">\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Stream Timeout (seconds)</label>\n                                                <input type=\"number\" id=\"guided-stream-timeout\" class=\"form-input\" placeholder=\"30\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">First Chunk Timeout (seconds)</label>\n                                                <input type=\"number\" id=\"guided-first-chunk-timeout\" class=\"form-input\" placeholder=\"30\">\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\"><input type=\"checkbox\" id=\"guided-multimodal\"> Multimodal</label>\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\"><input type=\"checkbox\" id=\"guided-compressor-multimodal\"> Compressor Multimodal</label>\n                                            </div>\n                                        </div>\n                                    </div>\n\n                                    <div class=\"guided-section-card\">\n                                        <h3><i class=\"fas fa-bolt\"></i> Runtime & History</h3>\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\"><input type=\"checkbox\" id=\"guided-thinking-enabled\"> Enable Thinking Agent Mode</label>\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Thinking Steps</label>\n                                                <input type=\"number\" id=\"guided-thinking-steps\" class=\"form-input\" min=\"1\" placeholder=\"30\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">No-tool Retry Limit</label>\n                                                <input type=\"number\" id=\"guided-no-tool-retry-limit\" class=\"form-input\" min=\"1\" placeholder=\"7\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Max Turns</label>\n                                                <input type=\"number\" id=\"guided-max-turns\" class=\"form-input\" min=\"1\" placeholder=\"100000\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">User History Compress Threshold</label>\n                                                <input type=\"number\" id=\"guided-user-history-threshold\" class=\"form-input\" min=\"0\" placeholder=\"1500\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Recent History Items</label>\n                                                <input type=\"number\" id=\"guided-user-history-recent-items\" class=\"form-input\" min=\"0\" placeholder=\"0 = all history\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-row\">\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Structured Call Agent Threshold</label>\n                                                <input type=\"number\" id=\"guided-structured-call-agent-threshold\" class=\"form-input\" min=\"1\" placeholder=\"10\">\n                                            </div>\n                                            <div class=\"form-group form-half\">\n                                                <label class=\"form-label\">Structured Call Token Threshold</label>\n                                                <input type=\"number\" id=\"guided-structured-call-token-threshold\" class=\"form-input\" min=\"0\" placeholder=\"2200\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"form-label\">Visible Skills <span class=\"form-hint\">(one per line)</span></label>\n                                            <textarea id=\"guided-visible-skills\" class=\"form-input\" rows=\"4\" placeholder=\"browser-use&#10;paper-analyze\"></textarea>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"config-tab-content\" id=\"tab-editor\">\n                                <textarea id=\"config-editor-textarea\" placeholder=\"Loading configuration...\"></textarea>\n                            </div>\n                            <div class=\"config-tab-content\" id=\"tab-tree\">\n                                <div class=\"agent-tree-container\" id=\"agent-tree-container\">\n                                    <div class=\"agent-tree-loading\">Loading agent tree...</div>\n                                </div>\n                            </div>\n                            <div class=\"config-status\" id=\"config-status\"></div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n        <!-- Tools Modal -->\n        <div id=\"tools-modal\" class=\"config-modal\" style=\"display: none;\">\n            <div class=\"config-modal-content tools-modal-content\">\n                <div class=\"config-modal-header\">\n                    <h2><i class=\"fas fa-wrench\"></i> Runtime Tools</h2>\n                    <button id=\"close-tools-btn\" class=\"btn-icon\" title=\"Close\"><i class=\"fas fa-times\"></i></button>\n                </div>\n                <div class=\"tools-modal-body\">\n                    <div class=\"tools-toolbar\">\n                        <button id=\"upload-tool-btn\" class=\"btn-primary\"><i class=\"fas fa-upload\"></i> Upload Python Tool</button>\n                        <button id=\"reload-tools-btn\" class=\"btn-secondary\"><i class=\"fas fa-sync-alt\"></i> Reload Registry</button>\n                    </div>\n                    <div class=\"tools-help\">\n                        Upload a Python file that defines one public tool class. Tool description and parameters are still controlled by your `agent_library` YAML files.\n                    </div>\n                    <div id=\"tools-status\" class=\"config-status\"></div>\n                    <div id=\"tools-list\" class=\"tools-list\"></div>\n                </div>\n            </div>\n            <input type=\"file\" id=\"tool-upload-input\" style=\"display: none;\" accept=\".py\">\n        </div>\n\n        <!-- User Management Modal -->\n        <div id=\"users-modal\" class=\"config-modal\" style=\"display: none;\">\n            <div class=\"config-modal-content tools-modal-content\">\n                <div class=\"config-modal-header\">\n                    <h2><i class=\"fas fa-users\"></i> User Management</h2>\n                    <button id=\"close-users-btn\" class=\"btn-icon\" title=\"Close\"><i class=\"fas fa-times\"></i></button>\n                </div>\n                <div class=\"tools-modal-body\">\n                    <div class=\"tools-toolbar\">\n                        <button id=\"new-user-btn\" class=\"btn-primary\"><i class=\"fas fa-user-plus\"></i> New User</button>\n                        <button id=\"reload-users-btn\" class=\"btn-secondary\"><i class=\"fas fa-sync-alt\"></i> Reload</button>\n                    </div>\n                    <div id=\"users-status\" class=\"config-status\"></div>\n                    <div class=\"users-admin-grid\">\n                        <div class=\"users-list-panel\">\n                            <div id=\"users-list\" class=\"tools-list\"></div>\n                        </div>\n                        <div class=\"users-editor-panel\">\n                            <div class=\"form-group\">\n                                <label class=\"form-label\" for=\"admin-user-username\">Username</label>\n                                <input type=\"text\" id=\"admin-user-username\" class=\"form-input\" placeholder=\"new_user\">\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"form-label\" for=\"admin-user-password\">Password</label>\n                                <input type=\"password\" id=\"admin-user-password\" class=\"form-input\" placeholder=\"Leave empty to keep unchanged\">\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"form-label\" for=\"admin-user-role\">Role</label>\n                                <select id=\"admin-user-role\" class=\"form-input\">\n                                    <option value=\"user\">user</option>\n                                    <option value=\"admin\">admin</option>\n                                </select>\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"form-label\"><input type=\"checkbox\" id=\"admin-user-enabled\" checked> Enabled</label>\n                            </div>\n                            <div class=\"tools-toolbar\">\n                                <button id=\"save-user-btn\" class=\"btn-primary\"><i class=\"fas fa-save\"></i> Save</button>\n                                <button id=\"delete-user-btn\" class=\"btn-danger\"><i class=\"fas fa-trash\"></i> Delete</button>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n        <!-- Agent Selection Modal -->\n        <div id=\"agent-select-modal\" class=\"agent-select-modal\" style=\"display: none;\">\n            <div class=\"agent-select-modal-content\">\n                <div class=\"agent-select-modal-header\">\n                    <h2><i class=\"fas fa-robot\"></i> Select Agent</h2>\n                    <button id=\"close-agent-select-btn\" class=\"btn-icon\" title=\"Close\"><i class=\"fas fa-times\"></i></button>\n                </div>\n                <div class=\"agent-select-modal-body\">\n                    <div class=\"agent-select-left\">\n                        <div class=\"agent-select-search\">\n                            <input type=\"text\" id=\"agent-search-input\" placeholder=\"Search agents...\" autocomplete=\"off\">\n                        </div>\n                        <div class=\"agent-select-list\" id=\"agent-select-list\">\n                            <div class=\"agent-select-loading\">Loading agents...</div>\n                        </div>\n                    </div>\n                    <div class=\"agent-select-right\" id=\"agent-tree-panel\">\n                        <div class=\"agent-tree-panel-header\">\n                            <h3><i class=\"fas fa-sitemap\"></i> Agent Tree</h3>\n                        </div>\n                        <div class=\"agent-tree-panel-content\" id=\"agent-tree-panel-content\">\n                            <div class=\"agent-tree-empty\">Select an agent to view tree</div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"main-content\">\n            <div class=\"chat-wrapper\">\n                <div class=\"chat-container\">\n                    <div id=\"messages\" class=\"messages\">\n                        <div class=\"welcome-message\" id=\"welcome-message\" style=\"display: none;\">\n                            <p><i class=\"fas fa-hand-wave\"></i> Welcome to MLA-V3 Web UI</p>\n                            <p>Please set Task ID above, then enter a task to start conversation.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"input-container\">\n                    <div class=\"input-wrapper\">\n                        <textarea id=\"user-input\" placeholder=\"Enter task description...\" rows=\"2\"></textarea>\n                        <button id=\"stop-btn\" class=\"btn-danger\" style=\"display: none;\">Stop</button>\n                        <button id=\"send-btn\" class=\"btn-primary\">Send</button>\n                    </div>\n                    <div class=\"status-bar\">\n                        <span id=\"status-text\">Ready</span>\n                        <span id=\"workspace-path\" class=\"workspace\"></span>\n                    </div>\n                </div>\n            </div>\n\n            <div class=\"file-browser\">\n                <div class=\"file-browser-header\">\n                    <h3><i class=\"fas fa-folder\"></i> File Browser</h3>\n                    <div class=\"file-browser-actions\">\n                        <button id=\"upload-file-btn\" class=\"btn-icon\" title=\"Upload file\"><i class=\"fas fa-upload\"></i></button>\n                        <button id=\"refresh-files-btn\" class=\"btn-icon\" title=\"Refresh\"><i class=\"fas fa-sync-alt\"></i></button>\n                    </div>\n                </div>\n                <div class=\"file-browser-path\" id=\"file-browser-path\">Path not set</div>\n                <div class=\"file-tree\" id=\"file-tree\">\n                    <div class=\"file-tree-empty\">Please set Task ID to view files</div>\n                </div>\n                <div class=\"file-viewer\" id=\"file-viewer\" style=\"display: none;\">\n                    <div class=\"file-viewer-header\">\n                        <span id=\"file-viewer-title\"></span>\n                        <div class=\"file-viewer-actions\">\n                            <button id=\"download-file-btn\" class=\"btn-icon\" title=\"Download file\"><i class=\"fas fa-download\"></i></button>\n                            <button id=\"delete-file-btn\" class=\"btn-icon\" title=\"Delete file\"><i class=\"fas fa-trash\"></i></button>\n                            <button id=\"close-file-btn\" class=\"btn-icon\"><i class=\"fas fa-times\"></i></button>\n                        </div>\n                    </div>\n                    <div class=\"file-viewer-content\" id=\"file-viewer-content\"></div>\n                </div>\n                <input type=\"file\" id=\"file-upload-input\" style=\"display: none;\" multiple>\n            </div>\n        </div>\n    </div>\n\n    <script>\n        (function() {\n            const savedTaskId = localStorage.getItem('mla_task_id');\n            const welcomeMsg = document.getElementById('welcome-message');\n            if (welcomeMsg) {\n                if (!savedTaskId || !savedTaskId.trim()) {\n                    welcomeMsg.style.display = '';\n                }\n            }\n        })();\n    </script>\n    <script src=\"{{ url_for('static', filename='app.js') }}?v=20260322-thinking-fix-2\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "web_ui/login.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Login - MLA-V3</title>\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='style.css') }}?v=20260322-thinking-fix-2\">\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            margin: 0;\n            padding: 0;\n            overflow: hidden;\n            background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1419 100%);\n            min-height: 100vh;\n        }\n        \n        @keyframes fadeIn {\n            from {\n                opacity: 0;\n            }\n            to {\n                opacity: 1;\n            }\n        }\n        \n        .login-container {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1419 100%);\n            position: relative;\n            opacity: 0;\n            animation: fadeInUp 0.5s ease-out 0.1s forwards;\n        }\n        \n        @keyframes fadeInUp {\n            from {\n                opacity: 0;\n                transform: translateY(20px);\n            }\n            to {\n                opacity: 1;\n                transform: translateY(0);\n            }\n        }\n        .login-container::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background: radial-gradient(circle at 50% 50%, rgba(0, 212, 255, 0.05) 0%, transparent 70%);\n            pointer-events: none;\n        }\n        .login-box {\n            background: rgba(20, 30, 50, 0.8);\n            padding: 50px 40px;\n            border-radius: 12px;\n            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(0, 212, 255, 0.2), 0 0 20px rgba(0, 212, 255, 0.1);\n            width: 100%;\n            max-width: 420px;\n            backdrop-filter: blur(10px);\n            border: 1px solid rgba(0, 212, 255, 0.2);\n            position: relative;\n            z-index: 1;\n        }\n        .login-box h1 {\n            color: #ffffff;\n            margin-bottom: 35px;\n            text-align: center;\n            font-size: 24px;\n            font-weight: 600;\n            text-shadow: 0 0 10px rgba(0, 212, 255, 0.3), 0 1px 2px rgba(0, 0, 0, 0.5);\n            letter-spacing: -0.3px;\n        }\n        .login-form {\n            display: flex;\n            flex-direction: column;\n            gap: 24px;\n        }\n        .auth-tabs {\n            display: flex;\n            gap: 8px;\n            margin-bottom: 24px;\n        }\n        .auth-tab {\n            flex: 1;\n            background: rgba(20, 30, 50, 0.55);\n            border: 1px solid rgba(0, 212, 255, 0.18);\n            color: #c8d2de;\n            border-radius: 8px;\n            padding: 10px 12px;\n            cursor: pointer;\n            transition: all 0.2s ease;\n        }\n        .auth-tab.active {\n            color: #00d4ff;\n            border-color: rgba(0, 212, 255, 0.5);\n            box-shadow: 0 0 12px rgba(0, 212, 255, 0.18);\n        }\n        .auth-panel {\n            display: none;\n        }\n        .auth-panel.active {\n            display: block;\n        }\n        .form-group {\n            display: flex;\n            flex-direction: column;\n            gap: 10px;\n        }\n        .form-group label {\n            color: #e0e6ed;\n            font-size: 13px;\n            font-weight: 500;\n        }\n        .form-group input {\n            background: rgba(20, 30, 50, 0.6);\n            border: 1px solid rgba(0, 212, 255, 0.2);\n            color: #e0e6ed;\n            padding: 12px 16px;\n            border-radius: 8px;\n            font-size: 14px;\n            transition: all 0.2s ease;\n            box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n        }\n        .form-group input:focus {\n            outline: none;\n            border-color: #00d4ff;\n            background: rgba(25, 35, 55, 0.8);\n            box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.2), inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 8px rgba(0, 212, 255, 0.15);\n        }\n        .form-group input::placeholder {\n            color: #858585;\n        }\n        .login-btn {\n            background: linear-gradient(135deg, #00b8d4 0%, #0097a7 100%);\n            color: white;\n            border: none;\n            padding: 14px;\n            border-radius: 8px;\n            font-size: 15px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: all 0.2s ease;\n            box-shadow: 0 2px 8px rgba(0, 184, 212, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n            margin-top: 8px;\n        }\n        .login-btn:hover:not(:disabled) {\n            background: linear-gradient(135deg, #00d4ff 0%, #00b8d4 100%);\n            transform: translateY(-1px);\n            box-shadow: 0 4px 12px rgba(0, 212, 255, 0.4), 0 0 12px rgba(0, 212, 255, 0.2);\n        }\n        .login-btn:active:not(:disabled) {\n            transform: translateY(0);\n            box-shadow: 0 2px 8px rgba(0, 184, 212, 0.3);\n        }\n        .login-btn:disabled {\n            background: rgba(60, 60, 60, 0.5);\n            cursor: not-allowed;\n            box-shadow: none;\n        }\n        .error-message {\n            color: #ff6b6b;\n            font-size: 13px;\n            text-align: center;\n            margin-top: 12px;\n            padding: 10px;\n            background: rgba(255, 107, 107, 0.1);\n            border: 1px solid rgba(255, 107, 107, 0.3);\n            border-radius: 6px;\n            box-shadow: 0 0 8px rgba(255, 107, 107, 0.15);\n        }\n        \n        @keyframes fadeOutUp {\n            from {\n                opacity: 1;\n                transform: translateY(0) scale(1);\n            }\n            to {\n                opacity: 0;\n                transform: translateY(-30px) scale(0.95);\n            }\n        }\n        \n        @keyframes fadeOut {\n            from {\n                opacity: 1;\n            }\n            to {\n                opacity: 0;\n            }\n        }\n    </style>\n</head>\n<body style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1419 100%); margin: 0; padding: 0; overflow: hidden; min-height: 100vh;\">\n    <div class=\"login-container\">\n        <div class=\"login-box\">\n            <h1>MLA-V3</h1>\n            <div class=\"auth-tabs\">\n                <button type=\"button\" class=\"auth-tab active\" id=\"tab-login-btn\">Login</button>\n                <button type=\"button\" class=\"auth-tab\" id=\"tab-register-btn\">Register</button>\n            </div>\n            <div class=\"auth-panel active\" id=\"login-panel\">\n                <form class=\"login-form\" id=\"login-form\">\n                    <div class=\"form-group\">\n                        <label for=\"username\">Username</label>\n                        <input type=\"text\" id=\"username\" name=\"username\" required autocomplete=\"username\">\n                    </div>\n                    <div class=\"form-group\">\n                        <label for=\"password\">Password</label>\n                        <input type=\"password\" id=\"password\" name=\"password\" required autocomplete=\"current-password\">\n                    </div>\n                    <button type=\"submit\" class=\"login-btn\" id=\"login-btn\">Login</button>\n                </form>\n            </div>\n            <div class=\"auth-panel\" id=\"register-panel\">\n                <form class=\"login-form\" id=\"register-form\">\n                    <div class=\"form-group\">\n                        <label for=\"register-username\">Username</label>\n                        <input type=\"text\" id=\"register-username\" name=\"register-username\" required autocomplete=\"username\">\n                    </div>\n                    <div class=\"form-group\">\n                        <label for=\"register-password\">Password</label>\n                        <input type=\"password\" id=\"register-password\" name=\"register-password\" required autocomplete=\"new-password\">\n                    </div>\n                    <div class=\"form-group\">\n                        <label for=\"register-password-confirm\">Confirm Password</label>\n                        <input type=\"password\" id=\"register-password-confirm\" name=\"register-password-confirm\" required autocomplete=\"new-password\">\n                    </div>\n                    <button type=\"submit\" class=\"login-btn\" id=\"register-btn\">Create Account</button>\n                </form>\n            </div>\n            <div id=\"error-message\" class=\"error-message\" style=\"display: none;\"></div>\n        </div>\n    </div>\n\n    <script>\n        const loginForm = document.getElementById('login-form');\n        const loginBtn = document.getElementById('login-btn');\n        const registerForm = document.getElementById('register-form');\n        const registerBtn = document.getElementById('register-btn');\n        const errorMessage = document.getElementById('error-message');\n        const tabLoginBtn = document.getElementById('tab-login-btn');\n        const tabRegisterBtn = document.getElementById('tab-register-btn');\n        const loginPanel = document.getElementById('login-panel');\n        const registerPanel = document.getElementById('register-panel');\n\n        function switchAuthTab(mode) {\n            const loginActive = mode === 'login';\n            tabLoginBtn.classList.toggle('active', loginActive);\n            tabRegisterBtn.classList.toggle('active', !loginActive);\n            loginPanel.classList.toggle('active', loginActive);\n            registerPanel.classList.toggle('active', !loginActive);\n            errorMessage.style.display = 'none';\n        }\n\n        tabLoginBtn.addEventListener('click', () => switchAuthTab('login'));\n        tabRegisterBtn.addEventListener('click', () => switchAuthTab('register'));\n\n        loginForm.addEventListener('submit', async (e) => {\n            e.preventDefault();\n            \n            const username = document.getElementById('username').value.trim();\n            const password = document.getElementById('password').value.trim();\n            \n            if (!username || !password) {\n                showError('Please enter username and password');\n                return;\n            }\n            \n            loginBtn.disabled = true;\n            loginBtn.textContent = 'Logging in...';\n            errorMessage.style.display = 'none';\n            \n            try {\n                const response = await fetch('/api/login', {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/json'\n                    },\n                    credentials: 'include',\n                    body: JSON.stringify({\n                        username: username,\n                        password: password\n                    })\n                });\n                \n                const data = await response.json();\n                \n                if (response.ok && data.success) {\n                    const loginBox = document.querySelector('.login-box');\n                    const loginContainer = document.querySelector('.login-container');\n                    \n                    loginBox.style.animation = 'fadeOutUp 0.8s ease-out forwards';\n                    loginContainer.style.animation = 'fadeOut 0.8s ease-out forwards';\n                    \n                    setTimeout(() => {\n                        window.location.href = '/';\n                    }, 350);\n                } else {\n                    showError(data.error || 'Login failed');\n                }\n            } catch (error) {\n                showError('Login failed: ' + error.message);\n            } finally {\n                loginBtn.disabled = false;\n                loginBtn.textContent = 'Login';\n            }\n        });\n\n        registerForm.addEventListener('submit', async (e) => {\n            e.preventDefault();\n\n            const username = document.getElementById('register-username').value.trim();\n            const password = document.getElementById('register-password').value.trim();\n            const confirmPassword = document.getElementById('register-password-confirm').value.trim();\n\n            if (!username || !password) {\n                showError('Please enter username and password');\n                return;\n            }\n            if (password !== confirmPassword) {\n                showError('Passwords do not match');\n                return;\n            }\n\n            registerBtn.disabled = true;\n            registerBtn.textContent = 'Creating...';\n            errorMessage.style.display = 'none';\n\n            try {\n                const response = await fetch('/api/register', {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/json'\n                    },\n                    credentials: 'include',\n                    body: JSON.stringify({\n                        username,\n                        password\n                    })\n                });\n                const data = await response.json();\n                if (response.ok && data.success) {\n                    window.location.href = '/';\n                } else {\n                    showError(data.error || 'Registration failed');\n                }\n            } catch (error) {\n                showError('Registration failed: ' + error.message);\n            } finally {\n                registerBtn.disabled = false;\n                registerBtn.textContent = 'Create Account';\n            }\n        });\n        \n        function showError(message) {\n            errorMessage.textContent = message;\n            errorMessage.style.display = 'block';\n        }\n        \n        (async () => {\n            try {\n                const response = await fetch('/api/check-auth', {\n                    credentials: 'include'\n                });\n                const data = await response.json();\n                if (data.logged_in) {\n                    window.location.href = '/';\n                }\n            } catch (error) {\n                // Ignore error\n            }\n        })();\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "web_ui/requirements.txt",
    "content": "flask>=2.0.0\nflask-cors>=3.0.0\n\n"
  },
  {
    "path": "web_ui/server/output_capture.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nOutput Capture Tool\n\nCaptures output during agent execution process.\n\nAuthor: Songmiao Wang\nMLA System: Chenlin Yu, Songmiao Wang\"\"\"\n\nimport sys\nimport json\nimport re\nfrom typing import Optional, Callable\nfrom io import StringIO\nfrom datetime import datetime\n\n\nclass OutputCapture:\n    \"\"\"Output capture class - captures stdout/stderr and EventEmitter events\"\"\"\n    \n    def __init__(self, callback: Callable[[dict], None], agent_name: str = \"unknown\"):\n        \"\"\"\n        Args:\n            callback: Callback function called when there is output, receives a dict with type, agent, content, timestamp\n            agent_name: Currently executing agent name\n        \"\"\"\n        self.callback = callback\n        self.agent_name = agent_name\n        self.original_stdout = sys.stdout\n        self.original_stderr = sys.stderr\n        self.buffer = StringIO()\n        self.current_agent = agent_name\n        \n        # Output buffer - for merging similar messages\n        self.output_buffer = []\n        self.last_output_time = 0\n        self.buffer_timeout = 0.5  # Output buffer content after 0.5 seconds\n        \n        # Maintain most recent calling agent name (for parameter lines and JSON content)\n        self.last_call_agent = None\n        \n        # Call buffer: stores tool/agent call message, waiting for parameters\n        self.call_buffer = None\n        \n        # Parameter buffer (for merging \"Parameters:\" and parameter content)\n        self.params_buffer = None\n        \n        # Final output buffer (for merging final_output call and result)\n        self.final_output_buffer = None\n        self.is_final_output_call = False  # Track if current call is final_output\n        \n        # Only keep these important message patterns (Agent calls, tool calls, parameters)\n        # Format unified as:\n        # - Tool call: 🔧 [agent_name] calls tool: tool_name\n        # - Agent call: 📚 [caller_name] calls sub-agent: agent_name\n        # - Parameters: 📋 Parameters: + JSON\n        self.important_patterns = [\n            re.compile(r'📚.*\\[.*\\].*calls sub-agent'),  # Agent call (only keep those with caller)\n            re.compile(r'🔧.*\\[.*\\].*calls tool'),  # Tool call (unified format, no longer use \"Execute tool\")\n            re.compile(r'📋.*Parameters'),  # Parameter info (parameter title)\n        ]\n        \n        # Noise messages to filter (all other output)\n        self.noise_patterns = [\n            # Server related\n            re.compile(r'检查/创建任务时出错'),\n            re.compile(r'HTTPConnectionPool'),\n            re.compile(r'Connection refused'),\n            re.compile(r'Max retries exceeded'),\n            re.compile(r'Restarting with stat'),\n            re.compile(r'Debugger is active'),\n            re.compile(r'Running on'),\n            re.compile(r'Serving Flask app'),\n            # Agent startup and task info\n            re.compile(r'🤖\\s+启动Agent'),\n            re.compile(r'📝\\s+任务:'),\n            re.compile(r'📂\\s+已加载对话历史'),\n            re.compile(r'🔄\\s+发现.*pending工具'),\n            re.compile(r'---\\s+第\\s+\\d+.*轮执行'),\n            re.compile(r'⚠️\\s+达到最大轮次限制'),\n            re.compile(r'✅\\s+任务已完成，直接返回'),\n            # Initialization info\n            re.compile(r'🚀\\s+启动任务'),\n            re.compile(r'📦\\s+加载配置'),\n            re.compile(r'✅\\s+配置加载成功'),\n            re.compile(r'📊\\s+初始化层级管理器'),\n            re.compile(r'✅\\s+层级管理器初始化成功'),\n            re.compile(r'🧹\\s+检查并清理状态'),\n            re.compile(r'✅\\s+指令已注册'),\n            re.compile(r'🔍\\s+查找Agent配置'),\n            re.compile(r'✅\\s+Agent配置加载成功'),\n            re.compile(r'▶️\\s+开始执行任务'),\n            # Agent push (not displayed, only show call relationship)\n            re.compile(r'📚\\s+Agent入栈:'),\n            re.compile(r'📚\\s+Agent出栈'),\n            # Other completion info\n            re.compile(r'✅\\s+使用.*模型'),\n            re.compile(r'✅\\s+Agent配置'),\n            re.compile(r'✅\\s+工具执行器初始化'),\n            re.compile(r'✅\\s+任务.*已在toolServer中创建'),\n            re.compile(r'✅\\s+.*测试'),\n            re.compile(r'✅\\s+.*工具.*执行完成'),  # Tool execution completion also not displayed\n            re.compile(r'工具\\s+\\w+\\s+完成'),  # Tool xxx completed\n            re.compile(r'工具.*完成:'),  # Tool xxx completed: success\n            re.compile(r'\"type\":\\s*\"token\".*工具.*完成'),  # Tool completion info in JSONL events\n            # Warnings and errors\n            re.compile(r'⚠️\\s+.*'),\n            re.compile(r'❌\\s+执行出错'),\n            re.compile(r'❌\\s+恢复失败'),\n            # Other info\n            re.compile(r'📄\\s+输出预览'),\n            re.compile(r'🔗\\s+.*调用toolServer'),\n            re.compile(r'🎉\\s+所有Agent已完成'),\n            re.compile(r'✅\\s+任务已归档'),\n            re.compile(r'📝\\s+新指令已添加'),\n            re.compile(r'ℹ️\\s+指令已存在'),\n            re.compile(r'⚠️\\s+加载.*失败'),\n            re.compile(r'⚠️\\s+保存.*失败'),\n            re.compile(r'⚠️\\s+.*配置失败'),\n            re.compile(r'⚠️\\s+创建任务失败'),\n            re.compile(r'⚠️\\s+Thinking触发失败'),\n            re.compile(r'⚠️\\s+压缩失败'),\n            # Separator lines\n            re.compile(r'^={80,}$'),\n            re.compile(r'^-{3,}.*-{3,}$'),\n        ]\n        \n        # Agent name pattern matching\n        self.agent_patterns = [\n            re.compile(r'\\[([^\\]]+)\\]\\s+calls'),  # [agent_name] calls...\n            re.compile(r'\\[([^\\]]+)\\]'),  # [agent_name]\n            re.compile(r'🤖\\s+Start Agent:\\s+(\\w+)'),  # 🤖 Start Agent: agent_name\n            re.compile(r'Agent completed:\\s+(\\w+)'),  # Agent completed: agent_name\n            re.compile(r'calls sub-agent:\\s+(\\w+)'),  # Call sub-agent: agent_name\n            re.compile(r'calls tool:\\s+(\\w+)'),  # Call tool: tool_name\n        ]\n    \n    def start(self):\n        \"\"\"开始捕获输出\"\"\"\n        sys.stdout = self\n        sys.stderr = self\n    \n    def stop(self):\n        \"\"\"停止捕获输出\"\"\"\n        # Output remaining buffered content\n        self._flush_buffer()\n        # Output remaining call with parameters or final output (if any)\n        if self.call_buffer:\n            if self.final_output_buffer:\n                self._output_final_output_with_result()\n            elif self.params_buffer:\n                self._output_call_with_params()\n        sys.stdout = self.original_stdout\n        sys.stderr = self.original_stderr\n    \n    def write(self, text: str):\n        \"\"\"写入输出（重定向 stdout/stderr）\"\"\"\n        # 写入原始 stdout（用于调试）\n        self.original_stdout.write(text)\n        self.original_stdout.flush()\n        \n        # 如果是 final_output 调用，先处理结果收集（在所有过滤之前）\n        # 现在只输出 output 字段的内容（纯文本），不再是 JSON\n        if self.is_final_output_call and self.call_buffer:\n            text_stripped = text.strip()\n            \n            # 跳过参数行（对于 final_output，不显示参数）\n            if '📋' in text and 'Parameters' in text:\n                return  # 忽略参数标题行\n            \n            # 跳过参数内容（参数是 JSON 格式）\n            # 如果还没有开始收集结果，且看起来是 JSON 格式，可能是参数，忽略\n            # 现在参数已经在 agent_executor.py 中被跳过了，但为了安全起见还是检查一下\n            if not self.final_output_buffer:\n                # 检查是否是 JSON 格式的参数内容\n                looks_like_json = (text_stripped.startswith('{') or text_stripped.startswith('[') or \n                                  (text_stripped.startswith('\"') and ':' in text))\n                if looks_like_json:\n                    # 检查是否是参数：如果包含参数字段\n                    has_param_fields = any(field in text for field in ['\"task_id\"', '\"task_input\"', '\"arguments\"', '\"status\"', '\"output\"'])\n                    # 如果看起来像完整的 JSON 对象（包含多个字段），可能是参数或工具完成信息，忽略\n                    if has_param_fields or ('\"' in text and text.count(':') > 1):\n                        return\n            \n            # Check if tool completion info (need to output final output and filter this message)\n            is_tool_complete = 'tool' in text.lower() and 'completed' in text.lower()\n            \n            if is_tool_complete:\n                # Output call message with final output together\n                if self.final_output_buffer:\n                    self._output_final_output_with_result()\n                # 过滤掉工具完成信息\n                return\n            \n            # 检查是否是结果内容\n            # 对于 final_output，现在只输出 output 字段的内容（纯文本），不再是 JSON\n            # 排除 JSON 格式的内容（可能是参数或工具完成信息）\n            # 只接受纯文本内容（不包含 JSON 特征）\n            is_result_content = (\n                text_stripped and \n                not any(x in text for x in ['🔧', '📋', '📚', 'calls tool', 'calls sub-agent', 'completed']) and\n                # 排除参数行\n                'Parameters' not in text and\n                # 排除 JSON 格式（不应该是 JSON）\n                not text_stripped.startswith('{') and\n                not text_stripped.startswith('[') and\n                not (text_stripped.startswith('\"') and ':' in text) and\n                # 排除包含多个 JSON 字段的行（如 \"task_id\": \"xxx\"）\n                not ('\"' in text and text.count(':') >= 1 and any(field in text for field in ['\"task_id\"', '\"status\"', '\"output\"', '\"execution_experience\"', '\"sub_tools\"']))\n            )\n            \n            if is_result_content:\n                # 初始化或更新 final_output_buffer\n                if not self.final_output_buffer:\n                    agent = self.call_buffer.get(\"agent\") or self.current_agent\n                    self.final_output_buffer = {\n                        \"type\": \"final_output\",\n                        \"agent\": agent,\n                        \"content\": text_stripped,\n                        \"timestamp\": datetime.now().isoformat()\n                    }\n                else:\n                    # 追加内容（可能是多行文本）\n                    self.final_output_buffer[\"content\"] = self.final_output_buffer[\"content\"] + \"\\n\" + text_stripped\n                # 继续等待更多结果内容（可能是多行文本）\n                return\n            elif text_stripped:\n                # 遇到非结果内容，可能是新的工具调用等\n                # 先输出已收集的结果\n                if self.final_output_buffer:\n                    self._output_final_output_with_result()\n                # 继续处理当前行（不要 return，让它继续处理）\n            # 空行也作为结果的一部分（可能是多行文本）\n            elif not text_stripped:\n                # 如果已经有内容，空行可能是文本的分隔，继续等待\n                if self.final_output_buffer:\n                    return\n        \n        if not text.strip():\n            return\n        \n        # 先过滤噪音消息（所有不需要的输出）\n        if self._is_noise(text):\n            return\n        \n        # 如果参数缓冲存在，检查是否是参数内容（即使不是重要消息，也要处理）\n        if self.params_buffer:\n            # 如果是 final_output 工具，忽略参数，清空 params_buffer\n            if self.is_final_output_call:\n                self.params_buffer = None\n            else:\n                text_stripped = text.strip()\n            \n            # Check if tool completion info (need to output parameters and filter this message)\n            is_tool_complete = 'tool' in text.lower() and 'completed' in text.lower()\n            \n            if is_tool_complete:\n                # Output call message with parameters together\n                self._output_call_with_params()\n                # 过滤掉工具完成信息\n                return\n            \n            # 空行也作为参数的一部分（可能是多行JSON）\n            if not text_stripped:\n                # 空行，继续等待参数内容\n                return\n            \n            # 检查是否是参数内容（JSON格式）\n            is_json_content = (\n                text_stripped.startswith('{') or \n                text_stripped.startswith('[') or\n                (text_stripped.startswith('\"') and ':' in text) or  # JSON字段\n                (text_stripped and not any(x in text for x in ['🔧', '📋', '📚', 'calls tool', 'calls sub-agent', 'completed']))\n            )\n            \n            if is_json_content:\n                # 合并参数标题和内容\n                if self.params_buffer[\"content\"].endswith('Parameters:'):\n                    self.params_buffer[\"content\"] = self.params_buffer[\"content\"] + \"\\n\" + text_stripped\n                else:\n                    self.params_buffer[\"content\"] = self.params_buffer[\"content\"] + \"\\n\" + text_stripped\n                # 继续等待更多参数内容（可能是多行JSON）\n                return\n            else:\n                # Check if new important message (tool call, Agent call, etc.)\n                is_new_important = (\n                    '🔧' in text and 'calls tool' in text or\n                    '📚' in text and 'calls sub-agent' in text\n                )\n                \n                if is_new_important:\n                        # Encounter new important message, output call with parameters together\n                        self._output_call_with_params()\n                    # 继续处理当前行\n                else:\n                        # Other cases, output call with parameters together\n                        self._output_call_with_params()\n                    # 继续处理当前行\n        \n        # 只处理重要消息（Agent调用、工具调用、参数）\n        if not self._is_important(text):\n            return\n        \n        # Determine message type\n        msg_type = self._determine_message_type(text)\n        \n        # Handle tool call or agent call - save to call_buffer instead of immediate output\n        if msg_type in [\"tool_call\", \"agent_call\"]:\n            # If there's a previous call_buffer with parameters, output it first\n            if self.call_buffer:\n                if self.params_buffer:\n                    self._output_call_with_params()\n                elif self.final_output_buffer:\n                    self._output_final_output_with_result()\n            \n            # Save current call to call_buffer\n            agent = self._extract_agent_name(text)\n            if not agent:\n                # 如果提取失败，尝试从文本中提取\n                if msg_type == \"agent_call\":\n                    match = re.search(r'\\[([^\\]]+)\\]\\s+calls sub-agent', text)\n                    if match:\n                        agent = match.group(1)\n                elif msg_type == \"tool_call\":\n                    match = re.search(r'\\[([^\\]]+)\\]\\s+calls tool', text)\n                    if match:\n                        agent = match.group(1)\n            \n            if agent:\n                self.last_call_agent = agent\n            \n            if not agent:\n                agent = self.last_call_agent or self.current_agent\n            \n            # Check if this is final_output tool call\n            self.is_final_output_call = False\n            if msg_type == \"tool_call\":\n                # Extract tool name from text\n                match = re.search(r'calls tool:\\s*(\\w+)', text)\n                if match and match.group(1) == \"final_output\":\n                    self.is_final_output_call = True\n            \n            self.call_buffer = {\n                \"type\": msg_type,\n                \"agent\": agent,\n                \"content\": text.strip(),\n                \"timestamp\": datetime.now().isoformat()\n            }\n            # Clear params_buffer and final_output_buffer to prepare for new content\n            self.params_buffer = None\n            self.final_output_buffer = None\n            return  # 不立即输出，等待参数或结果\n        \n        # Handle parameter title line (\"📋 Parameters:\")\n        if msg_type == \"params\" and '📋' in text and 'Parameters' in text:\n            # 如果是 final_output 工具，跳过参数处理，只等待最终输出\n            if self.is_final_output_call:\n                # 对于 final_output，忽略参数，不保存到 params_buffer\n                return\n            \n            # 保存参数标题到缓冲，等待参数内容\n            agent = self._extract_agent_name(text) or self.last_call_agent or self.current_agent\n            self.params_buffer = {\n                \"type\": \"params\",\n                \"agent\": agent,\n                \"content\": text.strip(),\n                \"timestamp\": datetime.now().isoformat()\n            }\n            return  # 不立即输出，等待参数内容\n        \n        # 如果不是参数内容，且不是工具/Agent调用，清空缓冲并输出\n        if self.call_buffer and self.params_buffer:\n            self._output_call_with_params()\n        \n        # 其他类型的消息正常处理\n        if msg_type not in [\"tool_call\", \"agent_call\", \"params\"]:\n        # 尝试从输出中提取 agent 名称\n            agent = self._extract_agent_name(text) or self.last_call_agent or self.current_agent\n        \n        # 如果还是没有 agent，使用当前 agent\n        if not agent:\n            agent = self.current_agent\n        \n        # 检查内容是否为空\n        content = text.strip()\n        if not content:\n            return  # 不输出空消息\n        \n        # 去重：检查是否与最近输出的消息相同（避免重复）\n        if hasattr(self, '_last_output'):\n            if self._last_output == content and msg_type == self._last_output_type:\n                return  # 跳过重复消息\n        \n        # 保存最近输出的消息\n        self._last_output = content\n        self._last_output_type = msg_type\n        \n            # 立即输出其他类型消息\n        self.callback({\n            \"type\": msg_type,\n            \"agent\": agent,\n            \"content\": content,\n            \"timestamp\": datetime.now().isoformat()\n        })\n        return\n    \n    def _is_important(self, text: str) -> bool:\n        \"\"\"判断是否是重要消息（只保留Agent调用、工具调用、参数）\"\"\"\n        text_stripped = text.strip()\n        \n        # 空消息不算重要\n        if not text_stripped:\n            return False\n        \n        # Check if important message（Agent调用、工具调用、参数）\n        # 只匹配带调用者信息的消息（避免重复）\n        for pattern in self.important_patterns:\n            if pattern.search(text):\n                # Ensure message contains caller information (avoid duplicates)\n                if 'calls sub-agent' in text and '[' not in text:\n                    return False  # Agent call without caller info not displayed\n                if 'calls tool' in text and '[' not in text:\n                    return False  # Tool call without caller info not displayed\n                return True\n        \n        # 检查是否是参数的 JSON 内容（多行）\n        # 如果当前行是 JSON（以 { 或 [ 开头，且包含常见字段）\n        if text_stripped.startswith('{') or text_stripped.startswith('['):\n            # 检查是否包含常见字段（参数或结果）\n            if any(field in text for field in ['\"task_input\"', '\"path\"', '\"content\"', '\"arguments\"', '\"task_id\"', '\"status\"', '\"output\"']):\n                # 只有在有参数缓冲时才显示（避免单独显示 JSON）\n                if self.params_buffer:\n                    return True\n                return False  # 没有参数缓冲的 JSON 不单独显示\n        \n        # 检查是否是参数内容的后续行（不以 { 开头，但包含 JSON 字段）\n        if self.params_buffer and not text_stripped.startswith('{') and not text_stripped.startswith('['):\n            # 可能是多行 JSON 的一部分\n            if any(x in text for x in ['\"', ':', ',', '}', ']']) and not any(x in text for x in ['🔧', '📋', '📚', 'calls tool', 'calls sub-agent']):\n                return True  # 作为参数内容处理\n        \n        return False\n    \n    def _is_noise(self, text: str) -> bool:\n        \"\"\"判断是否是噪音消息（过滤所有其他输出）\"\"\"\n        # 先检查是否是重要消息，如果是就不算噪音\n        if self._is_important(text):\n            return False\n        # 其他都是噪音\n        return True\n    \n    def _flush_buffer(self):\n        \"\"\"输出缓冲的内容\"\"\"\n        if not self.output_buffer:\n            return\n        \n        # 合并缓冲中的消息\n        if len(self.output_buffer) == 1:\n            msg = self.output_buffer[0]\n        else:\n            # 合并多条消息\n            contents = [m[\"content\"] for m in self.output_buffer]\n            msg = {\n                \"type\": self.output_buffer[0][\"type\"],\n                \"agent\": self.output_buffer[0][\"agent\"],\n                \"content\": \"\\n\".join(contents)\n            }\n        \n        self.callback({\n            \"type\": msg[\"type\"],\n            \"agent\": msg[\"agent\"],\n            \"content\": msg[\"content\"],\n            \"timestamp\": datetime.now().isoformat()\n        })\n        \n        self.output_buffer.clear()\n    \n    def _output_call_with_params(self):\n        \"\"\"输出工具调用/Agent调用和参数合并的消息\"\"\"\n        if not self.call_buffer:\n            # 如果没有调用信息，只输出参数\n            if self.params_buffer and self.params_buffer[\"content\"].strip() and self.params_buffer[\"content\"] != \"📋 Parameters:\":\n                self.callback(self.params_buffer)\n                self.params_buffer = None\n            return\n        \n        # 合并调用信息和参数\n        call_content = self.call_buffer[\"content\"]\n        \n        if self.params_buffer and self.params_buffer[\"content\"].strip() and self.params_buffer[\"content\"] != \"📋 Parameters:\":\n            # 提取参数内容（去掉 \"📋 Parameters:\" 前缀）\n            params_content = self.params_buffer[\"content\"]\n            if params_content.startswith(\"📋 Parameters:\"):\n                params_content = params_content.replace(\"📋 Parameters:\", \"\").strip()\n            \n            # 合并到调用消息中\n            combined_content = f\"{call_content}\\n\\n📋 Parameters:\\n{params_content}\"\n        else:\n            combined_content = call_content\n        \n        # 输出合并后的消息\n        self.callback({\n            \"type\": self.call_buffer[\"type\"],\n            \"agent\": self.call_buffer[\"agent\"],\n            \"content\": combined_content,\n            \"timestamp\": self.call_buffer[\"timestamp\"]\n        })\n        \n        # 清空缓冲\n        self.call_buffer = None\n        self.params_buffer = None\n    \n    def _output_final_output_with_result(self):\n        \"\"\"输出 final_output 工具调用和完整结果合并的消息\"\"\"\n        if not self.call_buffer:\n            # 如果没有调用信息，只输出结果\n            if self.final_output_buffer and self.final_output_buffer[\"content\"].strip():\n                self.callback(self.final_output_buffer)\n                self.final_output_buffer = None\n            return\n        \n        # 合并调用信息和完整结果\n        call_content = self.call_buffer[\"content\"].strip()\n        \n        if self.final_output_buffer and self.final_output_buffer[\"content\"].strip():\n            # 获取结果内容\n            result_content = self.final_output_buffer[\"content\"].strip()\n            \n            # 合并到调用消息中（只显示调用信息和完整输出，不显示参数）\n            # 确保调用信息和结果之间有明确的换行\n            combined_content = f\"{call_content}\\n\\n{result_content}\"\n        else:\n            # 没有结果，只显示调用信息\n            combined_content = call_content\n        \n        # 输出合并后的消息（使用 final_output 类型）\n        self.callback({\n            \"type\": \"final_output\",\n            \"agent\": self.call_buffer[\"agent\"],\n            \"content\": combined_content,\n            \"timestamp\": self.call_buffer[\"timestamp\"]\n        })\n        \n        # 清空缓冲\n        self.call_buffer = None\n        self.final_output_buffer = None\n        self.is_final_output_call = False\n    \n    def flush(self):\n        \"\"\"刷新缓冲区\"\"\"\n        self.original_stdout.flush()\n    \n    def _extract_agent_name(self, text: str) -> Optional[str]:\n        \"\"\"从文本中提取 agent 名称\"\"\"\n        for pattern in self.agent_patterns:\n            match = pattern.search(text)\n            if match:\n                return match.group(1)\n        return None\n    \n    def _determine_message_type(self, text: str) -> str:\n        \"\"\"确定消息类型\"\"\"\n        text_stripped = text.strip()\n        \n        # 空消息直接返回\n        if not text_stripped:\n            return \"info\"\n        \n        # Agent call (check if contains caller information)\n        # Format: 📚 [caller_name] calls sub-agent: agent_name\n        if '📚' in text and 'calls sub-agent' in text and '[' in text:\n            return \"agent_call\"\n        # Tool call (unified format)\n        # Format: 🔧 [agent_name] calls tool: tool_name\n        elif '🔧' in text and 'calls tool' in text and '[' in text:\n            return \"tool_call\"\n        # Parameter info\n        # Format: 📋 Parameters:\n        elif '📋' in text and 'Parameters' in text:\n            return \"params\"\n        else:\n            return \"info\"\n    \n    def set_agent(self, agent_name: str):\n        \"\"\"设置当前 agent 名称\"\"\"\n        self.current_agent = agent_name\n        self.agent_name = agent_name\n    \n    def parse_jsonl_event(self, line: str):\n        \"\"\"解析 EventEmitter 的 JSONL 事件\"\"\"\n        try:\n            event = json.loads(line.strip())\n            event_type = event.get('type', 'unknown')\n            \n            # 提取 agent 信息\n            agent = self.current_agent\n            if 'agent' in event:\n                agent = event['agent']\n            \n            # 格式化内容\n            content = \"\"\n            if event_type == 'token':\n                # token 类型：检查内容是否需要过滤\n                text = event.get('text', '')\n                \n                # Filter tool completion info\n                if 'tool' in text.lower() and 'completed' in text.lower():\n                    return  # Do not process tool completion info\n                \n                content = text\n                \n                # 如果内容为空，不输出\n                if not content.strip():\n                    return\n                    \n            elif event_type == 'start':\n                content = f\"🚀 Task started: {event.get('task', '')}\"\n                agent = event.get('agent', agent)\n            elif event_type == 'result':\n                content = f\"📊 Execution result: {event.get('summary', '')}\"\n            elif event_type == 'end':\n                status = event.get('status', 'unknown')\n                duration = event.get('duration_ms', 0) / 1000\n                content = f\"{'✅' if status == 'ok' else '❌'} Task completed ({duration:.1f}s)\"\n            elif event_type == 'error':\n                content = f\"❌ Error: {event.get('text', '')}\"\n            elif event_type == 'warn':\n                content = f\"⚠️ Warning: {event.get('text', '')}\"\n            elif event_type == 'notice':\n                content = f\"ℹ️ Notice: {event.get('text', '')}\"\n            elif event_type == 'progress':\n                # progress 类型：不输出（避免显示进度条）\n                return\n            else:\n                content = json.dumps(event, ensure_ascii=False)\n            \n            # 如果内容为空，不输出\n            if not content or not content.strip():\n                return\n            \n            # Send message（使用原始事件类型）\n            self.callback({\n                \"type\": event_type,\n                \"agent\": agent,\n                \"content\": content.strip(),\n                \"timestamp\": datetime.now().isoformat()\n            })\n        except json.JSONDecodeError:\n            # 不是 JSON，忽略\n            pass\n\n"
  },
  {
    "path": "web_ui/server/sdk_worker.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nWeb UI SDK worker.\n\nRuns one task per process using the Python SDK and emits JSONL events on stdout.\nNormal logs are redirected to stderr to keep stdout machine-readable.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nimport sys\nimport threading\nimport time\nfrom pathlib import Path\nfrom typing import Any, Dict\n\nPROJECT_ROOT = Path(__file__).resolve().parent.parent.parent\nif str(PROJECT_ROOT) not in sys.path:\n    sys.path.insert(0, str(PROJECT_ROOT))\n\nfrom infiagent import infiagent\nfrom core.runtime_exceptions import InfiAgentRunError\nfrom tool_server_lite.tools.human_tools import respond_hil_task, respond_tool_confirmation\nimport utils.event_emitter as event_emitter_module\n\n_EMIT_LOCK = threading.Lock()\n\n\ndef emit_json(payload: Dict[str, Any]) -> None:\n    with _EMIT_LOCK:\n        sys.stdout_orig.write(json.dumps(payload, ensure_ascii=False) + \"\\n\")\n        sys.stdout_orig.flush()\n\n\nclass WorkerBridgeEmitter:\n    def __init__(self):\n        self.enabled = True\n        self.call_id = \"sdk-worker\"\n        self.start_time = time.time()\n\n    def emit(self, event: Dict[str, Any]):\n        if not isinstance(event, dict):\n            return\n        event_type = str(event.get(\"type\") or \"\").strip()\n        if event_type in {\"human_in_loop\", \"tool_confirmation\"}:\n            emit_json(event)\n\n    def start(self, call_id: str, project: str, agent: str, task: str):\n        self.call_id = call_id\n        self.start_time = time.time()\n\n    def token(self, text: str):\n        # SDK stream tokens are relayed through on_event, not the legacy emitter.\n        return\n\n    def progress(self, phase: str, pct: int):\n        return\n\n    def notice(self, text: str):\n        emit_json({\"type\": \"notice\", \"text\": str(text or \"\")})\n\n    def warn(self, text: str):\n        emit_json({\"type\": \"warn\", \"text\": str(text or \"\")})\n\n    def error(self, text: str):\n        emit_json({\"type\": \"error\", \"text\": str(text or \"\")})\n\n    def artifact(self, kind: str, path: str = None, summary: str = None, preview: str = None):\n        emit_json({\n            \"type\": \"artifact\",\n            \"kind\": kind,\n            \"path\": path,\n            \"summary\": summary,\n            \"preview\": preview,\n        })\n\n    def human_in_loop(self, hil_id: str, title: str, message: str, ui: Dict[str, Any], timeout_sec: int = 1800, resume_hint: str = None):\n        emit_json({\n            \"type\": \"human_in_loop\",\n            \"hil_id\": hil_id,\n            \"title\": title,\n            \"message\": message,\n            \"ui\": ui,\n            \"timeout_sec\": timeout_sec,\n            \"resume_hint\": resume_hint,\n        })\n\n    def result(self, ok: bool, summary: str, artifacts=None):\n        emit_json({\n            \"type\": \"result\",\n            \"ok\": bool(ok),\n            \"summary\": str(summary or \"\"),\n            \"artifacts\": list(artifacts or []),\n        })\n\n    def end(self, status: str, extra: Dict[str, Any] = None):\n        payload = {\n            \"type\": \"end\",\n            \"status\": str(status or \"\"),\n            \"duration_ms\": int((time.time() - self.start_time) * 1000),\n        }\n        if isinstance(extra, dict):\n            payload.update(extra)\n        emit_json(payload)\n\n\ndef map_sdk_event(event: Dict[str, Any]) -> Dict[str, Any] | None:\n    event_type = str(event.get(\"event_type\") or \"\")\n    payload = event.get(\"payload\", {}) if isinstance(event.get(\"payload\"), dict) else {}\n\n    if event_type == \"agent.start\":\n        return {\n            \"type\": \"agent_start\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"task\": payload.get(\"task_input\", \"\"),\n        }\n    if event_type == \"agent.end\":\n        return {\n            \"type\": \"agent_end\",\n            \"status\": payload.get(\"status\", \"\"),\n        }\n    if event_type == \"run.thinking.start\":\n        return {\n            \"type\": \"thinking_start\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"is_initial\": bool(payload.get(\"is_initial\")),\n            \"is_forced\": bool(payload.get(\"is_forced\")),\n        }\n    if event_type == \"run.thinking.end\":\n        return {\n            \"type\": \"thinking_end\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"result\": payload.get(\"result\", \"\") or payload.get(\"raw_output\", \"\"),\n            \"model\": payload.get(\"model\", \"\"),\n        }\n    if event_type == \"run.thinking.token\":\n        return {\n            \"type\": \"thinking_token\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"model\": payload.get(\"model\", \"\"),\n            \"text\": payload.get(\"text\", \"\"),\n        }\n    if event_type == \"run.thinking.reasoning_token\":\n        return {\n            \"type\": \"thinking_token\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"model\": payload.get(\"model\", \"\"),\n            \"text\": payload.get(\"text\", \"\"),\n            \"token_kind\": \"reasoning\",\n        }\n    if event_type == \"run.llm.token\":\n        return {\n            \"type\": \"token\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"model\": payload.get(\"model\", \"\"),\n            \"text\": payload.get(\"text\", \"\"),\n        }\n    if event_type == \"run.llm.reasoning_token\":\n        return {\n            \"type\": \"reasoning_token\",\n            \"agent\": payload.get(\"agent_name\", \"\"),\n            \"model\": payload.get(\"model\", \"\"),\n            \"text\": payload.get(\"text\", \"\"),\n        }\n    if event_type == \"run.tool.start\":\n        return {\n            \"type\": \"tool_call\",\n            \"name\": payload.get(\"tool_name\", \"\"),\n            \"tool_name\": payload.get(\"tool_name\", \"\"),\n            \"arguments\": payload.get(\"arguments\", {}) or {},\n        }\n    if event_type == \"run.tool.end\":\n        result = payload.get(\"result\", {}) if isinstance(payload.get(\"result\"), dict) else {}\n        error_text = str(result.get(\"error_information\") or result.get(\"error\") or \"\")\n        preview = str(result.get(\"output\", \"\") or \"\")\n        return {\n            \"type\": \"tool_result\",\n            \"name\": payload.get(\"tool_name\", \"\"),\n            \"tool_name\": payload.get(\"tool_name\", \"\"),\n            \"status\": payload.get(\"status\", \"\"),\n            \"output_preview\": preview[:2000],\n            \"error\": error_text,\n        }\n    return None\n\n\ndef start_control_thread() -> None:\n    def _worker():\n        for line in sys.stdin:\n            line = (line or \"\").strip()\n            if not line:\n                continue\n            try:\n                payload = json.loads(line)\n            except Exception:\n                continue\n            if not isinstance(payload, dict):\n                continue\n            message_type = str(payload.get(\"type\") or \"\").strip()\n            if message_type == \"hil_response\":\n                hil_id = str(payload.get(\"hil_id\") or \"\").strip()\n                response = payload.get(\"response\")\n                if hil_id and response is not None:\n                    respond_hil_task(hil_id, str(response))\n            elif message_type == \"tool_confirmation_response\":\n                confirm_id = str(payload.get(\"confirm_id\") or \"\").strip()\n                approved = payload.get(\"approved\")\n                if confirm_id and approved is not None:\n                    respond_tool_confirmation(confirm_id, bool(approved))\n\n    thread = threading.Thread(target=_worker, daemon=True, name=\"sdk-worker-stdin\")\n    thread.start()\n\n\ndef main() -> int:\n    sys.stdout_orig = sys.stdout\n    sys.stdout = sys.stderr\n\n    parser = argparse.ArgumentParser(description=\"Web UI SDK worker\")\n    parser.add_argument(\"--task_id\", required=True)\n    parser.add_argument(\"--user_data_root\", required=True)\n    parser.add_argument(\"--skills_dir\", required=True)\n    parser.add_argument(\"--agent_system\", required=True)\n    parser.add_argument(\"--agent_name\", required=True)\n    parser.add_argument(\"--user_input\", required=True)\n    args = parser.parse_args()\n\n    bridge = WorkerBridgeEmitter()\n    event_emitter_module._event_emitter = bridge\n    start_control_thread()\n    bridge.start(\"sdk-worker\", args.task_id, args.agent_name, args.user_input)\n\n    started_at = time.time()\n    emit_json({\n        \"type\": \"start\",\n        \"agent\": args.agent_name,\n        \"task\": args.user_input,\n        \"task_id\": args.task_id,\n    })\n\n    def on_event(event: Dict[str, Any]) -> None:\n        mapped = map_sdk_event(event)\n        if mapped:\n            emit_json(mapped)\n\n    agent = infiagent(\n        user_data_root=args.user_data_root,\n        skills_dir=args.skills_dir,\n        default_agent_system=args.agent_system,\n        default_agent_name=args.agent_name,\n        seed_builtin_resources=True,\n        direct_tools=True,\n    )\n\n    try:\n        result = agent.run(\n            args.user_input,\n            task_id=args.task_id,\n            agent_system=args.agent_system,\n            agent_name=args.agent_name,\n            collect_events=False,\n            on_event=on_event,\n            include_trace=False,\n            raise_on_error=True,\n            stream_llm_tokens=True,\n        )\n        ok = str(result.get(\"status\") or \"\") == \"success\"\n        summary = str(result.get(\"output\") or result.get(\"error\") or \"\")\n        emit_json({\n            \"type\": \"result\",\n            \"ok\": ok,\n            \"summary\": summary,\n        })\n        emit_json({\n            \"type\": \"end\",\n            \"status\": \"ok\" if ok else \"error\",\n            \"duration_ms\": int((time.time() - started_at) * 1000),\n        })\n        return 0 if ok else 1\n    except InfiAgentRunError as exc:\n        text = str(exc.result.get(\"error\") or exc.result.get(\"error_information\") or str(exc))\n        emit_json({\"type\": \"error\", \"text\": text})\n        emit_json({\n            \"type\": \"end\",\n            \"status\": \"error\",\n            \"duration_ms\": int((time.time() - started_at) * 1000),\n        })\n        return 1\n    except Exception as exc:\n        emit_json({\"type\": \"error\", \"text\": str(exc)})\n        emit_json({\n            \"type\": \"end\",\n            \"status\": \"error\",\n            \"duration_ms\": int((time.time() - started_at) * 1000),\n        })\n        return 1\n\n\nif __name__ == \"__main__\":\n    raise SystemExit(main())\n"
  },
  {
    "path": "web_ui/server/server",
    "content": "#!/bin/bash\n# Web UI 和工具服务器统一管理脚本\n# 用法: ./server [start|stop|restart|status]\n\n# 获取脚本所在目录（server 目录）\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n# 切换到 server 目录\ncd \"$SCRIPT_DIR\"\n\n# 获取项目根目录\nPROJECT_ROOT=\"$( cd \"$SCRIPT_DIR/../..\" && pwd )\"\nTOOL_SERVER_DIR=\"$PROJECT_ROOT/tool_server_lite\"\n\nWEB_PORT=${PORT:-22228}\nTOOL_PORT=${TOOL_PORT:-24243}\nACTION=${1:-start}\n\ncase \"$ACTION\" in\n    start)\n        # 检查 Web UI 端口\n        if lsof -ti:$WEB_PORT &> /dev/null; then\n            echo \"⚠️  Web UI 端口 $WEB_PORT 已被占用\"\n            echo \"💡 使用 './server stop' 停止现有服务器\"\n            exit 1\n        fi\n        \n        # 激活 conda 环境\n        if conda env list | grep -q \"paper_agent\"; then\n            source \"$(conda info --base)/etc/profile.d/conda.sh\"\n            conda activate paper_agent\n        fi\n        \n        # 启动工具服务器（如果未运行）\n        echo \"🔧 检查工具服务器...\"\n        \n        # 检查端口是否被占用\n        if lsof -ti:$TOOL_PORT &> /dev/null; then\n            # 检查服务器是否真的响应\n            if curl -s http://localhost:$TOOL_PORT/health > /dev/null 2>&1; then\n                TOOL_PID=$(lsof -ti:$TOOL_PORT | head -1)\n                echo \"   ✅ 工具服务器已在运行（端口 $TOOL_PORT, PID: $TOOL_PID）\"\n            else\n                echo \"   ⚠️  端口 $TOOL_PORT 被占用但服务器未响应，尝试重启...\"\n                kill -9 $(lsof -ti:$TOOL_PORT) 2>/dev/null\n                sleep 2\n            fi\n        fi\n        \n        # 如果端口未被占用或需要重启，启动服务器\n        if ! lsof -ti:$TOOL_PORT &> /dev/null; then\n            echo \"   🚀 启动工具服务器（端口 $TOOL_PORT）...\"\n            cd \"$TOOL_SERVER_DIR\"\n            \n            # 获取当前 Python 解释器路径\n            PYTHON_CMD=$(which python3 || which python)\n            \n            # 直接启动服务器（使用专门的启动脚本）\n            nohup $PYTHON_CMD \"$TOOL_SERVER_DIR/start_server.py\" --host 0.0.0.0 --port $TOOL_PORT > /home/koalm/Songmiao_server/mla-workspace/tool_server.log 2>&1 &\n            TOOL_SERVER_PID=$!\n            sleep 5  # 增加等待时间，让服务器完全启动\n            \n            # 检查是否启动成功\n            if lsof -ti:$TOOL_PORT &> /dev/null; then\n                sleep 2\n                if curl -s http://localhost:$TOOL_PORT/health > /dev/null 2>&1; then\n                    echo \"   ✅ 工具服务器已启动（PID: $TOOL_SERVER_PID）\"\n                    echo $TOOL_SERVER_PID > /home/koalm/Songmiao_server/mla-workspace/web_ui_tool_server.pid\n                else\n                    echo \"   ⚠️  工具服务器进程已启动但未响应\"\n                    if [ -f /home/koalm/Songmiao_server/mla-workspace/tool_server.log ]; then\n                        echo \"   📋 最近日志:\"\n                        tail -10 /home/koalm/Songmiao_server/mla-workspace/tool_server.log | sed 's/^/      /'\n                    fi\n                fi\n            else\n                echo \"   ⚠️  工具服务器启动失败\"\n                if [ -f /home/koalm/Songmiao_server/mla-workspace/tool_server.log ]; then\n                    echo \"   📋 最近日志:\"\n                    tail -10 /home/koalm/Songmiao_server/mla-workspace/tool_server.log | sed 's/^/      /'\n                fi\n            fi\n            cd \"$SCRIPT_DIR\"\n        fi\n        \n        echo \"\"\n        echo \"🚀 启动 Web UI 服务器...\"\n        PORT=$WEB_PORT python server.py\n        ;;\n    \n    stop)\n        echo \"🛑 正在停止服务器...\"\n        \n        # 停止 Web UI\n        WEB_PIDS=$(lsof -ti:$WEB_PORT 2>/dev/null)\n        if [ -z \"$WEB_PIDS\" ]; then\n            echo \"   ℹ️  Web UI 服务器未运行\"\n        else\n            echo \"   🛑 停止 Web UI 服务器...\"\n            kill -9 $WEB_PIDS 2>/dev/null\n            echo \"      ✅ 已停止\"\n        fi\n        \n        # 停止工具服务器\n        if [ -f /home/koalm/Songmiao_server/mla-workspace/web_ui_tool_server.pid ]; then\n            TOOL_PID=$(cat /home/koalm/Songmiao_server/mla-workspace/web_ui_tool_server.pid)\n            if kill -0 $TOOL_PID 2>/dev/null; then\n                echo \"   🛑 停止工具服务器（PID: $TOOL_PID）...\"\n                kill -9 $TOOL_PID 2>/dev/null\n                echo \"      ✅ 已停止\"\n            fi\n            rm -f /home/koalm/Songmiao_server/mla-workspace/web_ui_tool_server.pid\n        fi\n        \n        # 通过端口查找工具服务器\n        TOOL_PIDS=$(lsof -ti:$TOOL_PORT 2>/dev/null)\n        if [ ! -z \"$TOOL_PIDS\" ]; then\n            for PID in $TOOL_PIDS; do\n                if ps -p $PID -o command= | grep -q \"tool_server_lite.*server.py\"; then\n                    echo \"   🛑 停止工具服务器（PID: $PID）...\"\n                    kill -9 $PID 2>/dev/null\n                    echo \"      ✅ 已停止\"\n                fi\n            done\n        fi\n        \n        # 使用工具服务器的 stop 命令\n        if [ -f \"$TOOL_SERVER_DIR/server.py\" ]; then\n            cd \"$TOOL_SERVER_DIR\"\n            python server.py stop > /dev/null 2>&1\n            cd - > /dev/null\n        fi\n        \n        sleep 1\n        echo \"✅ 所有服务器已停止\"\n        ;;\n    \n    restart)\n        $0 stop\n        sleep 2\n        $0 start\n        ;;\n    \n    status)\n        echo \"📊 服务器状态：\"\n        echo \"\"\n        \n        # Web UI 状态\n        WEB_PIDS=$(lsof -ti:$WEB_PORT 2>/dev/null)\n        if [ -z \"$WEB_PIDS\" ]; then\n            echo \"   Web UI: ❌ 未运行（端口 $WEB_PORT）\"\n        else\n            echo \"   Web UI: ✅ 运行中\"\n            echo \"      端口: $WEB_PORT\"\n            echo \"      进程: $WEB_PIDS\"\n            echo \"      访问: http://localhost:$WEB_PORT\"\n        fi\n        \n        echo \"\"\n        \n        # 工具服务器状态\n        TOOL_PIDS=$(lsof -ti:$TOOL_PORT 2>/dev/null)\n        if [ -z \"$TOOL_PIDS\" ]; then\n            echo \"   工具服务器: ❌ 未运行（端口 $TOOL_PORT）\"\n        else\n            echo \"   工具服务器: ✅ 运行中\"\n            echo \"      端口: $TOOL_PORT\"\n            echo \"      进程: $TOOL_PIDS\"\n            echo \"      访问: http://localhost:$TOOL_PORT/docs\"\n        fi\n        ;;\n    \n    *)\n        echo \"用法: $0 [start|stop|restart|status]\"\n        echo \"\"\n        echo \"命令:\"\n        echo \"  start   - 启动 Web UI 和工具服务器\"\n        echo \"  stop    - 停止所有服务器\"\n        echo \"  restart - 重启所有服务器\"\n        echo \"  status  - 查看服务器状态\"\n        echo \"\"\n        echo \"环境变量:\"\n        echo \"  PORT      - Web UI 端口（默认: 22228）\"\n        echo \"  TOOL_PORT - 工具服务器端口（默认: 24243）\"\n        exit 1\n        ;;\nesac\n\n"
  },
  {
    "path": "web_ui/server/server.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nMLA-V3 Web UI Server\n\nProvides frontend interface and API endpoints.\n\nAuthor: Songmiao Wang\nMLA System: Chenlin Yu, Songmiao Wang\n\"\"\"\n\nimport os\nimport sys\nimport json\nimport threading\nimport queue\nimport subprocess\nimport signal\nimport fcntl  # For file locking (Unix systems)\nimport yaml\nfrom pathlib import Path\nfrom datetime import datetime\nfrom flask import Flask, render_template, request, Response, jsonify, session\nfrom flask_cors import CORS\n\n# Add project root to path\nproject_root = Path(__file__).parent.parent.parent\nsys.path.insert(0, str(project_root))\n\n# Add server_dir to path (for importing output_capture)\nserver_dir = Path(__file__).parent\nsys.path.insert(0, str(server_dir))\n\nfrom tool_server_lite.registry import (\n    get_runtime_registry,\n    get_runtime_registry_failures,\n    get_runtime_registry_metadata,\n    reload_runtime_registry,\n)\nfrom utils.user_paths import (\n    apply_runtime_env_defaults,\n    runtime_env_scope,\n)\nfrom user_runtime import (\n    ensure_web_user_runtime,\n    get_web_user_agent_library_root,\n    get_web_user_app_config_path,\n    get_web_user_config_dir,\n    get_web_user_conversations_dir,\n    get_web_user_data_root,\n    get_web_user_llm_config_path,\n    get_web_user_skills_dir,\n    get_web_user_tools_library_root,\n)\nfrom user_accounts import (\n    authenticate_user,\n    delete_user as delete_account,\n    ensure_default_accounts,\n    list_users as list_account_records,\n    public_user_record,\n    register_user,\n    update_user as update_account,\n)\n\n# OutputCapture is no longer used - we directly parse JSONL events\n# from output_capture import OutputCapture\n\napply_runtime_env_defaults()\n\n# Set template and static file paths (pointing to web_ui directory)\nweb_ui_dir = Path(__file__).parent.parent\napp = Flask(__name__, \n            template_folder=str(web_ui_dir),\n            static_folder=str(web_ui_dir / 'static'))\napp.secret_key = 'mla-secret-key-2024'  # For session\nCORS(app, supports_credentials=True)  # Support credentials (for session)\n\n# Workspace root directory (all tasks are under this directory)\n# 优先从环境变量读取，如果没有则使用当前工作目录（与 CLI 模式相同）\nworkspace_root_env = os.environ.get('WORKSPACE_ROOT')\nif workspace_root_env:\n    WORKSPACE_ROOT = Path(workspace_root_env)\nelse:\n    # 默认使用当前工作目录（和 CLI 模式一样）\n    WORKSPACE_ROOT = Path(os.getcwd())\n\n# 确保目录存在\nWORKSPACE_ROOT.mkdir(parents=True, exist_ok=True)\nHIDDEN_WORKSPACE_NAMES = {'chat_history.json', 'latest_output.json', 'conversations'}\nWRITE_LATEST_OUTPUT = os.environ.get('WEB_UI_WRITE_LATEST_OUTPUT', '').strip().lower() in {'1', 'true', 'yes', 'on'}\n\nensure_default_accounts()\n\n# Global variable to store current execution state (per user)\n# Format: {username: {'running': False, 'process': None, ...}}\ncurrent_executions = {}\n\n\ndef get_user_workspace(username: str) -> Path:\n    \"\"\"Get user-specific workspace root directory\"\"\"\n    user_workspace = WORKSPACE_ROOT / username\n    user_workspace.mkdir(parents=True, exist_ok=True)\n    return user_workspace\n\n\ndef get_user_execution(username: str) -> dict:\n    \"\"\"Get or create user-specific execution state\"\"\"\n    if username not in current_executions:\n        current_executions[username] = {\n            'running': False,\n            'process': None,\n            'output_queue': None,\n            'stop_requested': False,\n            'thread': None,\n            'reader_thread': None,\n            'sse_connections': set(),  # Track active SSE connections\n            'pending_hil': None,\n            'pending_tool_confirmation': None,\n        }\n    return current_executions[username]\n\n\ndef ensure_user_runtime_ready(username: str) -> Path:\n    return ensure_web_user_runtime(username)\n\n\ndef get_user_runtime_overrides(username: str) -> dict:\n    ensure_user_runtime_ready(username)\n    user_root = get_web_user_data_root(username)\n    return {\n        \"MLA_USER_DATA_ROOT\": str(user_root),\n        \"MLA_LLM_CONFIG_PATH\": str(get_web_user_llm_config_path(username)),\n        \"MLA_AGENT_LIBRARY_DIR\": str(user_root),\n        \"MLA_TOOLS_LIBRARY_DIR\": str(get_web_user_tools_library_root(username)),\n        \"MLA_SKILLS_LIBRARY_DIR\": str(get_web_user_skills_dir(username)),\n    }\n\n\ndef get_agent_system_dir(username: str, agent_system: str) -> Path:\n    ensure_user_runtime_ready(username)\n    return get_web_user_agent_library_root(username) / agent_system\n\n\ndef get_run_env_config_dir(username: str) -> Path:\n    ensure_user_runtime_ready(username)\n    cfg = get_web_user_config_dir(username)\n    cfg.mkdir(parents=True, exist_ok=True)\n    return cfg\n\n\ndef get_config_dir_for_type(username: str, config_type: str, agent_system: str) -> Path:\n    if config_type == 'run_env':\n        return get_run_env_config_dir(username)\n    if config_type == 'agent':\n        return get_agent_system_dir(username, agent_system)\n    raise ValueError(\"Invalid config type. Use 'run_env' or 'agent'\")\n\n\ndef validate_config_filename(filename: str, config_type: str) -> None:\n    if not filename:\n        raise ValueError(\"Missing file parameter\")\n    if '..' in filename or '/' in filename or '\\\\' in filename:\n        raise ValueError(\"Invalid file name\")\n    if filename.endswith('.yaml'):\n        return\n    if config_type == 'run_env' and filename == 'app_config.json':\n        return\n    raise ValueError(\"Invalid file name\")\n\n\ndef ensure_config_path(config_dir: Path, filename: str) -> Path:\n    config_path = config_dir / filename\n    try:\n        config_path.relative_to(config_dir.resolve())\n    except ValueError as exc:\n        raise ValueError(\"Invalid file path\") from exc\n    return config_path\n\n\ndef parse_config_text(filename: str, content: str):\n    if filename.endswith('.yaml'):\n        return yaml.safe_load(content) or {}\n    return json.loads(content or \"{}\")\n\n\ndef dump_config_text(filename: str, payload) -> str:\n    if filename.endswith('.yaml'):\n        return yaml.safe_dump(payload or {}, allow_unicode=True, sort_keys=False)\n    return json.dumps(payload or {}, ensure_ascii=False, indent=2) + \"\\n\"\n\n\ndef sanitize_tool_name(raw_name: str) -> str:\n    import re\n    name = re.sub(r'[^a-zA-Z0-9_.-]+', '_', (raw_name or '').strip())\n    name = name.strip('._-')\n    return name\n\n\ndef collect_tool_bindings(username: str) -> dict:\n    systems = []\n    root = get_web_user_agent_library_root(username)\n    if root.exists():\n        systems = sorted(d.name for d in root.iterdir() if d.is_dir() and not d.name.startswith('.'))\n\n    bound_by_tool = {}\n    declared_without_impl = []\n    with runtime_env_scope(get_user_runtime_overrides(username)):\n        reload_runtime_registry()\n        runtime_tools = set(get_runtime_registry().keys())\n\n    from utils.config_loader import ConfigLoader\n    for system_name in systems:\n        try:\n            loader = ConfigLoader(system_name, agent_library_root=str(get_web_user_data_root(username)))\n        except Exception:\n            continue\n        for tool_name, config in loader.all_tools.items():\n            if config.get(\"type\") != \"tool_call_agent\":\n                continue\n            bound_by_tool.setdefault(tool_name, []).append(system_name)\n            if tool_name not in runtime_tools:\n                declared_without_impl.append({\n                    \"tool_name\": tool_name,\n                    \"agent_system\": system_name,\n                    \"reason\": \"YAML 已声明但运行时未注册\"\n                })\n\n    return {\n        \"bindings\": bound_by_tool,\n        \"missing_runtime\": declared_without_impl,\n    }\n\n\ndef normalize_task_id(task_id: str, username: str = None) -> tuple[Path, str]:\n    \"\"\"\n    Normalize task ID path (user-aware)\n    \n    Args:\n        task_id: User input task ID (can be relative path or absolute path)\n        username: Username for user-specific workspace isolation\n    \n    Returns:\n        (absolute_path, display_path): \n        - absolute_path: Absolute path (under user workspace)\n        - display_path: Display path to user (relative to user workspace)\n    \n    Raises:\n        ValueError: If path is unsafe (contains .. or exceeds workspace root directory)\n    \"\"\"\n    import os\n    \n    if not username:\n        raise ValueError(\"Username is required for task isolation\")\n    \n    # Get user-specific workspace\n    user_workspace = get_user_workspace(username)\n    \n    # Remove leading/trailing spaces and slashes\n    task_id = task_id.strip().strip('/')\n    \n    # If user input is absolute path, check if it's under user workspace\n    if os.path.isabs(task_id):\n        abs_path = Path(task_id)\n        try:\n            # Check if path is under user workspace\n            abs_path.resolve().relative_to(user_workspace.resolve())\n        except ValueError:\n            raise ValueError(f\"Path must be under user workspace directory ({user_workspace})\")\n    else:\n        # Relative path: directly concatenate to user workspace\n        abs_path = user_workspace / task_id\n    \n    # Normalize path (resolve .. and .)\n    abs_path = abs_path.resolve()\n    \n    # Security check: ensure final path is under user workspace\n    try:\n        rel_path = abs_path.relative_to(user_workspace.resolve())\n    except ValueError:\n        raise ValueError(f\"Path is unsafe: cannot exceed user workspace directory ({user_workspace})\")\n    \n    # Check if contains .. (prevent path traversal)\n    if '..' in rel_path.parts:\n        raise ValueError(\"Path is unsafe: cannot contain '..'\")\n    \n    # Return absolute path and display path\n    display_path = str(rel_path) if rel_path != Path('.') else ''\n    return abs_path, display_path\n\n\ndef normalize_file_path(path: str, task_id: str = None, username: str = None) -> Path:\n    \"\"\"\n    Normalize file path (for file operations, user-aware)\n    \n    Args:\n        path: File path (can be absolute or relative, relative paths are relative to user workspace)\n        task_id: Task ID (if path is relative and needs to be relative to task directory, provide this)\n        username: Username for user-specific workspace isolation\n    \n    Returns:\n        Absolute path (under user workspace)\n    \n    Raises:\n        ValueError: If path is unsafe\n    \"\"\"\n    import os\n    \n    if not username:\n        raise ValueError(\"Username is required for file path isolation\")\n    \n    user_workspace = get_user_workspace(username)\n    path = path.strip()\n    \n    # If absolute path, check if it's under user workspace\n    if os.path.isabs(path):\n        abs_path = Path(path).resolve()\n        try:\n            abs_path.relative_to(user_workspace.resolve())\n        except ValueError:\n            raise ValueError(f\"Path must be under user workspace directory ({user_workspace})\")\n    else:\n        # Relative path: relative to user workspace or task directory\n        if task_id:\n            # Relative to task directory\n            _, _ = normalize_task_id(task_id, username)  # Validate task_id\n            abs_path = (user_workspace / task_id / path).resolve()\n        else:\n            # Relative to user workspace root\n            abs_path = (user_workspace / path).resolve()\n    \n    # Final security check\n    try:\n        abs_path.relative_to(user_workspace.resolve())\n    except ValueError:\n        raise ValueError(f\"Path is unsafe: cannot exceed user workspace directory\")\n    \n    return abs_path\n\n\n# Login verification decorator\ndef login_required(f):\n    \"\"\"Login verification decorator\"\"\"\n    from functools import wraps\n    @wraps(f)\n    def decorated_function(*args, **kwargs):\n        if not session.get('logged_in'):\n            return jsonify({\"error\": \"Login required\"}), 401\n        return f(*args, **kwargs)\n    return decorated_function\n\n\ndef admin_required(f):\n    \"\"\"Admin role required.\"\"\"\n    from functools import wraps\n    @wraps(f)\n    def decorated_function(*args, **kwargs):\n        if not session.get('logged_in'):\n            return jsonify({\"error\": \"Login required\"}), 401\n        if session.get('role') != 'admin':\n            return jsonify({\"error\": \"Admin permission required\"}), 403\n        return f(*args, **kwargs)\n    return decorated_function\n\n\ndef run_agent_task(task_id: str, agent_name: str, user_input: str, \n                   agent_system: str, output_queue: queue.Queue, username: str = None):\n    \"\"\"\n    Run agent task in background thread\n    \n    Args:\n        task_id: Task ID\n        agent_name: Agent name\n        user_input: User input\n        agent_system: Agent system name\n        output_queue: Output queue\n        username: Username for execution state isolation\n    \"\"\"\n    try:\n        # Get user-specific execution state\n        if not username:\n            raise ValueError(\"Username is required for task execution\")\n        user_execution = get_user_execution(username)\n        \n        # Check stop flag\n        if user_execution.get('stop_requested', False):\n            send_message({\n                \"type\": \"error\",\n                \"agent\": agent_name,\n                \"content\": \"⏹️ Task stopped by user\",\n                \"timestamp\": None\n            })\n            output_queue.put(None)\n            return\n        # Import necessary modules\n        from utils.config_loader import ConfigLoader\n        from core.hierarchy_manager import get_hierarchy_manager\n        from core.agent_executor import AgentExecutor\n        from utils.event_emitter import init_event_emitter\n        \n        # Create output capture (deprecated - this function is not used)\n        def send_message(msg):\n            output_queue.put(msg)\n        \n        # OutputCapture is no longer used - this function is deprecated\n        # capture = OutputCapture(send_message, agent_name)\n        # capture.start()\n        \n        try:\n            # Send start message\n            send_message({\n                \"type\": \"start\",\n                \"agent\": agent_name,\n                \"content\": f\"🚀 Start task: {user_input}\",\n                \"timestamp\": None\n            })\n            \n            # Initialize config loader\n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": \"📦 Loading config...\",\n                \"timestamp\": None\n            })\n            \n            config_loader = ConfigLoader(agent_system, agent_library_root=str(get_web_user_data_root(username)))\n            \n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": f\"✅ Configuration loaded successfully, {len(config_loader.all_tools)} tools/Agents\",\n                \"timestamp\": None\n            })\n            \n            # Initialize hierarchy manager\n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": \"📊 Initializing hierarchy manager...\",\n                \"timestamp\": None\n            })\n            \n            hierarchy_manager = get_hierarchy_manager(task_id)\n            \n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": \"✅ Hierarchy manager initialized successfully\",\n                \"timestamp\": None\n            })\n            \n            # Clean state\n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": \"🧹 Checking and cleaning state...\",\n                \"timestamp\": None\n            })\n            \n            from core.state_cleaner import clean_before_start\n            clean_before_start(task_id, user_input)\n            \n            # Register user instruction\n            instruction_id = hierarchy_manager.start_new_instruction(user_input)\n            \n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": f\"✅ Instruction registered: {instruction_id}\",\n                \"timestamp\": None\n            })\n            \n            # Get Agent config\n            agent_config = config_loader.get_tool_config(agent_name)\n            \n            if agent_config.get(\"type\") != \"llm_call_agent\":\n                send_message({\n                    \"type\": \"error\",\n                    \"agent\": agent_name,\n                    \"content\": f\"❌ Error: {agent_name} is not a LLM Agent\",\n                    \"timestamp\": None\n                })\n                return\n            \n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": f\"✅ Agent configuration loaded successfully (Level: {agent_config.get('level', 'unknown')})\",\n                \"timestamp\": None\n            })\n            \n            # Create and run Agent\n            send_message({\n                \"type\": \"info\",\n                \"agent\": agent_name,\n                \"content\": \"▶️ Start executing task\",\n                \"timestamp\": None\n            })\n            \n            # Check stop flag\n            if user_execution.get('stop_requested', False):\n                send_message({\n                    \"type\": \"error\",\n                    \"agent\": agent_name,\n                    \"content\": \"⏹️ Task has been stopped by user\",\n                    \"timestamp\": None\n                })\n                output_queue.put(None)\n                return\n            \n            agent = AgentExecutor(\n                agent_name=agent_name,\n                agent_config=agent_config,\n                config_loader=config_loader,\n                hierarchy_manager=hierarchy_manager\n            )\n            \n            # Update captured agent name (deprecated)\n            # capture.set_agent(agent_name)\n            \n            result = agent.run(task_id, user_input)\n            \n            # Check stop flag again after execution\n            if user_execution.get('stop_requested', False):\n                send_message({\n                    \"type\": \"error\",\n                    \"agent\": agent_name,\n                    \"content\": \"⏹️ Task stopped by user\",\n                    \"timestamp\": None\n                })\n                output_queue.put(None)\n                return\n            \n            # Send result\n            status = result.get('status', 'unknown')\n            output = result.get('output', '')\n            error_info = result.get('error_information', '')\n            \n            send_message({\n                \"type\": \"result\",\n                \"agent\": agent_name,\n                \"content\": f\"📊 Execution result:\\nStatus: {status}\\nOutput: {output}\\n\" + (f\"Error: {error_info}\" if error_info else \"\"),\n                \"timestamp\": None\n            })\n            \n            send_message({\n                \"type\": \"end\",\n                \"agent\": agent_name,\n                \"content\": f\"{'✅' if status == 'success' else '❌'} Task completed\",\n                \"timestamp\": None\n            })\n            \n        finally:\n            # capture.stop()  # Deprecated - OutputCapture no longer used\n            output_queue.put(None)  # End marker\n            \n    except Exception as e:\n        import traceback\n        error_msg = f\"❌ Execution failed: {str(e)}\\n{traceback.format_exc()}\"\n        output_queue.put({\n            \"type\": \"error\",\n            \"agent\": agent_name,\n            \"content\": error_msg,\n            \"timestamp\": None\n        })\n        output_queue.put(None)  # End marker\n\n\n@app.route('/')\ndef index():\n    \"\"\"Home page\"\"\"\n    # If not logged in, redirect to login page\n    if not session.get('logged_in'):\n        return render_template('login.html')\n    return render_template('index.html')\n\n\n@app.route('/api/login', methods=['POST'])\ndef login():\n    \"\"\"Login verification\"\"\"\n    try:\n        data = request.json\n        username = data.get('username', '').strip()\n        password = data.get('password', '').strip()\n        \n        account = authenticate_user(username, password)\n        if account:\n            session['logged_in'] = True\n            session['username'] = account['username']\n            session['role'] = account.get('role', 'user')\n            ensure_user_runtime_ready(account['username'])\n            get_user_workspace(account['username'])\n            return jsonify({\n                \"success\": True,\n                \"message\": \"Login successful\",\n                \"user\": account,\n            })\n        else:\n            return jsonify({\n                \"error\": \"Incorrect username or password\"\n            }), 401\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/register', methods=['POST'])\ndef register():\n    \"\"\"Self-service registration.\"\"\"\n    try:\n        data = request.json or {}\n        username = str(data.get('username', '')).strip()\n        password = str(data.get('password', '')).strip()\n        account = register_user(username, password, role='user')\n        session['logged_in'] = True\n        session['username'] = account['username']\n        session['role'] = account.get('role', 'user')\n        ensure_user_runtime_ready(account['username'])\n        get_user_workspace(account['username'])\n        return jsonify({\n            \"success\": True,\n            \"message\": \"Registration successful\",\n            \"user\": account,\n        })\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 400\n\n\n@app.route('/api/logout', methods=['POST'])\ndef logout():\n    \"\"\"Logout\"\"\"\n    session.clear()\n    return jsonify({\n        \"success\": True,\n        \"message\": \"Logged out\"\n    })\n\n\n@app.route('/api/check-auth', methods=['GET'])\ndef check_auth():\n    \"\"\"Check login status\"\"\"\n    if session.get('logged_in'):\n        return jsonify({\n            \"logged_in\": True,\n            \"username\": session.get('username', ''),\n            \"role\": session.get('role', 'user'),\n            \"can_manage_users\": session.get('role', 'user') == 'admin',\n        })\n    else:\n        return jsonify({\n            \"logged_in\": False\n        })\n\n\n@app.route('/health', methods=['GET'])\ndef health():\n    return jsonify({\n        \"status\": \"healthy\",\n        \"service\": \"web_ui\",\n        \"running_users\": sum(1 for st in current_executions.values() if st.get('running'))\n    })\n\n\n@app.route('/api/users', methods=['GET'])\n@admin_required\ndef api_list_users():\n    try:\n        return jsonify({\n            \"users\": list_account_records()\n        })\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/users', methods=['POST'])\n@admin_required\ndef api_create_user():\n    try:\n        data = request.json or {}\n        username = str(data.get('username', '')).strip()\n        password = str(data.get('password', '')).strip()\n        role = str(data.get('role', 'user')).strip()\n        account = register_user(username, password, role=role)\n        ensure_user_runtime_ready(account['username'])\n        return jsonify({\"success\": True, \"user\": account})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 400\n\n\n@app.route('/api/users/<username>', methods=['PATCH'])\n@admin_required\ndef api_update_user(username: str):\n    try:\n        data = request.json or {}\n        password = data.get('password')\n        role = data.get('role')\n        enabled = data.get('enabled')\n        account = update_account(\n            username,\n            password=password if password is not None else None,\n            role=role if role is not None else None,\n            enabled=enabled if enabled is not None else None,\n            actor_username=session.get('username'),\n        )\n        if username == session.get('username'):\n            session['role'] = account.get('role', session.get('role', 'user'))\n        return jsonify({\"success\": True, \"user\": account})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 400\n\n\n@app.route('/api/users/<username>', methods=['DELETE'])\n@admin_required\ndef api_delete_user(username: str):\n    try:\n        delete_account(username, actor_username=session.get('username'))\n        return jsonify({\"success\": True})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 400\n\n\n@app.route('/api/run', methods=['POST'])\n@login_required\ndef run_task():\n    \"\"\"Run agent task - SSE streaming output\"\"\"\n    data = request.json\n    \n    username = session.get('username')\n    if not username:\n        return jsonify({\"error\": \"User not authenticated\"}), 401\n    \n    task_id_input = data.get('task_id')\n    agent_name = data.get('agent_name', 'alpha_agent')\n    user_input = data.get('user_input')\n    agent_system = data.get('agent_system', 'Researcher')\n    \n    if not task_id_input or not user_input:\n        return jsonify({\"error\": \"Missing required parameters\"}), 400\n    \n    # Normalize task ID path (user-aware)\n    try:\n        task_path, _ = normalize_task_id(task_id_input, username)\n        task_id_absolute = str(task_path)  # Use absolute path to pass to start.py\n    except ValueError as e:\n        return jsonify({\"error\": str(e)}), 400\n    \n    # Get user-specific execution state\n    user_execution = get_user_execution(username)\n    \n    # Check if task is already running for this user\n    if user_execution['running']:\n        return jsonify({\"error\": \"Task already running\"}), 409\n    \n    # Create output queue\n    output_queue = queue.Queue()\n    user_execution['output_queue'] = output_queue\n    user_execution['running'] = True\n    user_execution['stop_requested'] = False\n    user_execution['pending_hil'] = None\n    user_execution['pending_tool_confirmation'] = None\n    \n    ensure_user_runtime_ready(username)\n    worker_script = server_dir / 'sdk_worker.py'\n    \n    process_env = os.environ.copy()\n    process_env.update(get_user_runtime_overrides(username))\n\n    process = subprocess.Popen(\n        [\n            sys.executable,\n            str(worker_script),\n            '--task_id', task_id_absolute,\n            '--user_data_root', str(get_web_user_data_root(username)),\n            '--skills_dir', str(get_web_user_skills_dir(username)),\n            '--agent_name', agent_name,\n            '--user_input', user_input,\n            '--agent_system', agent_system,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n        stdin=subprocess.PIPE,\n        text=True,\n        bufsize=1,\n        universal_newlines=True,\n        env=process_env,\n    )\n    \n    user_execution['process'] = process\n    \n    # Helper function to convert JSONL event to frontend format\n    def convert_event_to_frontend_format(event, default_agent_name):\n        \"\"\"Convert JSONL event to frontend message format\"\"\"\n        event_type = event.get(\"type\", \"token\")\n        agent = event.get(\"agent\", default_agent_name)\n        \n        frontend_event = {\n            \"type\": event_type,\n            \"agent\": agent,\n            \"content\": \"\",\n            \"timestamp\": datetime.now().isoformat()\n        }\n        \n        # Map event types to frontend format\n        if event_type == \"tool_call\":\n            # 结构化工具调用事件\n            tool_name = event.get(\"tool_name\") or event.get(\"name\", \"unknown\")\n            parameters = event.get(\"parameters\") or event.get(\"arguments\", {})\n            import json\n            params_str = json.dumps(parameters, ensure_ascii=False, indent=2)\n            frontend_event[\"type\"] = \"tool_call\"\n            frontend_event[\"tool_name\"] = tool_name\n            frontend_event[\"arguments\"] = parameters\n            frontend_event[\"content\"] = f\"🔧 [{default_agent_name}] calls tool: {tool_name}\\n\\n📋 Parameters:\\n{params_str}\"\n            \n        elif event_type == \"agent_call\":\n            # 结构化子 Agent 调用事件\n            agent_name = event.get(\"agent_name\", \"unknown\")\n            parameters = event.get(\"parameters\", {})\n            import json\n            params_str = json.dumps(parameters, ensure_ascii=False, indent=2)\n            frontend_event[\"type\"] = \"agent_call\"\n            frontend_event[\"content\"] = f\"🤖 [{default_agent_name}] calls sub-agent: {agent_name}\\n\\n📋 Parameters:\\n{params_str}\"\n            \n        elif event_type == \"human_in_loop\":\n            frontend_event[\"type\"] = \"human_in_loop\"\n            frontend_event[\"hil_id\"] = event.get(\"hil_id\", \"\")\n            frontend_event[\"instruction\"] = event.get(\"message\", \"\")\n            frontend_event[\"content\"] = event.get(\"message\", \"\")\n\n        elif event_type == \"tool_confirmation\":\n            frontend_event[\"type\"] = \"tool_confirmation\"\n            frontend_event[\"confirm_id\"] = event.get(\"confirm_id\", \"\")\n            frontend_event[\"tool_name\"] = event.get(\"tool_name\", \"\")\n            frontend_event[\"arguments\"] = event.get(\"arguments\", {})\n            frontend_event[\"content\"] = f\"⚠️ Tool confirmation required: {frontend_event['tool_name']}\"\n\n        elif event_type == \"tool_result\":\n            frontend_event[\"type\"] = \"tool_result\"\n            name = event.get(\"name\", \"unknown\")\n            status = event.get(\"status\", \"unknown\")\n            preview = event.get(\"output_preview\", \"\")\n            error_text = event.get(\"error\", \"\")\n            frontend_event[\"tool_name\"] = name\n            frontend_event[\"status\"] = status\n            frontend_event[\"output_preview\"] = preview\n            frontend_event[\"error\"] = error_text\n            frontend_event[\"content\"] = (\n                f\"🔧 Tool result: {name} ({status})\\n\\n\"\n                + (f\"Error:\\n{error_text}\" if error_text else f\"Output:\\n{preview}\")\n            )\n\n        elif event_type == \"agent_start\":\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"agent\"] = event.get(\"agent\", default_agent_name)\n            frontend_event[\"content\"] = f\"🤖 Agent start: {event.get('agent', default_agent_name)}\"\n\n        elif event_type == \"agent_end\":\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"content\"] = f\"🏁 Agent end: {event.get('status', 'unknown')}\"\n\n        elif event_type == \"thinking_start\":\n            frontend_event[\"type\"] = \"thinking_start\"\n            frontend_event[\"content\"] = \"Thinking...\"\n\n        elif event_type == \"thinking_end\":\n            frontend_event[\"type\"] = \"thinking_end\"\n            frontend_event[\"content\"] = str(event.get(\"result\", \"\") or \"\")\n\n        elif event_type == \"thinking_token\":\n            text = event.get(\"text\", \"\")\n            if not text:\n                return None\n            frontend_event[\"type\"] = \"thinking_token\"\n            frontend_event[\"content\"] = text\n\n        elif event_type == \"token\":\n            text = event.get(\"text\", \"\")\n            if not text.strip():\n                return None  # Skip empty content\n            \n            # Filter initialization messages (不需要在前端显示)\n            if \"加载配置\" in text or \"配置加载成功\" in text:\n                return None  # Skip config loading messages\n            frontend_event[\"type\"] = \"token\"\n            frontend_event[\"content\"] = text\n\n        elif event_type == \"reasoning_token\":\n            text = event.get(\"text\", \"\")\n            if not text:\n                return None\n            frontend_event[\"type\"] = \"reasoning_token\"\n            frontend_event[\"content\"] = text\n                \n        elif event_type == \"start\":\n            frontend_event[\"type\"] = \"start\"\n            frontend_event[\"agent\"] = event.get(\"agent\", default_agent_name)\n            frontend_event[\"content\"] = f\"🚀 任务开始: {event.get('task', '')}\"\n            \n        elif event_type == \"progress\":\n            # Filter initialization progress updates (不需要在前端显示)\n            phase = event.get(\"phase\", \"\")\n            if phase == \"init\":\n                return None  # Skip init phase progress updates\n            \n            pct = event.get(\"pct\", 0)\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"content\"] = f\"📊 进度更新: {phase} ({pct}%)\"\n            \n        elif event_type == \"notice\":\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"content\"] = f\"ℹ️ {event.get('text', '')}\"\n            \n        elif event_type == \"warn\":\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"content\"] = f\"⚠️ {event.get('text', '')}\"\n            \n        elif event_type == \"error\":\n            frontend_event[\"type\"] = \"error\"\n            frontend_event[\"content\"] = f\"❌ {event.get('text', '')}\"\n            \n        elif event_type == \"result\":\n            summary = event.get(\"summary\", \"\")\n            ok = event.get(\"ok\", False)\n            icon = \"✅\" if ok else \"❌\"\n            frontend_event[\"type\"] = \"info\"\n            frontend_event[\"content\"] = f\"{icon} 执行结果: {summary}\"\n            \n        elif event_type == \"end\":\n            status = event.get(\"status\", \"unknown\")\n            duration_ms = event.get(\"duration_ms\", 0)\n            duration = duration_ms / 1000 if duration_ms else 0\n            icon = \"✅\" if status == \"ok\" else \"❌\"\n            frontend_event[\"type\"] = \"end\"\n            frontend_event[\"content\"] = f\"{icon} 任务完成 ({duration:.1f}秒)\"\n            \n        else:\n            # Unknown event type, try to extract text field\n            text = event.get(\"text\", \"\")\n            if text:\n                frontend_event[\"type\"] = \"info\"\n                frontend_event[\"content\"] = text\n            else:\n                # Skip events without content\n                return None\n        \n        always_emit_types = {\"end\", \"thinking_start\", \"thinking_end\", \"tool_call\", \"tool_result\", \"human_in_loop\", \"tool_confirmation\"}\n        return frontend_event if frontend_event.get(\"content\") or frontend_event.get(\"type\") in always_emit_types else None\n    \n    # Read process output in background thread\n    def read_process_output():\n        \"\"\"Read subprocess output - directly parse JSONL events\"\"\"\n        end_event_received = False\n        try:\n            buffer = \"\"\n            for line in process.stdout:\n                if user_execution.get('stop_requested', False):\n                    break\n                \n                # Handle possible multi-line JSON (though JSONL is usually one line per JSON)\n                buffer += line\n                if not line.endswith('\\n'):\n                    continue  # Continue accumulating\n                \n                # Try to parse each line\n                lines = buffer.split('\\n')\n                buffer = lines[-1]  # Keep the last incomplete line\n                \n                for json_line in lines[:-1]:\n                    json_line = json_line.strip()\n                    if not json_line:\n                        continue\n                    \n                    try:\n                        # Parse JSONL event\n                        event = json.loads(json_line)\n                        \n                        # Track if end event was received\n                        if event.get(\"type\") == \"end\":\n                            end_event_received = True\n                        elif event.get(\"type\") == \"human_in_loop\":\n                            user_execution['pending_hil'] = {\n                                \"hil_id\": event.get(\"hil_id\", \"\"),\n                                \"instruction\": event.get(\"message\", \"\"),\n                            }\n                        elif event.get(\"type\") == \"tool_confirmation\":\n                            user_execution['pending_tool_confirmation'] = {\n                                \"confirm_id\": event.get(\"confirm_id\", \"\"),\n                                \"tool_name\": event.get(\"tool_name\", \"\"),\n                                \"arguments\": event.get(\"arguments\", {}) or {},\n                            }\n                        \n                        # Convert to frontend format\n                        frontend_event = convert_event_to_frontend_format(event, agent_name)\n                        \n                        # Send event if valid\n                        if frontend_event:\n                            output_queue.put(frontend_event)\n                            \n                    except json.JSONDecodeError:\n                        continue\n                    except Exception as e:\n                        # 捕获其他所有异常，输出错误但继续读取\n                        import traceback\n                        output_queue.put({\n                            \"type\": \"error\",\n                            \"agent\": agent_name,\n                            \"content\": f\"⚠️ 处理事件异常: {str(e)}\",\n                            \"timestamp\": datetime.now().isoformat()\n                        })\n                        # 记录详细错误日志供调试\n                        print(f\"⚠️ 处理事件异常，继续读取: {str(e)}\\n{traceback.format_exc()}\", flush=True)\n                        continue  # 继续处理下一个事件\n            \n            # Process remaining buffer\n            if buffer.strip():\n                try:\n                    event = json.loads(buffer.strip())\n                    if event.get(\"type\") == \"end\":\n                        end_event_received = True\n                    frontend_event = convert_event_to_frontend_format(event, agent_name)\n                    if frontend_event:\n                        output_queue.put(frontend_event)\n                except json.JSONDecodeError:\n                    pass\n                \n                # Wait for process to end\n                process.wait()\n                \n            # Send end message if not already received\n            if not end_event_received:\n                if user_execution.get('stop_requested', False):\n                    output_queue.put({\n                        \"type\": \"error\",\n                        \"agent\": agent_name,\n                        \"content\": \"⏹️ 任务已停止\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n                elif process.returncode == 0:\n                    output_queue.put({\n                        \"type\": \"end\",\n                        \"agent\": agent_name,\n                        \"content\": \"✅ 任务完成\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n                else:\n                    output_queue.put({\n                        \"type\": \"error\",\n                        \"agent\": agent_name,\n                        \"content\": f\"⚠️ 进程退出码: {process.returncode}\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n            \n                output_queue.put(None)  # End marker\n            \n        except Exception as e:\n            import traceback\n            error_detail = f\"{str(e)}\\n{traceback.format_exc()}\"\n            print(f\"❌ 读取输出循环异常: {error_detail}\", flush=True)\n            \n            # 输出错误但不终止 - 等待进程结束\n            output_queue.put({\n                \"type\": \"error\",\n                \"agent\": agent_name,\n                \"content\": f\"⚠️ 读取输出异常: {str(e)}，等待进程结束...\",\n                \"timestamp\": datetime.now().isoformat()\n            })\n            \n            # 等待进程结束\n            try:\n                if process.poll() is None:  # 进程还在运行\n                    print(\"⏳ 进程仍在运行，等待完成...\", flush=True)\n                    process.wait(timeout=300)  # 最多等待5分钟\n                    print(f\"✅ 进程已结束，退出码: {process.returncode}\", flush=True)\n                \n                # 发送最终状态\n                if process.returncode == 0:\n                    output_queue.put({\n                        \"type\": \"end\",\n                        \"agent\": agent_name,\n                        \"content\": \"✅ 进程完成\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n                else:\n                    output_queue.put({\n                        \"type\": \"error\",\n                        \"agent\": agent_name,\n                        \"content\": f\"⚠️ 进程退出码: {process.returncode}\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n            except Exception as wait_err:\n                print(f\"⚠️ 等待进程失败: {wait_err}\", flush=True)\n            finally:\n                output_queue.put(None)  # 发送终止标记\n        finally:\n            user_execution['running'] = False\n            user_execution['process'] = None\n            user_execution['pending_hil'] = None\n            user_execution['pending_tool_confirmation'] = None\n\n    def read_process_stderr():\n        try:\n            for line in process.stderr:\n                text = str(line or \"\").strip()\n                if not text:\n                    continue\n                if any(keyword in text for keyword in ['Error', 'Exception', 'Traceback', 'CRITICAL', 'FATAL']):\n                    output_queue.put({\n                        \"type\": \"error\",\n                        \"agent\": agent_name,\n                        \"content\": f\"❌ {text}\",\n                        \"timestamp\": datetime.now().isoformat()\n                    })\n        except Exception:\n            pass\n\n    reader_thread = threading.Thread(target=read_process_output, daemon=True)\n    user_execution['reader_thread'] = reader_thread\n    reader_thread.start()\n    stderr_thread = threading.Thread(target=read_process_stderr, daemon=True)\n    stderr_thread.start()\n    \n    # Track this SSE connection\n    import uuid\n    connection_id = str(uuid.uuid4())\n    user_execution['sse_connections'].add(connection_id)\n    \n    def generate():\n        \"\"\"Generate SSE event stream\"\"\"\n        try:\n            while True:\n                try:\n                    # Get message from queue (1 second timeout)\n                    msg = output_queue.get(timeout=1)\n                    \n                    if msg is None:  # End marker\n                        yield f\"data: {json.dumps({'type': 'end', 'content': 'Task completed'}, ensure_ascii=False)}\\n\\n\"\n                        break\n                    \n                    # Add timestamp\n                    if msg.get('timestamp') is None:\n                        from datetime import datetime\n                        msg['timestamp'] = datetime.now().isoformat()\n                    \n                    # Send SSE event\n                    yield f\"data: {json.dumps(msg, ensure_ascii=False)}\\n\\n\"\n                    \n                except queue.Empty:\n                    # Timeout, send heartbeat\n                    yield f\": heartbeat\\n\\n\"\n                    continue\n                    \n        except GeneratorExit:\n            # Client disconnected (e.g., page refresh or new window)\n            # Remove this connection from active connections\n            user_execution['sse_connections'].discard(connection_id)\n            \n            # Only stop process if no active connections remain\n            if len(user_execution['sse_connections']) == 0:\n                process = user_execution.get('process')\n                if process and process.poll() is None:  # Process still running\n                    try:\n                        user_execution['stop_requested'] = True\n                        process.terminate()\n                        try:\n                            process.wait(timeout=2)\n                        except subprocess.TimeoutExpired:\n                            process.kill()\n                            process.wait()\n                    except:\n                        pass\n                    finally:\n                        user_execution['running'] = False\n                        user_execution['process'] = None\n                        user_execution['reader_thread'] = None\n                        user_execution['stop_requested'] = False\n        finally:\n            # Remove connection on normal exit\n            user_execution['sse_connections'].discard(connection_id)\n            \n            # Only mark as not running if no active connections remain\n            if len(user_execution['sse_connections']) == 0:\n                user_execution['running'] = False\n                user_execution['stop_requested'] = False\n    \n    return Response(\n        generate(),\n        mimetype='text/event-stream',\n        headers={\n            'Cache-Control': 'no-cache',\n            'X-Accel-Buffering': 'no',\n            'Connection': 'keep-alive'\n        }\n    )\n\n\n@app.route('/api/task/confirm', methods=['POST'])\n@login_required\ndef confirm_task():\n    \"\"\"Confirm task ID, create if not exists\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        # Get user-specific execution state\n        user_execution = get_user_execution(username)\n        \n        # Auto cleanup: if task is running, stop it first (prevent process residue after refresh)\n        if user_execution.get('running'):\n            process = user_execution.get('process')\n            if process and process.poll() is None:  # Process still running\n                try:\n                    # Set stop flag\n                    user_execution['stop_requested'] = True\n                    # Terminate process\n                    process.terminate()\n                    try:\n                        process.wait(timeout=2)\n                    except subprocess.TimeoutExpired:\n                        process.kill()\n                        process.wait()\n                except Exception as e:\n                    # If termination fails, try force kill\n                    try:\n                        process.kill()\n                        process.wait()\n                    except:\n                        pass\n                finally:\n                    # Clean state\n                    user_execution['running'] = False\n                    user_execution['process'] = None\n                    user_execution['reader_thread'] = None\n        \n        data = request.json\n        task_id_input = data.get('task_id', '').strip()\n        \n        if not task_id_input:\n            return jsonify({\"error\": \"Missing task_id parameter\"}), 400\n        \n        # Normalize task ID path (user-aware)\n        try:\n            task_path, display_path = normalize_task_id(task_id_input, username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        is_new = False\n        \n        if task_path.exists():\n            if not task_path.is_dir():\n                return jsonify({\"error\": \"Path exists but is not a directory\"}), 400\n            # Directory already exists\n            is_new = False\n        else:\n            # Create new directory\n            try:\n                task_path.mkdir(parents=True, exist_ok=True)\n                is_new = True\n            except Exception as e:\n                return jsonify({\"error\": f\"Create directory failed: {str(e)}\"}), 500\n        \n        # Return display path (relative to workspace root)\n        return jsonify({\n            \"success\": True,\n            \"task_id\": display_path if display_path else '/',\n            \"task_id_absolute\": str(task_path),  # Internal use\n            \"is_new\": is_new,\n            \"message\": \"New task created\" if is_new else \"Entered existing task\"\n        })\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/stop', methods=['POST'])\n@login_required\ndef stop_task():\n    \"\"\"Stop currently running task\"\"\"\n    username = session.get('username')\n    if not username:\n        return jsonify({\"error\": \"User not authenticated\"}), 401\n    \n    user_execution = get_user_execution(username)\n    \n    if not user_execution['running']:\n        return jsonify({\"error\": \"No task is running\"}), 400\n    \n    process = user_execution.get('process')\n    if not process:\n        return jsonify({\"error\": \"Process object does not exist\"}), 400\n    \n    try:\n        # Set stop flag\n        user_execution['stop_requested'] = True\n        \n        # Terminate process\n        if process.poll() is None:  # Process still running\n            try:\n                # Try graceful termination first\n                process.terminate()\n                # Wait up to 2 seconds\n                try:\n                    process.wait(timeout=2)\n                except subprocess.TimeoutExpired:\n                    # If not terminated after 2 seconds, force kill\n                    process.kill()\n                    process.wait()\n            except Exception as e:\n                # If termination fails, try force kill\n                try:\n                    process.kill()\n                    process.wait()\n                except:\n                    pass\n        \n        user_execution['running'] = False\n        user_execution['pending_hil'] = None\n        user_execution['pending_tool_confirmation'] = None\n        \n        return jsonify({\n            \"success\": True,\n            \"message\": \"Task stopped\"\n        })\n    except Exception as e:\n        return jsonify({\n            \"error\": f\"Stop failed: {str(e)}\"\n        }), 500\n\n\n@app.route('/api/agents', methods=['GET'])\n@login_required\ndef get_agents():\n    \"\"\"Get available agent list\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        ensure_user_runtime_ready(username)\n        agent_system = request.args.get('agent_system', 'Researcher')\n        \n        from utils.config_loader import ConfigLoader\n        config_loader = ConfigLoader(agent_system, agent_library_root=str(get_web_user_data_root(username)))\n        \n        agents = []\n        for name, config in config_loader.all_tools.items():\n            if config.get(\"type\") == \"llm_call_agent\":\n                level = config.get(\"level\", 0)\n                agents.append({\n                    \"name\": name,\n                    \"level\": level,\n                    \"description\": config.get(\"description\", \"\")\n                })\n        \n        # Sort by level\n        agents.sort(key=lambda x: x[\"level\"])\n        \n        return jsonify({\"agents\": agents})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/agent-systems', methods=['GET'])\n@login_required\ndef get_agent_systems():\n    \"\"\"List all available agent systems from user library.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        ensure_user_runtime_ready(username)\n        agent_library_dir = get_web_user_agent_library_root(username)\n        systems = []\n        if agent_library_dir.exists():\n            for d in sorted(agent_library_dir.iterdir()):\n                if d.is_dir() and not d.name.startswith('.'):\n                    systems.append(d.name)\n        return jsonify({\"systems\": systems})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/resume/check', methods=['GET'])\n@login_required\ndef check_resume():\n    \"\"\"Check if there's an interrupted task that can be resumed\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        task_id_input = request.args.get('task_id', '')\n        if not task_id_input:\n            return jsonify({\"found\": False, \"message\": \"Missing task_id parameter\"})\n        \n        # Normalize task path\n        try:\n            task_path, _ = normalize_task_id(task_id_input, username)\n            task_id = str(task_path)\n        except ValueError as e:\n            return jsonify({\"found\": False, \"message\": str(e)})\n        \n        import hashlib\n        \n        # Calculate task hash (same logic as hierarchy_manager and cli_mode)\n        task_hash = hashlib.md5(task_id.encode()).hexdigest()[:8]\n        task_folder = Path(task_id).name if (os.sep in task_id or '/' in task_id or '\\\\' in task_id) else task_id\n        task_name = f\"{task_hash}_{task_folder}\"\n        \n        # Stack file location\n        conversations_dir = get_web_user_conversations_dir(username)\n        stack_file = conversations_dir / f\"{task_name}_stack.json\"\n        \n        if not stack_file.exists():\n            return jsonify({\"found\": False, \"message\": \"No interrupted task found\"})\n        \n        # Read stack\n        with open(stack_file, 'r', encoding='utf-8') as f:\n            data = json.load(f)\n            stack = data.get(\"stack\", [])\n        \n        if not stack:\n            return jsonify({\"found\": False, \"message\": \"Stack is empty\"})\n        \n        # Get bottom task (original user input)\n        bottom_task = stack[0]\n        agent_name = bottom_task.get(\"agent_name\")\n        user_input = bottom_task.get(\"user_input\")\n        \n        if not agent_name or not user_input:\n            return jsonify({\"found\": False, \"message\": \"Task data incomplete\"})\n        \n        return jsonify({\n            \"found\": True,\n            \"agent_name\": agent_name,\n            \"user_input\": user_input,\n            \"interrupted_at\": bottom_task.get(\"start_time\", \"unknown\"),\n            \"stack_depth\": len(stack)\n        })\n    \n    except Exception as e:\n        return jsonify({\"found\": False, \"message\": str(e)})\n\n\n@app.route('/api/status', methods=['GET'])\n@login_required\ndef get_status():\n    \"\"\"Get current execution status\"\"\"\n    username = session.get('username')\n    if not username:\n        return jsonify({\"error\": \"User not authenticated\"}), 401\n    \n    user_execution = get_user_execution(username)\n    process = user_execution.get('process')\n    is_running = user_execution.get('running', False)\n    \n    # Check if process is really running\n    if is_running and process:\n        if process.poll() is not None:\n            # Process ended but state not cleaned\n            is_running = False\n            user_execution['running'] = False\n            user_execution['process'] = None\n    \n    return jsonify({\n        \"running\": is_running,\n        \"has_process\": process is not None\n    })\n\n\n@app.route('/api/tasks/list', methods=['GET'])\n@login_required\ndef list_tasks():\n    \"\"\"Get all task directories under workspace root\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        tasks = []\n        \n        # Get user-specific workspace\n        user_workspace = get_user_workspace(username)\n        \n        if not user_workspace.exists():\n            return jsonify({\"tasks\": []})\n        \n        # Iterate all directories under user workspace\n        for item in sorted(user_workspace.iterdir()):\n            # Skip hidden files and files (only show directories)\n            if item.name.startswith('.') or not item.is_dir():\n                continue\n            \n            # Calculate relative path (for display)\n            try:\n                rel_path = item.relative_to(user_workspace)\n                display_path = str(rel_path) if rel_path != Path('.') else ''\n            except ValueError:\n                display_path = item.name\n            \n            tasks.append({\n                \"name\": item.name,\n                \"path\": display_path,  # Relative path (for frontend display)\n                \"path_absolute\": str(item)  # Absolute path (internal use)\n            })\n        \n        return jsonify({\"tasks\": tasks})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/files/list', methods=['GET'])\n@login_required\ndef list_files():\n    \"\"\"Get file list under specified path\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        path = request.args.get('path', '')\n        task_id = request.args.get('task_id', '')\n        if not path:\n            return jsonify({\"error\": \"Missing path parameter\"}), 400\n        \n        # Normalize path (limited to user workspace directory)\n        try:\n            path_obj = normalize_file_path(path, task_id=task_id if task_id else None, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not path_obj.exists():\n            return jsonify({\"error\": \"Path does not exist\"}), 404\n        \n        if not path_obj.is_dir():\n            return jsonify({\"error\": \"Path is not a directory\"}), 400\n        \n        # Get user workspace for relative path calculation\n        user_workspace = get_user_workspace(username)\n        \n        # Calculate relative path (for display)\n        try:\n            rel_path = path_obj.relative_to(user_workspace)\n            display_path = str(rel_path) if rel_path != Path('.') else ''\n        except ValueError:\n            display_path = str(path_obj)\n        \n        files = []\n        for item in sorted(path_obj.iterdir()):\n            # Skip hidden files and special directories\n            if item.name.startswith('.'):\n                continue\n            if item.name in HIDDEN_WORKSPACE_NAMES:\n                continue\n            \n            # Calculate file relative path (for display)\n            try:\n                item_rel = item.relative_to(user_workspace)\n                item_display_path = str(item_rel) if item_rel != Path('.') else ''\n            except ValueError:\n                item_display_path = str(item)\n            \n            files.append({\n                \"name\": item.name,\n                \"path\": item_display_path,  # Return relative path (for frontend display)\n                \"path_absolute\": str(item),  # Absolute path for internal use\n                \"type\": \"directory\" if item.is_dir() else \"file\",\n                \"size\": item.stat().st_size if item.is_file() else 0\n            })\n        \n        return jsonify({\n            \"files\": files,\n            \"path\": display_path  # Current path (relative path)\n        })\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/files/read', methods=['GET'])\n@login_required\ndef read_file():\n    \"\"\"Read file content\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        path = request.args.get('path', '')\n        task_id = request.args.get('task_id', '')\n        if not path:\n            return jsonify({\"error\": \"Missing path parameter\"}), 400\n        \n        # Normalize path (limited to user workspace directory)\n        try:\n            path_obj = normalize_file_path(path, task_id=task_id if task_id else None, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not path_obj.exists():\n            return jsonify({\"error\": \"File not found\"}), 404\n        \n        if not path_obj.is_file():\n            return jsonify({\"error\": \"Path is not a file\"}), 400\n        \n        # Try to read file\n        try:\n            content = path_obj.read_text(encoding='utf-8')\n        except UnicodeDecodeError:\n            # If not text file, return binary hint\n            return jsonify({\n                \"error\": \"Cannot read file as text (may be binary file)\",\n                \"size\": path_obj.stat().st_size\n            }), 400\n        \n        # Get user workspace for relative path calculation\n        user_workspace = get_user_workspace(username)\n        \n        # Calculate relative path (for display)\n        try:\n            rel_path = path_obj.relative_to(user_workspace)\n            display_path = str(rel_path) if rel_path != Path('.') else ''\n        except ValueError:\n            display_path = str(path_obj)\n        \n        return jsonify({\n            \"content\": content,\n            \"path\": display_path,  # Return relative path (for frontend display)\n            \"size\": path_obj.stat().st_size\n        })\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/task/clear', methods=['POST'])\n@login_required\ndef clear_task():\n    \"\"\"Clear task directory and all its files\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        user_execution = get_user_execution(username)\n        \n        # Auto cleanup: if task is running, stop it first\n        if user_execution.get('running'):\n            process = user_execution.get('process')\n            if process and process.poll() is None:  # Process still running\n                try:\n                    user_execution['stop_requested'] = True\n                    process.terminate()\n                    try:\n                        process.wait(timeout=2)\n                    except subprocess.TimeoutExpired:\n                        process.kill()\n                        process.wait()\n                except Exception as e:\n                    try:\n                        process.kill()\n                        process.wait()\n                    except:\n                        pass\n                finally:\n                    user_execution['running'] = False\n                    user_execution['process'] = None\n                    user_execution['reader_thread'] = None\n        \n        data = request.json\n        task_id_input = data.get('task_id', '').strip()\n        \n        if not task_id_input:\n            return jsonify({\"error\": \"Missing task_id parameter\"}), 400\n        \n        # Normalize task ID path (limited to user workspace)\n        try:\n            task_path, display_path = normalize_task_id(task_id_input, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not task_path.exists():\n            return jsonify({\"error\": \"Task directory does not exist\"}), 404\n        \n        if not task_path.is_dir():\n            return jsonify({\"error\": \"Path is not a directory\"}), 400\n        \n        # Recursively delete entire directory\n        import shutil\n        shutil.rmtree(task_path)\n        \n        # Also delete corresponding conversation files in home directory\n        # Generate task_hash and task_folder same way as hierarchy_manager\n        # Use absolute path (task_path) to ensure hash matches what was used during storage\n        import hashlib\n        import os\n        from pathlib import Path\n        \n        task_id_for_hash = str(task_path)  # Use absolute path for consistent hashing\n        task_hash = hashlib.md5(task_id_for_hash.encode()).hexdigest()[:8]\n        task_folder = Path(task_id_for_hash).name if (os.sep in task_id_for_hash or '/' in task_id_for_hash or '\\\\' in task_id_for_hash) else task_id_for_hash\n        task_name = f\"{task_hash}_{task_folder}\"\n        \n        # Delete all files matching the pattern in home conversations directory\n        conversations_dir = get_web_user_conversations_dir(username)\n        if conversations_dir.exists():\n            deleted_files = []\n            # Pattern: {task_hash}_{task_folder}_*.json\n            pattern = f\"{task_name}_*.json\"\n            for file_path in conversations_dir.glob(pattern):\n                try:\n                    file_path.unlink()\n                    deleted_files.append(file_path.name)\n                except Exception as e:\n                    # Log but don't fail if file deletion fails\n                    print(f\"⚠️ 删除对话历史文件失败: {file_path.name} - {e}\")\n            \n            if deleted_files:\n                print(f\"✅ 已删除主目录下的对话历史文件: {len(deleted_files)} 个文件\")\n        \n        return jsonify({\n            \"success\": True,\n            \"message\": f\"task {display_path if display_path else '/'} and all its files have been cleared\"\n        })\n    except Exception as e:\n        import traceback\n        return jsonify({\"error\": f\"Clear failed: {str(e)}\\n{traceback.format_exc()}\"}), 500\n\n\n# Global copy progress tracking (per user)\ncopy_progress = {}\ncopy_progress_lock = threading.Lock()\n\n\ndef get_copy_progress(username: str, task_id: str) -> dict:\n    \"\"\"Get copy progress for a task\"\"\"\n    with copy_progress_lock:\n        key = f\"{username}:{task_id}\"\n        return copy_progress.get(key, {\"status\": \"none\", \"progress\": 0, \"message\": \"\"})\n\n\ndef set_copy_progress(username: str, task_id: str, status: str, progress: int, message: str = \"\"):\n    \"\"\"Set copy progress for a task\"\"\"\n    with copy_progress_lock:\n        key = f\"{username}:{task_id}\"\n        copy_progress[key] = {\"status\": status, \"progress\": progress, \"message\": message}\n\n\ndef clear_copy_progress(username: str, task_id: str):\n    \"\"\"Clear copy progress for a task\"\"\"\n    with copy_progress_lock:\n        key = f\"{username}:{task_id}\"\n        if key in copy_progress:\n            del copy_progress[key]\n\n\ndef copy_tree_with_progress(src: Path, dst: Path, username: str, task_id: str):\n    \"\"\"Copy directory tree with progress tracking\"\"\"\n    import shutil\n    \n    # Count total files first\n    total_files = 0\n    for root, dirs, files in os.walk(src):\n        total_files += len(files)\n    \n    if total_files == 0:\n        total_files = 1  # Avoid division by zero\n    \n    copied_files = 0\n    \n    # Create destination directory\n    dst.mkdir(parents=True, exist_ok=True)\n    \n    try:\n        set_copy_progress(username, task_id, \"copying\", 0, f\"Starting copy: {total_files} files to copy\")\n        \n        # Walk through source directory and copy files\n        for root, dirs, files in os.walk(src):\n            # Calculate relative path\n            rel_path = Path(root).relative_to(src)\n            dst_dir = dst / rel_path\n            dst_dir.mkdir(parents=True, exist_ok=True)\n            \n            # Copy files\n            for file in files:\n                src_file = Path(root) / file\n                dst_file = dst_dir / file\n                shutil.copy2(src_file, dst_file)\n                copied_files += 1\n                progress = int((copied_files / total_files) * 100)\n                set_copy_progress(username, task_id, \"copying\", progress, \n                                 f\"Copying files: {copied_files}/{total_files}\")\n        \n        set_copy_progress(username, task_id, \"completed\", 100, f\"Copy completed: {total_files} files copied\")\n    except Exception as e:\n        set_copy_progress(username, task_id, \"error\", 0, f\"Copy failed: {str(e)}\")\n        raise\n\n\n@app.route('/api/task/copy', methods=['POST'])\n@login_required\ndef copy_task():\n    \"\"\"Copy task workspace to a new task\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        user_execution = get_user_execution(username)\n        \n        # Stop running task if any\n        if user_execution.get('running'):\n            process = user_execution.get('process')\n            if process and process.poll() is None:\n                try:\n                    user_execution['stop_requested'] = True\n                    process.terminate()\n                    try:\n                        process.wait(timeout=2)\n                    except subprocess.TimeoutExpired:\n                        process.kill()\n                        process.wait()\n                except Exception as e:\n                    try:\n                        process.kill()\n                        process.wait()\n                    except:\n                        pass\n                finally:\n                    user_execution['running'] = False\n                    user_execution['process'] = None\n                    user_execution['reader_thread'] = None\n        \n        data = request.json\n        source_task_id = data.get('source_task_id', '').strip()\n        target_task_id = data.get('target_task_id', '').strip()\n        \n        if not source_task_id or not target_task_id:\n            return jsonify({\"error\": \"Missing source_task_id or target_task_id\"}), 400\n        \n        # Normalize paths\n        try:\n            source_path, _ = normalize_task_id(source_task_id, username)\n            target_path, target_display = normalize_task_id(target_task_id, username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        # Check if source task exists\n        if not source_path.exists():\n            return jsonify({\"error\": \"Source task does not exist\"}), 404\n        \n        if not source_path.is_dir():\n            return jsonify({\"error\": \"Source path is not a directory\"}), 400\n        \n        # Check if target task already exists\n        if target_path.exists():\n            return jsonify({\"error\": \"Target task already exists\"}), 409\n        \n        # Initialize progress\n        set_copy_progress(username, target_task_id, \"starting\", 0, \"Preparing to copy...\")\n        \n        # Copy directory in background thread\n        def copy_in_thread():\n            try:\n                copy_tree_with_progress(source_path, target_path, username, target_task_id)\n            except Exception as e:\n                import traceback\n                set_copy_progress(username, target_task_id, \"error\", 0, \n                                f\"Copy failed: {str(e)}\\n{traceback.format_exc()}\")\n        \n        copy_thread = threading.Thread(target=copy_in_thread, daemon=True)\n        copy_thread.start()\n        \n        return jsonify({\n            \"success\": True,\n            \"task_id\": target_display,\n            \"task_id_absolute\": str(target_path),\n            \"message\": f\"Copy started for task {target_display}\"\n        })\n    except Exception as e:\n        import traceback\n        return jsonify({\"error\": f\"Copy failed: {str(e)}\\n{traceback.format_exc()}\"}), 500\n\n\n@app.route('/api/task/copy/progress', methods=['GET'])\n@login_required\ndef get_copy_progress_api():\n    \"\"\"Get copy progress for a task\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        task_id = request.args.get('task_id', '').strip()\n        if not task_id:\n            return jsonify({\"error\": \"Missing task_id parameter\"}), 400\n        \n        progress = get_copy_progress(username, task_id)\n        return jsonify(progress)\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/task/download', methods=['GET'])\n@login_required\ndef download_task():\n    \"\"\"Download entire task directory as ZIP archive\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        task_id = request.args.get('task_id', '').strip()\n        if not task_id:\n            return jsonify({\"error\": \"Missing task_id parameter\"}), 400\n        \n        # Normalize task path\n        try:\n            task_path, display_path = normalize_task_id(task_id, username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not task_path.exists():\n            return jsonify({\"error\": \"Task directory does not exist\"}), 404\n        \n        if not task_path.is_dir():\n            return jsonify({\"error\": \"Path is not a directory\"}), 400\n        \n        # Create ZIP file in memory\n        import zipfile\n        import io\n        from flask import send_file\n        \n        # Create in-memory ZIP file\n        zip_buffer = io.BytesIO()\n        \n        with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:\n            # Collect empty directories and files to include\n            empty_directories = set()\n            files_to_add = []\n            directories_with_files = set()  # Track directories that contain files\n            \n            # Walk through all files in task directory\n            for root, dirs, files in os.walk(task_path):\n                # Calculate relative path for current directory\n                rel_root = Path(root).relative_to(task_path)\n                rel_root_str = str(rel_root)\n                \n                dirs[:] = [d for d in dirs if d not in HIDDEN_WORKSPACE_NAMES and not d.startswith('.')]\n                \n                # Check if directory has any valid files (excluding chat_history.json)\n                valid_files = [f for f in files if f not in HIDDEN_WORKSPACE_NAMES]\n                \n                if not valid_files:\n                    # Directory is empty (or only contains chat_history.json)\n                    if rel_root != Path('.'):\n                        empty_directories.add(rel_root_str)\n                else:\n                    # Directory has files, mark it and its parents\n                    directories_with_files.add(rel_root_str)\n                    for parent in rel_root.parents:\n                        if parent != Path('.'):\n                            directories_with_files.add(str(parent))\n                \n                # Process files\n                for file in files:\n                    # Skip chat_history.json file\n                    if file in HIDDEN_WORKSPACE_NAMES:\n                        continue\n                    \n                    file_path = Path(root) / file\n                    # Calculate relative path from task directory\n                    arcname = file_path.relative_to(task_path)\n                    files_to_add.append((file_path, arcname))\n            \n            # Add empty directories (excluding those that will be created by files)\n            for dir_path in sorted(empty_directories):\n                if dir_path not in directories_with_files:\n                    # Create empty directory entry by adding a path ending with /\n                    zip_file.writestr(dir_path + '/', b'')\n            \n            # Add all files\n            for file_path, arcname in files_to_add:\n                zip_file.write(file_path, arcname)\n        \n        zip_buffer.seek(0)\n        \n        # Generate filename (sanitize task_id for filename)\n        safe_task_id = task_id.replace('/', '_').replace('\\\\', '_').replace('..', '_')\n        zip_filename = f\"{safe_task_id}.zip\"\n        \n        return send_file(\n            zip_buffer,\n            mimetype='application/zip',\n            as_attachment=True,\n            download_name=zip_filename\n        )\n    except Exception as e:\n        import traceback\n        return jsonify({\"error\": f\"Download failed: {str(e)}\\n{traceback.format_exc()}\"}), 500\n\n\n@app.route('/api/files/delete', methods=['POST'])\n@login_required\ndef delete_file():\n    \"\"\"Delete file or directory\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        data = request.json\n        path = data.get('path', '')\n        task_id = data.get('task_id', '')\n        if not path:\n            return jsonify({\"error\": \"Missing path parameter\"}), 400\n        \n        # Normalize path (limited to user workspace directory)\n        try:\n            path_obj = normalize_file_path(path, task_id=task_id if task_id else None, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not path_obj.exists():\n            return jsonify({\"error\": \"File or directory not found\"}), 404\n        \n        if path_obj.is_file():\n            path_obj.unlink()\n            return jsonify({\"success\": True, \"message\": \"File deleted\"})\n        elif path_obj.is_dir():\n            # Recursively delete directory\n            import shutil\n            shutil.rmtree(path_obj)\n            return jsonify({\"success\": True, \"message\": \"Directory deleted\"})\n        else:\n            return jsonify({\"error\": \"Unknown path type\"}), 400\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/chat/history', methods=['GET'])\n@login_required\ndef get_chat_history():\n    \"\"\"Get chat history\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        task_id_input = request.args.get('task_id', '').strip()\n        \n        if not task_id_input:\n            return jsonify({\"error\": \"Missing task_id parameter\"}), 400\n        \n        # Normalize task ID path (limited to user workspace)\n        try:\n            task_path, _ = normalize_task_id(task_id_input, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        chat_history_file = task_path / 'chat_history.json'\n        \n        if not chat_history_file.exists():\n            return jsonify({\"messages\": []})\n        \n        with open(chat_history_file, 'r', encoding='utf-8') as f:\n            data = json.load(f)\n        \n        messages = data.get(\"messages\", [])\n        \n        # Convert old messages with timestamp to sequence numbers and sort by sequence\n        for idx, msg in enumerate(messages):\n            if 'sequence' not in msg:\n                # Old message without sequence, assign based on index\n                msg['sequence'] = idx\n            # Remove timestamp for privacy (if exists)\n            if 'timestamp' in msg:\n                del msg['timestamp']\n        \n        # Sort messages by sequence number\n        messages.sort(key=lambda m: m.get('sequence', 0))\n        \n        return jsonify({\"messages\": messages})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\ndef create_latest_output(chat_history_file: Path):\n    \"\"\"\n    Create latest_output.json in current task folder from chat_history.json\n    Excludes system messages and truncates content to 200 characters\n    \"\"\"\n    try:\n        if not WRITE_LATEST_OUTPUT:\n            return\n        if not chat_history_file.exists():\n            print(f\"[latest_output] chat_history.json not found: {chat_history_file}\")\n            return\n        \n        # Read chat_history.json\n        with open(chat_history_file, 'r', encoding='utf-8') as f:\n            data = json.load(f)\n        \n        messages = data.get(\"messages\", [])\n        print(f\"[latest_output] Processing {len(messages)} messages from {chat_history_file}\")\n        \n        # Filter out system messages and process content\n        filtered_messages = []\n        for msg in messages:\n            # Skip system messages\n            if msg.get('agent') == 'system':\n                continue\n            \n            # Create a copy of the message\n            filtered_msg = msg.copy()\n            \n            # Truncate content field to 200 characters\n            if 'content' in filtered_msg and filtered_msg['content']:\n                content = filtered_msg['content']\n                if len(content) > 200:\n                    filtered_msg['content'] = content[:200] + \"...\"\n            \n            filtered_messages.append(filtered_msg)\n        \n        print(f\"[latest_output] Filtered to {len(filtered_messages)} messages (excluding system)\")\n        \n        # Create latest_output.json in current task folder (same directory as chat_history.json)\n        task_path = chat_history_file.parent\n        latest_output_file = task_path / 'latest_output.json'\n        with open(latest_output_file, 'w', encoding='utf-8') as f:\n            json.dump({\"messages\": filtered_messages}, f, ensure_ascii=False, indent=2)\n        \n        print(f\"[latest_output] Successfully created latest_output.json at {latest_output_file}\")\n    \n    except Exception as e:\n        # Log error but don't interrupt the main save operation\n        print(f\"[latest_output] Error creating latest_output.json: {e}\")\n        import traceback\n        traceback.print_exc()\n\n\n@app.route('/api/chat/save', methods=['POST'])\n@login_required\ndef save_chat_message():\n    \"\"\"Save chat message (use file lock to ensure atomicity)\"\"\"\n    try:\n        data = request.json\n        task_id_input = data.get('task_id', '').strip()\n        message = data.get('message')\n        \n        if not task_id_input or not message:\n            return jsonify({\"error\": \"Missing required parameters\"}), 400\n        \n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        # Normalize task ID path (limited to user workspace)\n        try:\n            task_path, _ = normalize_task_id(task_id_input, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        task_path.mkdir(parents=True, exist_ok=True)\n        chat_history_file = task_path / 'chat_history.json'\n        \n        # Use file lock to ensure atomic operation, prevent data loss from concurrent writes\n        try:\n            # Open file (create if not exists)\n            with open(chat_history_file, 'a+', encoding='utf-8') as f:\n                # Get file lock (blocking mode)\n                fcntl.flock(f.fileno(), fcntl.LOCK_EX)\n                \n                try:\n                    # Reposition to file beginning\n                    f.seek(0)\n                    \n                    # Read existing records\n                    content = f.read()\n                    if content.strip():\n                        try:\n                            data = json.loads(content)\n                            messages = data.get(\"messages\", [])\n                        except json.JSONDecodeError:\n                            # If JSON parsing fails, start from empty list\n                            messages = []\n                    else:\n                        messages = []\n                    \n                    # Convert old messages with timestamp to sequence numbers (for backward compatibility)\n                    # Find max sequence number or calculate from message count\n                    max_seq = -1\n                    for idx, m in enumerate(messages):\n                        # Remove timestamp from all messages for privacy\n                        if 'timestamp' in m:\n                            del m['timestamp']\n                        \n                        if 'sequence' in m:\n                            max_seq = max(max_seq, m['sequence'])\n                        else:\n                            # Old message without sequence, assign sequence based on index\n                            m['sequence'] = idx\n                            max_seq = max(max_seq, idx)\n                    \n                    # Calculate next sequence number\n                    next_sequence = max_seq + 1 if max_seq >= 0 else len(messages)\n                    \n                    # Remove timestamp from new message and add sequence number\n                    message_content = message.get('content', '')[:50] if message.get('content') else ''\n                    if 'timestamp' in message:\n                        del message['timestamp']\n                    message['sequence'] = next_sequence\n                    \n                    # Check if same message already exists (avoid duplicates)\n                    # Judge by sequence and content\n                    is_duplicate = any(\n                        (m.get('sequence') == next_sequence and \n                         (m.get('content', '')[:50] if m.get('content') else '') == message_content) or\n                        # Also check by content only for backward compatibility\n                        ((m.get('content', '')[:50] if m.get('content') else '') == message_content and\n                         m.get('agent') == message.get('agent') and\n                         m.get('type') == message.get('type') and\n                         m.get('isUser') == message.get('isUser'))\n                        for m in messages\n                    )\n                    \n                    if not is_duplicate:\n                        # Add new message\n                        messages.append(message)\n                        \n                        # Sort messages by sequence number before saving\n                        messages.sort(key=lambda m: m.get('sequence', 0))\n                        \n                        # Clear file and write\n                        f.seek(0)\n                        f.truncate(0)\n                        json.dump({\"messages\": messages}, f, ensure_ascii=False, indent=2)\n                        f.flush()  # Ensure immediate write to disk\n                        \n                        # Check if this is a final_output message, create latest_output.json\n                        if message.get('type') == 'final_output':\n                            print(f\"[latest_output] ✅ Detected final_output message - agent: {message.get('agent', 'unknown')}, task: {task_id_input}\")\n                            try:\n                                create_latest_output(chat_history_file)\n                            except Exception as e:\n                                print(f\"[latest_output] ❌ Error creating latest_output.json: {e}\")\n                                import traceback\n                                traceback.print_exc()\n                        else:\n                            # Debug: log message type for troubleshooting\n                            if message.get('type') in ['final_output', 'tool_call', 'start', 'info']:\n                                print(f\"[latest_output] Debug: Message type '{message.get('type')}' from agent '{message.get('agent', 'unknown')}' (not final_output)\")\n                finally:\n                    # Release file lock\n                    fcntl.flock(f.fileno(), fcntl.LOCK_UN)\n        \n        except OSError as e:\n            # If file lock unavailable (Windows), use thread lock as fallback\n            lock_key = f\"chat_lock_{task_id_input}\"\n            if not hasattr(save_chat_message, '_locks'):\n                save_chat_message._locks = {}\n            if lock_key not in save_chat_message._locks:\n                save_chat_message._locks[lock_key] = threading.Lock()\n            \n            with save_chat_message._locks[lock_key]:\n                # Read existing records\n                messages = []\n                if chat_history_file.exists():\n                    try:\n                        with open(chat_history_file, 'r', encoding='utf-8') as f:\n                            data = json.load(f)\n                            messages = data.get(\"messages\", [])\n                    except:\n                        messages = []\n                \n                # Convert old messages with timestamp to sequence numbers (for backward compatibility)\n                # Find max sequence number or calculate from message count\n                max_seq = -1\n                for idx, m in enumerate(messages):\n                    # Remove timestamp from all messages for privacy\n                    if 'timestamp' in m:\n                        del m['timestamp']\n                    \n                    if 'sequence' in m:\n                        max_seq = max(max_seq, m['sequence'])\n                    else:\n                        # Old message without sequence, assign sequence based on index\n                        m['sequence'] = idx\n                        max_seq = max(max_seq, idx)\n                \n                # Calculate next sequence number\n                next_sequence = max_seq + 1 if max_seq >= 0 else len(messages)\n                \n                # Remove timestamp from new message and add sequence number\n                message_content = message.get('content', '')[:50] if message.get('content') else ''\n                if 'timestamp' in message:\n                    del message['timestamp']\n                message['sequence'] = next_sequence\n                \n                # Check if same message already exists (avoid duplicates)\n                # Judge by sequence and content\n                is_duplicate = any(\n                    (m.get('sequence') == next_sequence and \n                     (m.get('content', '')[:50] if m.get('content') else '') == message_content) or\n                    # Also check by content only for backward compatibility\n                    ((m.get('content', '')[:50] if m.get('content') else '') == message_content and\n                     m.get('agent') == message.get('agent') and\n                     m.get('type') == message.get('type') and\n                     m.get('isUser') == message.get('isUser'))\n                    for m in messages\n                )\n                \n                if not is_duplicate:\n                    # Add new message\n                    messages.append(message)\n                    \n                    # Sort messages by sequence number before saving\n                    messages.sort(key=lambda m: m.get('sequence', 0))\n                    \n                    # Save\n                    with open(chat_history_file, 'w', encoding='utf-8') as f:\n                        json.dump({\"messages\": messages}, f, ensure_ascii=False, indent=2)\n                    \n                    # Check if this is a final_output message, create latest_output.json\n                    if message.get('type') == 'final_output':\n                        print(f\"[latest_output] ✅ Detected final_output message - agent: {message.get('agent', 'unknown')}, task: {task_id_input}\")\n                        try:\n                            create_latest_output(chat_history_file)\n                        except Exception as e:\n                            print(f\"[latest_output] ❌ Error creating latest_output.json: {e}\")\n                            import traceback\n                            traceback.print_exc()\n                    else:\n                        # Debug: log message type for troubleshooting\n                        if message.get('type') in ['final_output', 'tool_call', 'start', 'info']:\n                            print(f\"[latest_output] Debug: Message type '{message.get('type')}' from agent '{message.get('agent', 'unknown')}' (not final_output)\")\n        \n        return jsonify({\"success\": True})\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/files/files', methods=['POST'])\n@login_required\ndef upload_file():\n    \"\"\"Upload file\"\"\"\n    try:\n        if 'file' not in request.files:\n            return jsonify({\"error\": \"No file\"}), 400\n        \n        file = request.files['file']\n        if file.filename == '':\n            return jsonify({\"error\": \"Filename is empty\"}), 400\n        \n        # Get target directory\n        target_dir = request.form.get('target_dir', '')\n        if not target_dir:\n            return jsonify({\"error\": \"Missing target directory parameter\"}), 400\n        \n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        # Clean and extract filename\n        # Decode URL-encoded filename if needed\n        import urllib.parse\n        filename = file.filename\n        try:\n            # Try to decode URL encoding (handle special characters)\n            filename = urllib.parse.unquote(filename, encoding='utf-8')\n        except:\n            # If decoding fails, use original filename\n            pass\n        \n        # Ensure filename is safe (remove any path components and normalize)\n        filename = Path(filename).name  # Get only the filename part, remove any path\n        # Normalize filename (remove leading/trailing spaces)\n        filename = filename.strip()\n        \n        if not filename:\n            return jsonify({\"error\": \"Filename is empty after cleaning\"}), 400\n        \n        # Normalize target directory path (limited to user workspace directory)\n        try:\n            target_dir_obj = normalize_file_path(target_dir, username=username)\n        except ValueError as e:\n            error_msg = f\"Invalid target directory: {str(e)}\"\n            if \"pattern\" in str(e).lower():\n                error_msg += f\" (Directory path may contain invalid characters: {target_dir})\"\n            return jsonify({\"error\": error_msg}), 400\n        \n        if not target_dir_obj.exists():\n            return jsonify({\"error\": \"Target directory does not exist\"}), 404\n        \n        if not target_dir_obj.is_dir():\n            return jsonify({\"error\": \"Target path is not a directory\"}), 400\n        \n        # Build target file path\n        target_path = target_dir_obj / filename\n        \n        # Additional security check: ensure final path is still under user workspace\n        user_workspace = get_user_workspace(username)\n        try:\n            target_path.resolve().relative_to(user_workspace.resolve())\n        except ValueError:\n            return jsonify({\"error\": \"File path is unsafe: cannot exceed user workspace directory\"}), 400\n        \n        # Save file with comprehensive error handling\n        try:\n            # Ensure parent directory exists\n            target_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # Save the file\n            file.save(str(target_path))\n        except OSError as os_error:\n            # Handle OS-level errors (permissions, disk full, etc.)\n            error_msg = f\"Failed to save file: {str(os_error)}\"\n            if \"pattern\" in str(os_error).lower() or \"invalid\" in str(os_error).lower():\n                error_msg += f\" (Filename may contain invalid characters: {filename})\"\n            return jsonify({\"error\": error_msg}), 500\n        except Exception as save_error:\n            # Handle other errors\n            import traceback\n            error_msg = f\"Failed to save file: {str(save_error)}\"\n            if \"pattern\" in str(save_error).lower():\n                error_msg += f\" (Filename may contain invalid characters: {filename})\"\n            # Log full traceback for debugging\n            print(f\"Upload error: {traceback.format_exc()}\")\n            return jsonify({\"error\": error_msg}), 500\n        \n        # Get user workspace for relative path calculation\n        # Calculate relative path (for display)\n        try:\n            rel_path = target_path.relative_to(user_workspace)\n            display_path = str(rel_path) if rel_path != Path('.') else ''\n        except ValueError:\n            display_path = str(target_path)\n        \n        return jsonify({\n            \"success\": True,\n            \"message\": \"File uploaded successfully\",\n            \"path\": display_path  # Return relative path (for frontend display)\n        })\n    except Exception as e:\n        import traceback\n        error_msg = str(e)\n        # Check if error contains pattern-related message\n        if \"pattern\" in error_msg.lower():\n            error_msg = f\"Path validation failed: {error_msg}\"\n        print(f\"Upload error: {traceback.format_exc()}\")\n        return jsonify({\"error\": error_msg}), 500\n\n\n@app.route('/api/files/preview', methods=['GET'])\n@login_required\ndef preview_file():\n    \"\"\"Preview file (for images, etc.)\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        path = request.args.get('path', '')\n        if not path:\n            return jsonify({\"error\": \"Missing path parameter\"}), 400\n        \n        # path 已经是相对于用户工作空间的完整路径（包含 task_id）\n        try:\n            path_obj = normalize_file_path(path, task_id=None, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not path_obj.exists():\n            return jsonify({\"error\": f\"File not found: {path_obj}\"}), 404\n        \n        if not path_obj.is_file():\n            return jsonify({\"error\": \"Path is not a file\"}), 400\n        \n        # Use Flask's send_file to send file to client (not as attachment)\n        from flask import send_file\n        \n        # Get filename for content type detection\n        filename = path_obj.name\n        \n        # Determine MIME type\n        import mimetypes\n        mime_type, _ = mimetypes.guess_type(str(path_obj))\n        if not mime_type:\n            mime_type = 'application/octet-stream'\n        \n        return send_file(\n            str(path_obj),\n            mimetype=mime_type\n        )\n    except Exception as e:\n        import traceback\n        error_msg = f\"{str(e)}\\n{traceback.format_exc()}\"\n        return jsonify({\"error\": error_msg}), 500\n\n\n@app.route('/api/files/download', methods=['GET'])\n@login_required\ndef download_file():\n    \"\"\"Download file\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        path = request.args.get('path', '')\n        if not path:\n            return jsonify({\"error\": \"Missing path parameter\"}), 400\n        \n        # path 已经是相对于用户工作空间的完整路径（包含 task_id），不需要再传递 task_id\n        # 直接使用 normalize_file_path，不传递 task_id 参数\n        try:\n            path_obj = normalize_file_path(path, task_id=None, username=username)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not path_obj.exists():\n            return jsonify({\"error\": f\"File not found: {path_obj}\"}), 404\n        \n        if not path_obj.is_file():\n            return jsonify({\"error\": \"Path is not a file\"}), 400\n        \n        # Use Flask's send_file to send file to client\n        from flask import send_file\n        \n        # Get filename for download\n        filename = path_obj.name\n        \n        # Determine MIME type\n        import mimetypes\n        mime_type, _ = mimetypes.guess_type(str(path_obj))\n        if not mime_type:\n            mime_type = 'application/octet-stream'\n        \n        return send_file(\n            str(path_obj),\n            mimetype=mime_type,\n            as_attachment=True,\n            download_name=filename\n        )\n    except Exception as e:\n        import traceback\n        error_msg = str(e)\n        # For security, don't expose full traceback to frontend\n        # Only include first line of error message\n        error_lines = error_msg.split('\\n')\n        safe_error = error_lines[0] if error_lines else \"Unknown error occurred\"\n        print(f\"Download file error: {traceback.format_exc()}\")  # Log full error to server\n        return jsonify({\"error\": safe_error}), 500\n\n\n@app.route('/api/hil/check', methods=['POST'])\n@login_required\ndef check_hil_task():\n    \"\"\"Check if there's a pending HIL task for the current workspace\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        user_execution = get_user_execution(username)\n        pending = user_execution.get('pending_hil')\n        if pending:\n            return jsonify({\n                \"found\": True,\n                \"hil_id\": pending.get(\"hil_id\"),\n                \"instruction\": pending.get(\"instruction\", \"\")\n            })\n        return jsonify({\"found\": False})\n    \n    except Exception as e:\n        import traceback\n        print(f\"Check HIL task error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/hil/respond', methods=['POST'])\n@login_required\ndef respond_hil_task():\n    \"\"\"Respond to a HIL task\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        data = request.json\n        hil_id = data.get('hil_id')\n        response_text = data.get('response', '')\n        \n        if not hil_id:\n            return jsonify({\"error\": \"Missing hil_id parameter\"}), 400\n        user_execution = get_user_execution(username)\n        process = user_execution.get('process')\n        if not process or process.poll() is not None or not process.stdin:\n            return jsonify({\"error\": \"No active task process\"}), 400\n\n        process.stdin.write(json.dumps({\n            \"type\": \"hil_response\",\n            \"hil_id\": hil_id,\n            \"response\": response_text,\n        }, ensure_ascii=False) + \"\\n\")\n        process.stdin.flush()\n        user_execution['pending_hil'] = None\n        return jsonify({\"success\": True, \"message\": \"HIL task responded\"})\n    \n    except Exception as e:\n        import traceback\n        print(f\"Respond to HIL task error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/tool-confirm/respond', methods=['POST'])\n@login_required\ndef respond_tool_confirmation():\n    \"\"\"Respond to a pending direct-tools tool confirmation.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n\n        data = request.json or {}\n        confirm_id = data.get('confirm_id')\n        approved = data.get('approved')\n        if not confirm_id or approved is None:\n            return jsonify({\"error\": \"Missing confirm_id or approved\"}), 400\n\n        user_execution = get_user_execution(username)\n        process = user_execution.get('process')\n        if not process or process.poll() is not None or not process.stdin:\n            return jsonify({\"error\": \"No active task process\"}), 400\n\n        process.stdin.write(json.dumps({\n            \"type\": \"tool_confirmation_response\",\n            \"confirm_id\": confirm_id,\n            \"approved\": bool(approved),\n        }, ensure_ascii=False) + \"\\n\")\n        process.stdin.flush()\n        user_execution['pending_tool_confirmation'] = None\n        return jsonify({\"success\": True, \"message\": \"Tool confirmation responded\"})\n    except Exception as e:\n        import traceback\n        print(f\"Respond tool confirmation error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/tools/list', methods=['GET'])\n@login_required\ndef list_runtime_tools():\n    \"\"\"List runtime tools, custom tool load failures, and YAML binding status.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        with runtime_env_scope(get_user_runtime_overrides(username)):\n            reload_runtime_registry()\n            metadata = get_runtime_registry_metadata()\n            failures = get_runtime_registry_failures()\n        bindings_info = collect_tool_bindings(username)\n        bound_map = bindings_info[\"bindings\"]\n\n        tools = []\n        for tool_name, meta in sorted(metadata.items()):\n            tools.append({\n                \"name\": tool_name,\n                \"source\": meta.get(\"source\", \"builtin\"),\n                \"path\": meta.get(\"path\", \"\"),\n                \"class_name\": meta.get(\"class_name\", \"\"),\n                \"status\": meta.get(\"status\", \"loaded\"),\n                \"error\": meta.get(\"error\", \"\"),\n                \"agent_systems\": sorted(bound_map.get(tool_name, [])),\n                \"bound\": tool_name in bound_map,\n            })\n\n        return jsonify({\n            \"tools\": tools,\n            \"failures\": failures,\n            \"binding_issues\": bindings_info[\"missing_runtime\"],\n        })\n    except Exception as e:\n        import traceback\n        print(f\"List tools error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/tools/reload', methods=['POST'])\n@login_required\ndef reload_runtime_tools():\n    \"\"\"Reload runtime registry after tool changes.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        with runtime_env_scope(get_user_runtime_overrides(username)):\n            reload_runtime_registry()\n        return jsonify({\"success\": True})\n    except Exception as e:\n        import traceback\n        print(f\"Reload tools error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/tools/upload', methods=['POST'])\n@login_required\ndef upload_runtime_tool():\n    \"\"\"Upload a Python tool implementation into ~/mla_v3/tools_library/.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        if 'file' not in request.files:\n            return jsonify({\"error\": \"Missing file field\"}), 400\n        upload = request.files['file']\n        if not upload or not upload.filename:\n            return jsonify({\"error\": \"Missing filename\"}), 400\n        if not upload.filename.endswith('.py'):\n            return jsonify({\"error\": \"Only .py files are supported\"}), 400\n\n        tool_name = sanitize_tool_name(Path(upload.filename).stem)\n        if not tool_name:\n            return jsonify({\"error\": \"Invalid tool filename\"}), 400\n\n        ensure_user_runtime_ready(username)\n        tools_root = get_web_user_tools_library_root(username)\n        tool_dir = tools_root / tool_name\n        tool_dir.mkdir(parents=True, exist_ok=True)\n        target_path = tool_dir / f\"{tool_name}.py\"\n        upload.save(str(target_path))\n\n        with runtime_env_scope(get_user_runtime_overrides(username)):\n            reload_runtime_registry()\n        return jsonify({\n            \"success\": True,\n            \"tool_name\": tool_name,\n            \"path\": str(target_path),\n            \"message\": \"Tool uploaded\"\n        })\n    except Exception as e:\n        import traceback\n        print(f\"Upload tool error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/tools/<tool_name>', methods=['DELETE'])\n@login_required\ndef delete_runtime_tool(tool_name):\n    \"\"\"Delete a custom Python tool from ~/mla_v3/tools_library/.\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        safe_name = sanitize_tool_name(tool_name)\n        if not safe_name:\n            return jsonify({\"error\": \"Invalid tool name\"}), 400\n\n        tool_dir = get_web_user_tools_library_root(username) / safe_name\n        if not tool_dir.exists():\n            return jsonify({\"error\": \"Tool not found\"}), 404\n\n        if tool_dir.is_file():\n            tool_dir.unlink()\n        else:\n            import shutil\n            shutil.rmtree(tool_dir)\n\n        with runtime_env_scope(get_user_runtime_overrides(username)):\n            reload_runtime_registry()\n        return jsonify({\"success\": True, \"message\": \"Tool deleted\"})\n    except Exception as e:\n        import traceback\n        print(f\"Delete tool error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/list', methods=['GET'])\n@login_required\ndef list_config_files():\n    \"\"\"List available configuration files\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        # Get config type from query parameter (run_env or agent)\n        config_type = request.args.get('type', 'run_env')\n        \n        agent_system = request.args.get('agent_system', 'Researcher')\n        \n        try:\n            config_dir = get_config_dir_for_type(username, config_type, agent_system)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        config_dir.mkdir(parents=True, exist_ok=True)\n        if not config_dir.exists():\n            return jsonify({\"error\": f\"Config directory not found: {agent_system}\"}), 404\n        \n        config_files = []\n        patterns = [\"*.yaml\"]\n        if config_type == 'run_env':\n            patterns.append(\"app_config.json\")\n\n        seen = set()\n        for pattern in patterns:\n            iterator = config_dir.glob(pattern)\n            for file_path in iterator:\n                if not file_path.is_file():\n                    continue\n                if file_path.name in seen:\n                    continue\n                seen.add(file_path.name)\n                config_files.append({\n                    \"name\": file_path.name,\n                    \"path\": str(file_path)\n                })\n        \n        # Sort by filename\n        config_files.sort(key=lambda x: x['name'])\n        \n        return jsonify({\"files\": config_files})\n    except Exception as e:\n        import traceback\n        print(f\"List config files error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/read', methods=['GET'])\n@login_required\ndef read_config_file():\n    \"\"\"Read configuration file content\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        filename = request.args.get('file', '')\n        config_type = request.args.get('type', 'run_env')\n        agent_system = request.args.get('agent_system', 'Researcher')\n        \n        try:\n            validate_config_filename(filename, config_type)\n            config_dir = get_config_dir_for_type(username, config_type, agent_system)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        config_dir.mkdir(parents=True, exist_ok=True)\n        try:\n            config_path = ensure_config_path(config_dir, filename)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        if not config_path.exists():\n            return jsonify({\"error\": \"File not found\"}), 404\n        \n        # Check if it's a file or a valid symlink to a file\n        if not config_path.is_file() and not (config_path.is_symlink() and config_path.resolve().is_file()):\n            return jsonify({\"error\": \"Path is not a file\"}), 400\n        \n        # Read file content\n        try:\n            content = config_path.read_text(encoding='utf-8')\n        except Exception as e:\n            return jsonify({\"error\": f\"Failed to read file: {str(e)}\"}), 500\n        \n        return jsonify({\n            \"content\": content,\n            \"filename\": filename\n        })\n    except Exception as e:\n        import traceback\n        print(f\"Read config file error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/agent-tree', methods=['GET'])\n@login_required\ndef get_agent_tree():\n    \"\"\"Get agent hierarchy tree structure\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        ensure_user_runtime_ready(username)\n        \n        # Get optional root_agent and agent_system parameters\n        root_agent = request.args.get('root_agent', None)\n        agent_system = request.args.get('agent_system', 'Researcher')\n        \n        # Load agent configurations\n        from utils.config_loader import ConfigLoader\n        config_loader = ConfigLoader(agent_system, agent_library_root=str(get_web_user_data_root(username)))\n        \n        # Build agent tree\n        all_agents = {}\n        \n        # First pass: collect all agents\n        for name, config in config_loader.all_tools.items():\n            if config.get(\"type\") == \"llm_call_agent\":\n                level = config.get(\"level\", 0)\n                available_tools = config.get(\"available_tools\", [])\n                description = config.get(\"description\", \"\")\n                \n                all_agents[name] = {\n                    \"name\": name,\n                    \"level\": level,\n                    \"description\": description,\n                    \"available_tools\": available_tools,\n                    \"children\": []  # Will be populated in second pass\n                }\n        \n        # Second pass: build tree structure\n        # Find child agents (agents that are in available_tools)\n        for name, agent in all_agents.items():\n            for tool in agent[\"available_tools\"]:\n                if tool in all_agents:\n                    agent[\"children\"].append(tool)\n        \n        # Build tree starting from root agents\n        def build_tree_node(agent_name, visited=None):\n            if visited is None:\n                visited = set()\n            \n            if agent_name in visited:\n                return None  # Circular reference\n            \n            if agent_name not in all_agents:\n                return None\n            \n            visited.add(agent_name)\n            agent = all_agents[agent_name]\n            \n            node = {\n                \"name\": agent[\"name\"],\n                \"level\": agent[\"level\"],\n                \"description\": agent[\"description\"],\n                \"children\": []\n            }\n            \n            # Add child agents\n            for child_name in agent[\"children\"]:\n                child_node = build_tree_node(child_name, visited.copy())\n                if child_node:\n                    node[\"children\"].append(child_node)\n            \n            return node\n        \n        # If root_agent is specified, build tree from that agent\n        if root_agent:\n            if root_agent not in all_agents:\n                return jsonify({\"error\": f\"Agent '{root_agent}' not found\"}), 404\n            \n            tree = build_tree_node(root_agent)\n            if tree:\n                return jsonify({\n                    \"trees\": [tree],\n                    \"root_agent\": root_agent,\n                    \"all_agents\": {name: {\n                        \"level\": agent[\"level\"],\n                        \"description\": agent[\"description\"]\n                    } for name, agent in all_agents.items()}\n                })\n            else:\n                return jsonify({\"error\": \"Failed to build tree\"}), 500\n        \n        # Otherwise, find root agents (agents that are not children of any other agent)\n        root_agents = []\n        all_children = set()\n        for agent in all_agents.values():\n            all_children.update(agent[\"children\"])\n        \n        for name in all_agents.keys():\n            if name not in all_children:\n                root_agents.append(name)\n        \n        # If no root agents found, use highest level agents\n        if not root_agents:\n            max_level = max([agent[\"level\"] for agent in all_agents.values()], default=0)\n            for name, agent in all_agents.items():\n                if agent[\"level\"] == max_level:\n                    root_agents.append(name)\n        \n        # Build trees for all root agents\n        trees = []\n        for root_name in root_agents:\n            tree = build_tree_node(root_name)\n            if tree:\n                trees.append(tree)\n        \n        # If no root agents found, build from all agents\n        if not trees:\n            for name in all_agents.keys():\n                tree = build_tree_node(name)\n                if tree:\n                    trees.append(tree)\n        \n        return jsonify({\n            \"trees\": trees,\n            \"all_agents\": {name: {\n                \"level\": agent[\"level\"],\n                \"description\": agent[\"description\"]\n            } for name, agent in all_agents.items()}\n        })\n    except Exception as e:\n        import traceback\n        print(f\"Get agent tree error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/save', methods=['POST'])\n@login_required\ndef save_config_file():\n    \"\"\"Save configuration file content\"\"\"\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n        \n        data = request.json\n        filename = data.get('file', '')\n        content = data.get('content', '')\n        config_type = data.get('type', 'run_env')\n        agent_system = data.get('agent_system', 'Researcher')\n        \n        try:\n            validate_config_filename(filename, config_type)\n            config_dir = get_config_dir_for_type(username, config_type, agent_system)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n        \n        config_dir.mkdir(parents=True, exist_ok=True)\n        try:\n            config_path = ensure_config_path(config_dir, filename)\n        except ValueError as e:\n            return jsonify({\"error\": str(e)}), 400\n\n        try:\n            parse_config_text(filename, content)\n        except yaml.YAMLError as e:\n            return jsonify({\"error\": f\"Invalid YAML syntax: {str(e)}\"}), 400\n        except json.JSONDecodeError as e:\n            return jsonify({\"error\": f\"Invalid JSON syntax: {str(e)}\"}), 400\n        \n        # Save file\n        try:\n            config_path.write_text(content, encoding='utf-8')\n        except Exception as e:\n            return jsonify({\"error\": f\"Failed to save file: {str(e)}\"}), 500\n        \n        return jsonify({\"success\": True, \"message\": f\"Configuration saved successfully\"})\n    except Exception as e:\n        import traceback\n        print(f\"Save config file error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/guided', methods=['GET'])\n@login_required\ndef get_guided_config():\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n\n        ensure_user_runtime_ready(username)\n        llm_path = get_web_user_llm_config_path(username)\n        app_path = get_web_user_app_config_path(username)\n\n        llm_payload = yaml.safe_load(llm_path.read_text(encoding='utf-8')) or {}\n        app_payload = json.loads(app_path.read_text(encoding='utf-8') or \"{}\")\n\n        return jsonify({\n            \"llm_config\": llm_payload,\n            \"app_config\": app_payload,\n            \"llm_filename\": llm_path.name,\n            \"app_filename\": app_path.name,\n        })\n    except Exception as e:\n        import traceback\n        print(f\"Get guided config error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\n@app.route('/api/config/guided', methods=['POST'])\n@login_required\ndef save_guided_config():\n    try:\n        username = session.get('username')\n        if not username:\n            return jsonify({\"error\": \"User not authenticated\"}), 401\n\n        ensure_user_runtime_ready(username)\n        payload = request.json or {}\n        llm_config = payload.get('llm_config')\n        app_config = payload.get('app_config')\n\n        if not isinstance(llm_config, dict):\n            return jsonify({\"error\": \"llm_config must be an object\"}), 400\n        if not isinstance(app_config, dict):\n            return jsonify({\"error\": \"app_config must be an object\"}), 400\n\n        llm_text = dump_config_text('llm_config.yaml', llm_config)\n        app_text = dump_config_text('app_config.json', app_config)\n\n        get_web_user_llm_config_path(username).write_text(llm_text, encoding='utf-8')\n        get_web_user_app_config_path(username).write_text(app_text, encoding='utf-8')\n\n        return jsonify({\n            \"success\": True,\n            \"message\": \"Guided configuration saved successfully\",\n        })\n    except Exception as e:\n        import traceback\n        print(f\"Save guided config error: {traceback.format_exc()}\")\n        return jsonify({\"error\": str(e)}), 500\n\n\nif __name__ == '__main__':\n    # Default to use port 4242 (5000 may be occupied by macOS AirPlay)\n    port = int(os.environ.get('PORT', 4242))\n    print(f\"🌐 Web UI server started at http://localhost:{port}\")\n    print(f\"📂 Project root: {project_root}\")\n    print(f\"💡 Tip: If port is occupied, specify another port via environment variable PORT=8080\")\n    app.run(host='0.0.0.0', port=port, debug=True, threaded=True)\n"
  },
  {
    "path": "web_ui/server/songmiao/test/chat_history.json",
    "content": "{\n  \"messages\": [\n    {\n      \"agent\": \"system\",\n      \"type\": \"info\",\n      \"content\": \"New task created: test\",\n      \"isUser\": false,\n      \"sequence\": 0\n    },\n    {\n      \"agent\": \"user\",\n      \"type\": \"user\",\n      \"content\": \"你好\",\n      \"isUser\": true,\n      \"sequence\": 1\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"start\",\n      \"content\": \"🚀 任务开始: 你好\",\n      \"isUser\": false,\n      \"sequence\": 2\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"error\",\n      \"content\": \"⏹️ 任务已停止\",\n      \"isUser\": false,\n      \"sequence\": 3\n    }\n  ]\n}"
  },
  {
    "path": "web_ui/server/songmiao/test1/chat_history.json",
    "content": "{\n  \"messages\": [\n    {\n      \"agent\": \"system\",\n      \"type\": \"info\",\n      \"content\": \"New task created: test1\",\n      \"isUser\": false,\n      \"sequence\": 0\n    },\n    {\n      \"agent\": \"system\",\n      \"type\": \"info\",\n      \"content\": \"Entered existing task: test1\",\n      \"isUser\": false,\n      \"sequence\": 1\n    },\n    {\n      \"agent\": \"user\",\n      \"type\": \"user\",\n      \"content\": \"你好\",\n      \"isUser\": true,\n      \"sequence\": 2\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"start\",\n      \"content\": \"🚀 任务开始: 你好\",\n      \"isUser\": false,\n      \"sequence\": 3\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"info\",\n      \"content\": \"[alpha_agent] 初始规划: [🤖 初始规划]\\n\\n<todo_list>\\n1. 响应用户的问候并确认其具体需求：[ongoing]\\n2. 根据用户后续反馈编排任务流（如调研、写作或实验）：[waiting]\\n3. 按照编排的流程调用相应的子智能体（data_collection_agent 等）：[waiting]\\n4. 汇总产出并使用 judge_agent 进行质量检查：[waiting]\\n5. 使用 final_output 输出最终成果：[waiting]\\n</todo_list>\\n\\n<有效文件描述>\\n(暂无有效文件，等待任务启动)\\n</有效文件描述>\\n\\n<固化信息>\\nworkspace:\\n    [dir] . (根目录)\\nrules:\\n    1. 身份定位：alpha_agent，通用 AI 助手。\\n    2. 交互原则：高效、无废话、增量式工作。\\n    3. 参考文献管理：所有互联网信息必须维护在 reference.bib 中，包含总结和本地关联文件路径。\\n    4. 输出规范：复杂任务必须经过 judge_agent 审核，最终通过 final_output 提交。\\ncontent_need_next_steps:\\n    - 用户当前输入为简单的问候“你好”，需要通过 human_in_loop 引导用户提供具体任务指令。\\n</固化信息>\\n\\n<next_n_steps>\\n1. 使用 human_in_loop 工具向用户问好，并询问其具体需要完成的任务（如论文撰写、科学研究或数据分析等）。\\n2. 接收用户反馈后，使用 dir_list 检查当前工作空间状态。\\n3. 根据用户需求，分析是否需要创建 reference.bib 文件。\\n4. 详细分析用户意图，拆解任务步骤并更新 todo_list。\\n5. 根据拆解结果，调用第一个对应的子智能体（如 data_collection_agent）开始增量工作。\\n</next_n_steps>\",\n      \"isUser\": false,\n      \"sequence\": 4\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"tool_call\",\n      \"content\": \"🔧 [alpha_agent] calls tool: human_in_loop\\n\\n📋 Parameters:\\n\\n  \\\"instruction\\\": \\\"你好！我是 alpha_agent，你的 AI 助手。请问今天有什么我可以帮你的吗？你可以告诉我你想要进行的科研课题、论文写作需求、数据分析任务或者任何其他需要我协助的工作。\\\",\\n  \\\"hil_id\\\": \\\"greeting_and_task_inquiry_20251230\\\"\\n\",\n      \"isUser\": false,\n      \"sequence\": 5\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"error\",\n      \"content\": \"⏹️ 任务已停止\",\n      \"isUser\": false,\n      \"sequence\": 6\n    },\n    {\n      \"agent\": \"user\",\n      \"type\": \"user\",\n      \"content\": \"我刚刚问你什么了\",\n      \"isUser\": true,\n      \"sequence\": 7\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"start\",\n      \"content\": \"🚀 任务开始: 我刚刚问你什么了\",\n      \"isUser\": false,\n      \"sequence\": 8\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"info\",\n      \"content\": \"[alpha_agent] 初始规划: [🤖 初始规划]\\n\\n<todo_list>\\n1. 检索并分析历史交互记录，确认用户上一个问题的内容：[ongoing]\\n2. 整理用户上一个问题的具体信息（时间、内容、上下文）：[waiting]\\n3. 使用 final_output 工具向用户反馈其上一个问题的内容：[waiting]\\n</todo_list>\\n\\n<有效文件描述>\\n(暂无有效文件，当前任务为基于历史记录的查询)\\n</有效文件描述>\\n\\n<固化信息>\\nworkspace:\\n    [dir] . (根目录)\\nrules:\\n    1. 身份定位：alpha_agent，通用 AI 助手。\\n    2. 交互原则：高效、无废话、增量式工作。\\n    3. 历史溯源：根据<用户-智能体历史交互>，用户在 2025-12-30T17:46:57 曾发送过“你好”。\\ncontent_need_next_steps:\\n    - 历史记录显示用户上一个输入是“你好”。\\n    - 当前任务是回答用户“我刚刚问你什么了”。\\n</固化信息>\\n\\n<next_n_steps>\\n1. 分析<用户-智能体历史交互>标签中的数据，提取最近一次用户输入的指令内容。\\n2. 确认最近一次指令为“你好”，时间为 2025-12-30T17:46:57。\\n3. 使用 final_output 工具直接回答用户：“你刚才问我的是‘你好’。”，并结束本次任务。\\n</next_n_steps>\",\n      \"isUser\": false,\n      \"sequence\": 9\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"tool_call\",\n      \"content\": \"🔧 [alpha_agent] calls tool: final_output\\n\\n📋 Parameters:\\n\\n  \\\"output\\\": \\\"你刚才问我的是“你好”。(发送时间：2025-12-30 17:46:57)\\\",\\n  \\\"task_id\\\": \\\"alpha_agent_d1c64cf98e15\\\",\\n  \\\"status\\\": \\\"success\\\"\\n\",\n      \"isUser\": false,\n      \"sequence\": 10\n    },\n    {\n      \"agent\": \"alpha_agent\",\n      \"type\": \"info\",\n      \"content\": \"✅ 执行结果: 你刚才问我的是“你好”。(发送时间：2025-12-30 17:46:57)\",\n      \"isUser\": false,\n      \"sequence\": 11\n    }\n  ]\n}"
  },
  {
    "path": "web_ui/server/songmiao/test1/reference.bib",
    "content": ""
  },
  {
    "path": "web_ui/server/start.sh",
    "content": "#!/bin/bash\n# 启动 Web UI 服务器（direct-tools 模式）\n\n# 设置 UTF-8 编码（兼容 macOS）\nexport LANG=${LANG:-en_US.UTF-8}\nexport LC_ALL=${LC_ALL:-en_US.UTF-8}\n\n# 获取脚本所在目录（server 目录）\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n# 切换到 server 目录\ncd \"$SCRIPT_DIR\"\n\n# 检查 conda 环境（抑制所有警告和错误信息）\nif ! command -v conda &> /dev/null 2>&1; then\n    printf \"❌ 未找到 conda 命令\\n\"\n    exit 1\nfi\n\n# 抑制 conda 相关的警告和错误\nexport CONDA_AUTO_UPDATE_CONDA=false\nexport PYTHONWARNINGS=\"ignore::FutureWarning\"\nexport CONDARC=/dev/null 2>/dev/null\n\n# 激活 conda 环境（如果存在，抑制所有输出）\nif conda env list 2>/dev/null | grep -q \"paper_agent\"; then\n    # 初始化 conda（抑制所有输出）\n    eval \"$(conda shell.bash hook 2>/dev/null)\" 2>/dev/null\n    if [ -f \"$(conda info --base 2>/dev/null)/etc/profile.d/conda.sh\" ]; then\n        source \"$(conda info --base 2>/dev/null)/etc/profile.d/conda.sh\" 2>/dev/null\n    fi\n    # 激活环境（抑制所有输出）\n    conda activate paper_agent 2>/dev/null || true\nfi\n\n# 检查端口是否被占用\nWEB_PORT=${PORT:-22228}\n\nif lsof -ti:$WEB_PORT &> /dev/null; then\n    printf \"⚠️  Web UI 端口 %s 已被占用\\n\" \"$WEB_PORT\"\n    printf \"💡 使用以下命令停止现有服务器：\\n\"\n    printf \"   ./stop.sh\\n\"\n    exit 1\nfi\n\nPROJECT_ROOT=\"$( cd \"$SCRIPT_DIR/../..\" && pwd )\"\n\n# 询问用户 workspace 路径\nprintf \"\\n\"\nprintf \"📂 设置工作空间路径（Workspace Root）\\n\"\nprintf \"   💡 直接回车将使用当前目录作为工作空间（与 CLI 模式相同）\\n\"\nprintf \"   💡 输入绝对路径可指定自定义工作空间\\n\"\nread -p \"   请输入工作空间路径 (回车使用当前目录): \" workspace_input\n\n# 处理用户输入\nif [ -z \"$workspace_input\" ]; then\n    # 用户直接回车，使用当前工作目录（和 CLI 模式一样）\n    WORKSPACE_ROOT=$(pwd)\n    printf \"   ✅ 使用当前目录作为工作空间: %s\\n\" \"$WORKSPACE_ROOT\"\nelse\n    # 用户输入了路径\n    workspace_input=$(printf \"%s\" \"$workspace_input\" | xargs)  # 去除首尾空格\n    if [ -z \"$workspace_input\" ]; then\n        # 输入全是空格，当作回车处理\n        WORKSPACE_ROOT=$(pwd)\n        printf \"   ✅ 使用当前目录作为工作空间: %s\\n\" \"$WORKSPACE_ROOT\"\n    else\n        # 检查路径是否存在或是有效路径\n        if [ -d \"$workspace_input\" ] || mkdir -p \"$workspace_input\" 2>/dev/null; then\n            # 转换为绝对路径\n            WORKSPACE_ROOT=$(cd \"$workspace_input\" 2>/dev/null && pwd || printf \"%s\" \"$workspace_input\")\n            printf \"   ✅ 使用指定工作空间: %s\\n\" \"$WORKSPACE_ROOT\"\n        else\n            # 路径无效，使用当前目录\n            WORKSPACE_ROOT=$(pwd)\n            printf \"   ⚠️  输入路径无效，使用当前目录作为工作空间: %s\\n\" \"$WORKSPACE_ROOT\"\n        fi\n    fi\nfi\n\n# 启动 Web UI 服务器\nprintf \"\\n\"\nprintf \"🚀 启动 Web UI 服务器...\\n\"\nprintf \"📂 服务器工作目录: %s\\n\" \"$SCRIPT_DIR\"\nprintf \"📂 用户工作空间: %s\\n\" \"$WORKSPACE_ROOT\"\nprintf \"🌐 Web UI 地址: http://localhost:%s\\n\" \"$WEB_PORT\"\nprintf \"\\n\"\nprintf \"💡 提示: 使用 Ctrl+C 停止服务器，或运行 ./stop.sh\\n\"\nprintf \"\\n\"\n\nWORKSPACE_ROOT=\"$WORKSPACE_ROOT\" PORT=$WEB_PORT python server.py\n\n"
  },
  {
    "path": "web_ui/server/stop.sh",
    "content": "#!/bin/bash\n# 停止 Web UI 服务器\n\n# 设置 UTF-8 编码（兼容 macOS）\nexport LANG=${LANG:-en_US.UTF-8}\nexport LC_ALL=${LC_ALL:-en_US.UTF-8}\n\n# 默认端口\nWEB_PORT=${PORT:-22228}\n\nprintf \"🛑 正在停止服务器...\\n\"\n\n# 停止 Web UI 服务器\nWEB_PIDS=$(lsof -ti:$WEB_PORT 2>/dev/null)\nif [ -z \"$WEB_PIDS\" ]; then\n    printf \"   ℹ️  Web UI 服务器未运行（端口 %s）\\n\" \"$WEB_PORT\"\nelse\n    printf \"   🛑 停止 Web UI 服务器（端口 %s）...\\n\" \"$WEB_PORT\"\n    for PID in $WEB_PIDS; do\n        kill -9 $PID 2>/dev/null\n        if [ $? -eq 0 ]; then\n            printf \"      ✅ 已终止进程 %s\\n\" \"$PID\"\n        else\n            printf \"      ⚠️  无法终止进程 %s\\n\" \"$PID\"\n        fi\n    done\nfi\n\n# 等待一下，然后检查\nsleep 1\n\nREMAINING_WEB=$(lsof -ti:$WEB_PORT 2>/dev/null)\n\nif [ -z \"$REMAINING_WEB\" ]; then\n    printf \"✅ 所有服务器已成功停止\\n\"\nelse\n    printf \"⚠️  Web UI 服务器仍在运行: %s\\n\" \"$REMAINING_WEB\"\nfi\n\n"
  },
  {
    "path": "web_ui/server/user_accounts.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nWeb UI user account storage and authentication helpers.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport base64\nimport hashlib\nimport hmac\nimport os\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import Any, Dict, List\n\nimport yaml\n\n\nUSERS_FILE = Path(\n    os.environ.get(\"WEB_UI_USERS_FILE\", str(Path(__file__).resolve().parent / \"users.yaml\"))\n).expanduser().resolve()\nPBKDF2_ITERATIONS = 120_000\n\n\ndef _now_iso() -> str:\n    return datetime.utcnow().replace(microsecond=0).isoformat() + \"Z\"\n\n\ndef _validate_username(username: str) -> str:\n    value = str(username or \"\").strip()\n    if not value:\n        raise ValueError(\"Username is required\")\n    if len(value) < 3:\n        raise ValueError(\"Username must be at least 3 characters\")\n    if len(value) > 32:\n        raise ValueError(\"Username must be at most 32 characters\")\n    allowed = set(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-\")\n    if any(ch not in allowed for ch in value):\n        raise ValueError(\"Username may only contain letters, numbers, dot, underscore, and hyphen\")\n    return value\n\n\ndef _validate_password(password: str) -> str:\n    value = str(password or \"\")\n    if len(value) < 6:\n        raise ValueError(\"Password must be at least 6 characters\")\n    if len(value) > 256:\n        raise ValueError(\"Password is too long\")\n    return value\n\n\ndef hash_password(password: str) -> str:\n    password = _validate_password(password)\n    salt = os.urandom(16)\n    digest = hashlib.pbkdf2_hmac(\"sha256\", password.encode(\"utf-8\"), salt, PBKDF2_ITERATIONS)\n    return f\"pbkdf2_sha256${PBKDF2_ITERATIONS}${base64.b64encode(salt).decode()}${base64.b64encode(digest).decode()}\"\n\n\ndef verify_password(password: str, stored_hash: str) -> bool:\n    try:\n        scheme, iterations_text, salt_b64, digest_b64 = str(stored_hash or \"\").split(\"$\", 3)\n        if scheme != \"pbkdf2_sha256\":\n            return False\n        iterations = int(iterations_text)\n        salt = base64.b64decode(salt_b64.encode())\n        expected = base64.b64decode(digest_b64.encode())\n        actual = hashlib.pbkdf2_hmac(\"sha256\", str(password or \"\").encode(\"utf-8\"), salt, iterations)\n        return hmac.compare_digest(actual, expected)\n    except Exception:\n        return False\n\n\ndef _normalize_record(username: str, raw: Any, *, default_role: str = \"user\") -> Dict[str, Any]:\n    now = _now_iso()\n    if isinstance(raw, str):\n        return {\n            \"username\": username,\n            \"password_hash\": \"\",\n            \"legacy_password\": raw,\n            \"role\": default_role,\n            \"enabled\": True,\n            \"created_at\": now,\n            \"updated_at\": now,\n        }\n    if not isinstance(raw, dict):\n        raise ValueError(f\"Invalid record for user {username}\")\n    return {\n        \"username\": username,\n        \"password_hash\": str(raw.get(\"password_hash\") or \"\"),\n        \"legacy_password\": str(raw.get(\"legacy_password\") or \"\"),\n        \"role\": str(raw.get(\"role\") or default_role),\n        \"enabled\": bool(raw.get(\"enabled\", True)),\n        \"created_at\": str(raw.get(\"created_at\") or now),\n        \"updated_at\": str(raw.get(\"updated_at\") or now),\n    }\n\n\ndef load_user_records() -> Dict[str, Dict[str, Any]]:\n    if not USERS_FILE.exists():\n        return {}\n    try:\n        payload = yaml.safe_load(USERS_FILE.read_text(encoding=\"utf-8\")) or {}\n    except Exception:\n        return {}\n    raw_users = payload.get(\"users\", {}) if isinstance(payload, dict) else {}\n    if not isinstance(raw_users, dict):\n        return {}\n\n    records: Dict[str, Dict[str, Any]] = {}\n    provisional_admin: str | None = None\n    for idx, (username, raw) in enumerate(raw_users.items()):\n        safe_username = _validate_username(username)\n        default_role = \"admin\" if idx == 0 else \"user\"\n        record = _normalize_record(safe_username, raw, default_role=default_role)\n        if provisional_admin is None and record.get(\"role\") == \"admin\":\n            provisional_admin = safe_username\n        records[safe_username] = record\n\n    if records and provisional_admin is None:\n        first_username = next(iter(records.keys()))\n        records[first_username][\"role\"] = \"admin\"\n\n    return records\n\n\ndef save_user_records(records: Dict[str, Dict[str, Any]]) -> None:\n    ordered = {}\n    for username in sorted(records.keys(), key=lambda item: item.lower()):\n        record = records[username]\n        ordered[username] = {\n            \"password_hash\": str(record.get(\"password_hash\") or \"\"),\n            \"role\": str(record.get(\"role\") or \"user\"),\n            \"enabled\": bool(record.get(\"enabled\", True)),\n            \"created_at\": str(record.get(\"created_at\") or _now_iso()),\n            \"updated_at\": str(record.get(\"updated_at\") or _now_iso()),\n        }\n    USERS_FILE.write_text(\n        yaml.safe_dump({\"users\": ordered}, allow_unicode=True, sort_keys=False),\n        encoding=\"utf-8\",\n    )\n\n\ndef ensure_default_accounts() -> Dict[str, Dict[str, Any]]:\n    records = load_user_records()\n    if not records:\n        records = {\n            \"admin\": {\n                \"username\": \"admin\",\n                \"password_hash\": hash_password(\"admin123\"),\n                \"legacy_password\": \"\",\n                \"role\": \"admin\",\n                \"enabled\": True,\n                \"created_at\": _now_iso(),\n                \"updated_at\": _now_iso(),\n            }\n        }\n        save_user_records(records)\n        return records\n\n    changed = False\n    admin_count = 0\n    for username, record in records.items():\n        if record.get(\"legacy_password\"):\n            record[\"password_hash\"] = hash_password(record[\"legacy_password\"])\n            record[\"legacy_password\"] = \"\"\n            record[\"updated_at\"] = _now_iso()\n            changed = True\n        if record.get(\"role\") == \"admin\" and record.get(\"enabled\", True):\n            admin_count += 1\n\n    if records and admin_count == 0:\n        first_username = next(iter(records.keys()))\n        records[first_username][\"role\"] = \"admin\"\n        records[first_username][\"updated_at\"] = _now_iso()\n        changed = True\n\n    if changed:\n        save_user_records(records)\n    return records\n\n\ndef authenticate_user(username: str, password: str) -> Dict[str, Any] | None:\n    records = ensure_default_accounts()\n    safe_username = _validate_username(username)\n    record = records.get(safe_username)\n    if not record or not record.get(\"enabled\", True):\n        return None\n    if verify_password(password, record.get(\"password_hash\", \"\")):\n        return public_user_record(record)\n    return None\n\n\ndef public_user_record(record: Dict[str, Any]) -> Dict[str, Any]:\n    return {\n        \"username\": str(record.get(\"username\") or \"\"),\n        \"role\": str(record.get(\"role\") or \"user\"),\n        \"enabled\": bool(record.get(\"enabled\", True)),\n        \"created_at\": str(record.get(\"created_at\") or \"\"),\n        \"updated_at\": str(record.get(\"updated_at\") or \"\"),\n    }\n\n\ndef list_users() -> List[Dict[str, Any]]:\n    records = ensure_default_accounts()\n    return [public_user_record(records[name]) for name in sorted(records.keys(), key=lambda item: item.lower())]\n\n\ndef register_user(username: str, password: str, *, role: str = \"user\") -> Dict[str, Any]:\n    records = ensure_default_accounts()\n    safe_username = _validate_username(username)\n    if safe_username in records:\n        raise ValueError(\"Username already exists\")\n    safe_role = \"admin\" if role == \"admin\" else \"user\"\n    now = _now_iso()\n    records[safe_username] = {\n        \"username\": safe_username,\n        \"password_hash\": hash_password(password),\n        \"legacy_password\": \"\",\n        \"role\": safe_role,\n        \"enabled\": True,\n        \"created_at\": now,\n        \"updated_at\": now,\n    }\n    save_user_records(records)\n    return public_user_record(records[safe_username])\n\n\ndef update_user(username: str, *, password: str | None = None, role: str | None = None, enabled: bool | None = None, actor_username: str | None = None) -> Dict[str, Any]:\n    records = ensure_default_accounts()\n    safe_username = _validate_username(username)\n    if safe_username not in records:\n        raise ValueError(\"User not found\")\n    record = records[safe_username]\n    original_role = record.get(\"role\")\n    original_enabled = bool(record.get(\"enabled\", True))\n\n    if password is not None and password != \"\":\n        record[\"password_hash\"] = hash_password(password)\n\n    if role is not None:\n        record[\"role\"] = \"admin\" if role == \"admin\" else \"user\"\n\n    if enabled is not None:\n        record[\"enabled\"] = bool(enabled)\n\n    enabled_admins = [\n        item for item in records.values()\n        if item.get(\"role\") == \"admin\" and bool(item.get(\"enabled\", True))\n    ]\n    if original_role == \"admin\" and original_enabled:\n        becomes_non_admin = record.get(\"role\") != \"admin\" or not bool(record.get(\"enabled\", True))\n        if becomes_non_admin and len(enabled_admins) <= 1:\n            raise ValueError(\"Cannot remove or disable the last enabled admin\")\n\n    if actor_username and safe_username == actor_username and not bool(record.get(\"enabled\", True)):\n        raise ValueError(\"You cannot disable your own account\")\n\n    record[\"updated_at\"] = _now_iso()\n    save_user_records(records)\n    return public_user_record(record)\n\n\ndef delete_user(username: str, *, actor_username: str | None = None) -> None:\n    records = ensure_default_accounts()\n    safe_username = _validate_username(username)\n    if safe_username not in records:\n        raise ValueError(\"User not found\")\n    if actor_username and safe_username == actor_username:\n        raise ValueError(\"You cannot delete your own account\")\n\n    record = records[safe_username]\n    enabled_admins = [\n        item for item in records.values()\n        if item.get(\"role\") == \"admin\" and bool(item.get(\"enabled\", True))\n    ]\n    if record.get(\"role\") == \"admin\" and bool(record.get(\"enabled\", True)) and len(enabled_admins) <= 1:\n        raise ValueError(\"Cannot delete the last enabled admin\")\n\n    records.pop(safe_username)\n    save_user_records(records)\n"
  },
  {
    "path": "web_ui/server/user_runtime.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nWeb UI per-user runtime helpers.\n\nAvoids switching global process env inside the Flask server by giving each user an\nexplicit runtime root, config root, agent library, tools library and skills dir.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport re\nimport shutil\nfrom pathlib import Path\nfrom typing import Any\n\nimport yaml\n\nfrom utils.user_paths import get_project_root\n\n\nSERVER_DIR = Path(__file__).resolve().parent\nWEB_UI_USER_DATA_ROOT = Path(\n    os.environ.get(\"WEB_UI_USER_DATA_ROOT\", str(SERVER_DIR / \"user_data\"))\n).expanduser().resolve()\n\n\ndef sanitize_username(username: str) -> str:\n    value = re.sub(r\"[^a-zA-Z0-9_.-]+\", \"_\", str(username or \"\").strip())\n    value = value.strip(\"._-\")\n    return value or \"user\"\n\n\ndef get_web_user_home(username: str) -> Path:\n    return WEB_UI_USER_DATA_ROOT / sanitize_username(username)\n\n\ndef get_web_user_data_root(username: str) -> Path:\n    return get_web_user_home(username) / \"mla_v3\"\n\n\ndef get_web_user_config_dir(username: str) -> Path:\n    return get_web_user_data_root(username) / \"config\"\n\n\ndef get_web_user_llm_config_path(username: str) -> Path:\n    return get_web_user_config_dir(username) / \"llm_config.yaml\"\n\n\ndef get_web_user_app_config_path(username: str) -> Path:\n    return get_web_user_config_dir(username) / \"app_config.json\"\n\n\ndef get_web_user_agent_library_root(username: str) -> Path:\n    return get_web_user_data_root(username) / \"agent_library\"\n\n\ndef get_web_user_tools_library_root(username: str) -> Path:\n    return get_web_user_data_root(username) / \"tools_library\"\n\n\ndef get_web_user_conversations_dir(username: str) -> Path:\n    return get_web_user_data_root(username) / \"conversations\"\n\n\ndef get_web_user_logs_dir(username: str) -> Path:\n    return get_web_user_data_root(username) / \"logs\"\n\n\ndef get_web_user_runtime_dir(username: str) -> Path:\n    return get_web_user_data_root(username) / \"runtime\"\n\n\ndef get_web_user_skills_dir(username: str) -> Path:\n    return get_web_user_home(username) / \"skills\"\n\n\ndef _blank_api_keys(value: Any) -> Any:\n    if isinstance(value, dict):\n        result = {}\n        for k, v in value.items():\n            if str(k).strip().lower() == \"api_key\":\n                result[k] = \"\"\n            else:\n                result[k] = _blank_api_keys(v)\n        return result\n    if isinstance(value, list):\n        return [_blank_api_keys(v) for v in value]\n    return value\n\n\ndef _seed_directory_children(src_root: Path, dest_root: Path) -> None:\n    if not src_root.exists():\n        return\n    dest_root.mkdir(parents=True, exist_ok=True)\n    for entry in src_root.iterdir():\n        if not entry.is_dir() or entry.name.startswith(\".\"):\n            continue\n        dest = dest_root / entry.name\n        if dest.exists():\n            continue\n        shutil.copytree(entry, dest)\n\n\ndef ensure_web_user_runtime(username: str) -> Path:\n    user_home = get_web_user_home(username)\n    user_root = get_web_user_data_root(username)\n    config_dir = get_web_user_config_dir(username)\n    agent_root = get_web_user_agent_library_root(username)\n    tools_root = get_web_user_tools_library_root(username)\n    conversations_dir = get_web_user_conversations_dir(username)\n    logs_dir = get_web_user_logs_dir(username)\n    runtime_dir = get_web_user_runtime_dir(username)\n    skills_dir = get_web_user_skills_dir(username)\n\n    for path in [\n        user_home,\n        user_root,\n        config_dir,\n        agent_root,\n        tools_root,\n        conversations_dir,\n        logs_dir,\n        runtime_dir,\n        runtime_dir / \"task_events\",\n        runtime_dir / \"launched_tasks\",\n        skills_dir,\n    ]:\n        path.mkdir(parents=True, exist_ok=True)\n\n    project_root = get_project_root()\n    _seed_directory_children(project_root / \"config\" / \"agent_library\", agent_root)\n    _seed_directory_children(project_root / \"skills\", skills_dir)\n\n    llm_config_path = get_web_user_llm_config_path(username)\n    if not llm_config_path.exists():\n        example_path = project_root / \"config\" / \"run_env_config\" / \"llm_config.example.yaml\"\n        if example_path.exists():\n            try:\n                parsed = yaml.safe_load(example_path.read_text(encoding=\"utf-8\"))\n                sanitized = _blank_api_keys(parsed)\n                llm_config_path.write_text(\n                    yaml.safe_dump(sanitized, allow_unicode=True, sort_keys=False),\n                    encoding=\"utf-8\",\n                )\n            except Exception:\n                llm_config_path.write_text('base_url: \"\"\\napi_key: \"\"\\nmodels:\\n  - openai/gpt-4o-mini\\n', encoding=\"utf-8\")\n        else:\n            llm_config_path.write_text('base_url: \"\"\\napi_key: \"\"\\nmodels:\\n  - openai/gpt-4o-mini\\n', encoding=\"utf-8\")\n\n    app_config_path = get_web_user_app_config_path(username)\n    if not app_config_path.exists():\n        default_payload = {\n            \"runtime\": {\n                \"action_window_steps\": 30,\n                \"thinking_interval\": 30,\n                \"thinking_enabled\": True,\n                \"thinking_steps\": 30,\n                \"no_tool_retry_limit\": 7,\n                \"visible_skills\": [],\n                \"max_turns\": 100000,\n                \"fresh_enabled\": False,\n                \"fresh_interval_sec\": 0,\n            },\n            \"env\": {\n                \"command_mode\": \"direct\",\n                \"seed_builtin_resources\": True,\n            },\n            \"context\": {\n                \"user_history_compress_threshold_tokens\": 1500,\n                \"user_history_recent_items\": 0,\n                \"structured_call_info_compress_threshold_agents\": 10,\n                \"structured_call_info_compress_threshold_tokens\": 2200,\n            },\n            \"mcp\": {\n                \"servers\": [],\n            },\n        }\n        app_config_path.write_text(\n            json.dumps(default_payload, ensure_ascii=False, indent=2) + \"\\n\",\n            encoding=\"utf-8\",\n        )\n\n    return user_root\n"
  },
  {
    "path": "web_ui/server/users.yaml",
    "content": "users:\n  admin:\n    password_hash: pbkdf2_sha256$120000$IuT1vcU5d2q2ZlGYGw19Pg==$FjWja4SpXCd4NWHyuRkPNNKIUMogs0WVGx1pQkcHY9E=\n    role: admin\n    enabled: true\n    created_at: '2026-03-23T00:00:00Z'\n    updated_at: '2026-03-23T00:00:00Z'\n"
  },
  {
    "path": "web_ui/static/app.js",
    "content": "/**\n * MLA-V3 Web UI - Frontend JavaScript\n * \n * Author: Songmiao Wang\n * MLA System: Chenlin Yu, Songmiao Wang\n */\n\n// Global variables\nlet currentEventSource = null;\nlet isRunning = false;\nlet currentHILTask = null;  // Current HIL task: {hil_id, instruction}\nlet currentToolConfirmation = null;  // Current tool confirmation: {confirm_id, tool_name, arguments}\nlet hilCheckInterval = null;  // Interval for checking HIL tasks\nlet liveAgentStream = null;\nlet liveReasoningStream = null;\nlet liveThinkingStream = null;\nlet pendingThinkingMeta = null;\nlet pendingReasoningMeta = null;\nlet currentUsername = '';\nlet currentUserRole = 'user';\nlet selectedAdminUser = null;\n\n// Message save queue (ensures serial saving to avoid concurrency issues)\nlet saveQueue = [];\nlet isSaving = false;\n\n// Agent avatar mapping (using Font Awesome icons)\nconst agentAvatars = {\n    'alpha_agent': '<i class=\"fas fa-robot\"></i>',\n    'alpha_node': '<i class=\"fas fa-robot\"></i>',  // Legacy support\n    'writing_agent': '<i class=\"fas fa-pen\"></i>',\n    'researcher': '<i class=\"fas fa-dna\"></i>',\n    'data_collection_agent': '<i class=\"fas fa-chart-bar\"></i>',\n    'protein_function_evidence_agent': '<i class=\"fas fa-microscope\"></i>',\n    'get_searchPdf_by_doi_or_title': '<i class=\"fas fa-download\"></i>',\n    'web_search_agent': '<i class=\"fas fa-search\"></i>',\n    'default': '<i class=\"fas fa-robot\"></i>'\n};\n\n/**\n * Replace emoji with Font Awesome icons in text\n * @param {string} text - Text containing emoji\n * @returns {string} - Text with emoji replaced by HTML icon tags\n */\nfunction replaceEmojiWithIcons(text) {\n    if (typeof text !== 'string') return text;\n    \n    return text\n        .replace(/⬇️/g, '<i class=\"fas fa-download\"></i>')\n        .replace(/🗑️/g, '<i class=\"fas fa-trash\"></i>')\n        .replace(/✕/g, '<i class=\"fas fa-times\"></i>')\n        .replace(/✅/g, '<i class=\"fas fa-check-circle\"></i>')\n        .replace(/❌/g, '<i class=\"fas fa-times-circle\"></i>')\n        .replace(/🔧/g, '<i class=\"fas fa-wrench\"></i>')\n        .replace(/📚/g, '<i class=\"fas fa-book\"></i>')\n        .replace(/📋/g, '<i class=\"fas fa-clipboard-list\"></i>')\n        .replace(/🚀/g, '<i class=\"fas fa-rocket\"></i>')\n        .replace(/⏹️/g, '<i class=\"fas fa-stop\"></i>')\n        .replace(/📤/g, '<i class=\"fas fa-upload\"></i>')\n        .replace(/🔄/g, '<i class=\"fas fa-sync-alt\"></i>')\n        .replace(/📁/g, '<i class=\"fas fa-folder\"></i>')\n        .replace(/👋/g, '<i class=\"fas fa-hand-wave\"></i>')\n        .replace(/⚠️/g, '<i class=\"fas fa-exclamation-triangle\"></i>');\n}\n\n// Agent color cache (ensures same agent always gets same color)\nconst agentColors = {};\n\n/**\n * Generate unique color based on agent name\n * Uses hash function to ensure same name always gets same color\n */\nfunction getAgentColor(agentName) {\n    if (agentColors[agentName]) {\n        return agentColors[agentName];\n    }\n    \n    // Simple hash function\n    let hash = 0;\n    for (let i = 0; i < agentName.length; i++) {\n        hash = agentName.charCodeAt(i) + ((hash << 5) - hash);\n    }\n    \n    // Generate HSL color (saturation 70-100%, lightness 50-70% for vibrant and visible colors)\n    const hue = Math.abs(hash) % 360;\n    const saturation = 70 + (Math.abs(hash) % 31); // 70-100%\n    const lightness = 50 + (Math.abs(hash) % 21); // 50-70%\n    \n    // Convert to HSL string\n    const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;\n    \n    // Cache color\n    agentColors[agentName] = color;\n    \n    return color;\n}\n\n// DOM elements\nconst taskIdInput = document.getElementById('task-id');\nconst taskSelect = document.getElementById('task-select');\nconst confirmTaskBtn = document.getElementById('confirm-task-btn');\nconst clearTaskBtn = document.getElementById('clear-task-btn');\nconst resumeTaskBtn = document.getElementById('resume-task-btn');\nconst copyTaskBtn = document.getElementById('copy-task-btn');\nconst downloadTaskBtn = document.getElementById('download-task-btn');\nconst configBtn = document.getElementById('config-btn');\nconst toolsBtn = document.getElementById('tools-btn');\nconst usersBtn = document.getElementById('users-btn');\nconst agentSelectBtn = document.getElementById('agent-select-btn');\nconst agentSelectText = document.getElementById('agent-select-text');\nconst agentSelectModal = document.getElementById('agent-select-modal');\nconst closeAgentSelectBtn = document.getElementById('close-agent-select-btn');\nconst agentSelectList = document.getElementById('agent-select-list');\nconst agentSearchInput = document.getElementById('agent-search-input');\nconst agentTreePanel = document.getElementById('agent-tree-panel');\nconst agentTreePanelContent = document.getElementById('agent-tree-panel-content');\n// Agent system: dynamic, loaded from selector / localStorage\nconst agentSystemSelect = document.getElementById('agent-system-select');\nlet agentSystem = localStorage.getItem('mla_agent_system') || 'Researcher';\n\n// Current selected agent (default: alpha_agent)\nlet selectedAgent = localStorage.getItem('mla_selected_agent') || 'alpha_agent';\nconst userInput = document.getElementById('user-input');\nconst sendBtn = document.getElementById('send-btn');\nconst stopBtn = document.getElementById('stop-btn');\nconst messagesContainer = document.getElementById('messages');\nconst statusText = document.getElementById('status-text');\nconst workspacePath = document.getElementById('workspace-path');\n\n// File browser elements\nconst fileBrowserPath = document.getElementById('file-browser-path');\nconst fileTree = document.getElementById('file-tree');\nconst refreshFilesBtn = document.getElementById('refresh-files-btn');\nconst uploadFileBtn = document.getElementById('upload-file-btn');\nconst fileUploadInput = document.getElementById('file-upload-input');\nconst fileViewer = document.getElementById('file-viewer');\nconst fileViewerTitle = document.getElementById('file-viewer-title');\nconst fileViewerContent = document.getElementById('file-viewer-content');\nconst closeFileBtn = document.getElementById('close-file-btn');\nconst deleteFileBtn = document.getElementById('delete-file-btn');\nconst downloadFileBtn = document.getElementById('download-file-btn');\nconst toolsModal = document.getElementById('tools-modal');\nconst closeToolsBtn = document.getElementById('close-tools-btn');\nconst uploadToolBtn = document.getElementById('upload-tool-btn');\nconst reloadToolsBtn = document.getElementById('reload-tools-btn');\nconst toolUploadInput = document.getElementById('tool-upload-input');\nconst toolsList = document.getElementById('tools-list');\nconst toolsStatus = document.getElementById('tools-status');\nconst usersModal = document.getElementById('users-modal');\nconst closeUsersBtn = document.getElementById('close-users-btn');\nconst reloadUsersBtn = document.getElementById('reload-users-btn');\nconst newUserBtn = document.getElementById('new-user-btn');\nconst saveUserBtn = document.getElementById('save-user-btn');\nconst deleteUserBtn = document.getElementById('delete-user-btn');\nconst usersList = document.getElementById('users-list');\nconst usersStatus = document.getElementById('users-status');\nconst adminUserUsername = document.getElementById('admin-user-username');\nconst adminUserPassword = document.getElementById('admin-user-password');\nconst adminUserRole = document.getElementById('admin-user-role');\nconst adminUserEnabled = document.getElementById('admin-user-enabled');\n\n// Current browsing path (for directory navigation)\nlet currentBrowsePath = '';\nlet currentViewingFile = null; // Currently viewing file path\nlet confirmedTaskId = null;  // Currently confirmed taskid\n\n// Check and stop old task\nasync function checkAndStopOldTask() {\n    try {\n        // Check status first\n        const statusResponse = await fetch('/api/status', {\n            credentials: 'include'\n        });\n        const statusData = await statusResponse.json();\n        \n        // If there's a running task, stop it automatically\n        if (statusData.running) {\n            console.log('Detected running task, stopping automatically...');\n            await fetch('/api/stop', {\n                method: 'POST',\n                headers: {\n                    'Content-Type': 'application/json'\n                },\n                credentials: 'include'\n            });\n        }\n    } catch (error) {\n        // Ignore error (server may not be started, etc.)\n        console.log('Failed to check task status (may be normal):', error);\n    }\n}\n\n// Check login status\nasync function checkAuth() {\n    try {\n        const response = await fetch('/api/check-auth', {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (!data.logged_in) {\n            // Not logged in, redirect to login page\n            window.location.href = '/';\n            return false;\n        }\n        \n        // Display username\n        const usernameDisplay = document.getElementById('username-display');\n        if (usernameDisplay) {\n            currentUsername = data.username || '';\n            currentUserRole = data.role || 'user';\n            usernameDisplay.textContent = `User: ${currentUsername}${currentUserRole === 'admin' ? ' (admin)' : ''}`;\n        }\n        if (usersBtn) {\n            usersBtn.style.display = data.can_manage_users ? 'inline-flex' : 'none';\n        }\n        \n        return true;\n    } catch (error) {\n        console.error('Failed to check login status:', error);\n        return false;\n    }\n}\n\n// Logout\nasync function logout() {\n    try {\n        const response = await fetch('/api/logout', {\n            method: 'POST',\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (data.success) {\n            // Direct redirect without fade-out animation (avoid white screen issue)\n            window.location.replace('/');\n        }\n    } catch (error) {\n        console.error('Logout failed:', error);\n    }\n}\n\nfunction setUsersStatus(text, isError = false) {\n    if (!usersStatus) return;\n    usersStatus.textContent = text || '';\n    usersStatus.style.color = isError ? '#ff6b6b' : '#4ec9b0';\n}\n\nfunction openUsersModal() {\n    if (!usersModal) return;\n    usersModal.style.display = 'flex';\n    resetUserEditor();\n    loadUsers();\n}\n\nfunction closeUsersModal() {\n    if (!usersModal) return;\n    usersModal.style.display = 'none';\n}\n\nfunction resetUserEditor() {\n    selectedAdminUser = null;\n    if (adminUserUsername) {\n        adminUserUsername.value = '';\n        adminUserUsername.disabled = false;\n    }\n    if (adminUserPassword) adminUserPassword.value = '';\n    if (adminUserRole) adminUserRole.value = 'user';\n    if (adminUserEnabled) adminUserEnabled.checked = true;\n    if (deleteUserBtn) deleteUserBtn.disabled = true;\n    setUsersStatus('');\n    document.querySelectorAll('.user-item').forEach(item => item.classList.remove('active'));\n}\n\nfunction fillUserEditor(user) {\n    selectedAdminUser = user || null;\n    if (!user) {\n        resetUserEditor();\n        return;\n    }\n    if (adminUserUsername) {\n        adminUserUsername.value = user.username || '';\n        adminUserUsername.disabled = true;\n    }\n    if (adminUserPassword) adminUserPassword.value = '';\n    if (adminUserRole) adminUserRole.value = user.role || 'user';\n    if (adminUserEnabled) adminUserEnabled.checked = !!user.enabled;\n    if (deleteUserBtn) deleteUserBtn.disabled = user.username === currentUsername;\n}\n\nfunction renderUsersList(users) {\n    if (!usersList) return;\n    if (!Array.isArray(users) || users.length === 0) {\n        usersList.innerHTML = '<div class=\"config-file-empty\">No users found</div>';\n        return;\n    }\n    usersList.innerHTML = users.map(user => `\n        <div class=\"tool-item user-item${selectedAdminUser && selectedAdminUser.username === user.username ? ' active' : ''}\" data-username=\"${escapeHtml(user.username)}\">\n            <div class=\"tool-item-header\">\n                <div class=\"tool-item-name\"><i class=\"fas fa-user\"></i> ${escapeHtml(user.username)}</div>\n                <span class=\"tool-item-status ${user.enabled ? 'bound' : 'error'}\">${user.enabled ? user.role : 'disabled'}</span>\n            </div>\n            <div class=\"tool-item-meta\">\n                <span>Role: ${escapeHtml(user.role || 'user')}</span>\n                <span>Updated: ${escapeHtml(user.updated_at || '')}</span>\n            </div>\n        </div>\n    `).join('');\n    usersList.querySelectorAll('.user-item').forEach(item => {\n        item.addEventListener('click', () => {\n            const username = item.dataset.username;\n            const user = users.find(entry => entry.username === username);\n            fillUserEditor(user);\n            usersList.querySelectorAll('.user-item').forEach(node => node.classList.remove('active'));\n            item.classList.add('active');\n        });\n    });\n}\n\nasync function loadUsers() {\n    if (!usersList) return;\n    setUsersStatus('');\n    try {\n        const response = await fetch('/api/users', {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        if (!response.ok) {\n            throw new Error(data.error || 'Failed to load users');\n        }\n        renderUsersList(data.users || []);\n    } catch (error) {\n        setUsersStatus(error.message, true);\n    }\n}\n\nasync function saveUserRecord() {\n    try {\n        const username = (adminUserUsername?.value || '').trim();\n        const password = (adminUserPassword?.value || '').trim();\n        const role = adminUserRole?.value || 'user';\n        const enabled = !!adminUserEnabled?.checked;\n\n        if (!username) {\n            throw new Error('Username is required');\n        }\n\n        let response;\n        if (selectedAdminUser) {\n            response = await fetch(`/api/users/${encodeURIComponent(selectedAdminUser.username)}`, {\n                method: 'PATCH',\n                headers: { 'Content-Type': 'application/json' },\n                credentials: 'include',\n                body: JSON.stringify({\n                    ...(password ? { password } : {}),\n                    role,\n                    enabled,\n                })\n            });\n        } else {\n            if (!password) {\n                throw new Error('Password is required for a new user');\n            }\n            response = await fetch('/api/users', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application/json' },\n                credentials: 'include',\n                body: JSON.stringify({\n                    username,\n                    password,\n                    role,\n                })\n            });\n        }\n\n        const data = await response.json();\n        if (!response.ok) {\n            throw new Error(data.error || 'Save failed');\n        }\n\n        setUsersStatus(selectedAdminUser ? 'User updated' : 'User created');\n        resetUserEditor();\n        await checkAuth();\n        await loadUsers();\n    } catch (error) {\n        setUsersStatus(error.message, true);\n    }\n}\n\nasync function deleteSelectedUser() {\n    if (!selectedAdminUser) return;\n    if (!confirm(`Delete user \"${selectedAdminUser.username}\"?`)) return;\n    try {\n        const response = await fetch(`/api/users/${encodeURIComponent(selectedAdminUser.username)}`, {\n            method: 'DELETE',\n            credentials: 'include'\n        });\n        const data = await response.json();\n        if (!response.ok) {\n            throw new Error(data.error || 'Delete failed');\n        }\n        setUsersStatus('User deleted');\n        resetUserEditor();\n        await loadUsers();\n    } catch (error) {\n        setUsersStatus(error.message, true);\n    }\n}\n\n// Initialize\ndocument.addEventListener('DOMContentLoaded', async () => {\n    // Check login status\n    const isAuthenticated = await checkAuth();\n    if (!isAuthenticated) {\n        return;  // Not logged in, don't continue initialization\n    }\n    \n    // Logout button event\n    const logoutBtn = document.getElementById('logout-btn');\n    if (logoutBtn) {\n        logoutBtn.addEventListener('click', logout);\n    }\n    \n    // Check and stop any existing old task on page load\n    await checkAndStopOldTask();\n    \n    // Restore task_id from localStorage (restore after refresh)\n    const savedTaskId = localStorage.getItem('mla_task_id');\n    if (savedTaskId) {\n        taskIdInput.value = savedTaskId;\n        confirmedTaskId = savedTaskId;  // Restore confirmed taskid\n    } else {\n        // If no saved taskid, clear input (don't set default value)\n        taskIdInput.value = '';\n    }\n    \n    updateWorkspacePath();\n    \n    // Initialize agent system selector\n    await initAgentSystemSelector();\n    \n    // Initialize agent selection\n    initAgentSelection();\n    \n    // If task_id already has a value，自动加载聊天记录\n    const taskId = taskIdInput.value.trim();\n    if (taskId && savedTaskId) {\n        // Only when there is saved taskid in localStorage\n        console.log('DOMContentLoaded: Detected saved taskId =', taskId, '');\n        // Ensure welcome message is hidden\n        const welcomeMsg = messagesContainer.querySelector('.welcome-message');\n        if (welcomeMsg) {\n            welcomeMsg.style.display = 'none';\n        }\n        // Delay to ensure other initialization completes\n        setTimeout(async () => {\n            console.log('DOMContentLoaded: Start loading chat history');\n            await loadChatHistory(taskId);\n            // After loading history, if there is history\n            // If no history, welcome message should be kept\n            const welcomeMsgAfter = messagesContainer.querySelector('.welcome-message');\n            if (welcomeMsgAfter) {\n                // If no history but welcome message still exists, also remove it (user has entered taskid)\n                welcomeMsgAfter.remove();\n                console.log('DOMContentLoaded: No history');\n            }\n        }, 500);\n    } else {\n        console.log('DOMContentLoaded: No saved taskId');\n        // 如果没有保存的taskid\n        const welcomeMsg = messagesContainer.querySelector('.welcome-message');\n        if (welcomeMsg) {\n            welcomeMsg.style.display = '';\n        }\n    }\n    \n    // Event listeners\n    // Update task list in real-time\n    taskIdInput.addEventListener('input', () => {\n        updateWorkspacePath();\n        // Update task list in real-time\n        loadTasks();\n    });\n    taskIdInput.addEventListener('change', () => {\n        updateWorkspacePath();\n    });\n    taskIdInput.addEventListener('keydown', (e) => {\n        if (e.key === 'Enter') {\n            e.preventDefault();\n            confirmTask();\n        }\n    });\n    confirmTaskBtn.addEventListener('click', confirmTask);\n    clearTaskBtn.addEventListener('click', clearTask);\n    resumeTaskBtn.addEventListener('click', resumeTask);\n    copyTaskBtn.addEventListener('click', copyTask);\n    downloadTaskBtn.addEventListener('click', downloadTask);\n    configBtn.addEventListener('click', openConfigModal);\n    sendBtn.addEventListener('click', sendMessage);\n    stopBtn.addEventListener('click', stopTask);\n    userInput.addEventListener('keydown', (e) => {\n        if (e.key === 'Enter' && !e.shiftKey) {\n            e.preventDefault();\n            sendMessage();\n        }\n    });\n    // Listen to input changes\n    userInput.addEventListener('input', updateSendButtonState);\n    // Agent selection removed, always use alpha_agent\n    \n    // Task select box event\n    taskSelect.addEventListener('change', (e) => {\n        const selectedPath = e.target.value;\n        if (selectedPath) {\n            taskIdInput.value = selectedPath;\n            updateWorkspacePath();\n        }\n        // Update task list in real-time\n        loadTasks();\n    });\n    \n    // Update task list in real-time\n    taskSelect.addEventListener('input', () => {\n        loadTasks();\n    });\n    \n    // Load task list\n    loadTasks();\n    \n    // Set timer, periodically refresh task list (real-time folder scanning)\n    setInterval(() => {\n        loadTasks();\n    }, 1000); // Refresh every 1 second, real-time update\n    \n    // When page gains focus\n    window.addEventListener('focus', () => {\n        loadTasks();\n    });\n    \n    // When mouse hovers over task select box\n    taskSelect.addEventListener('mouseenter', () => {\n        loadTasks();\n    });\n    \n    // Initialize button state\n    updateTaskButtonsState();\n    updateSendButtonState(); // Initialize send button state\n    \n    // Start HIL task checking when task is running\n    startHILTaskChecking();\n    \n    // File browser events\n    refreshFilesBtn.addEventListener('click', () => {\n        loadFiles(); // Refresh current directory, no parameters\n    });\n    uploadFileBtn.addEventListener('click', () => {\n        fileUploadInput.click();\n    });\n    fileUploadInput.addEventListener('change', handleFileUpload);\n    closeFileBtn.addEventListener('click', () => {\n        fileViewer.style.display = 'none';\n        currentViewingFile = null;\n    });\n    deleteFileBtn.addEventListener('click', handleDeleteFile);\n    downloadFileBtn.addEventListener('click', handleDownloadFile);\n    \n    // Initial file list load\n    loadFiles();\n\n    // Periodically refresh file list\n    setInterval(() => {\n        if (taskIdInput.value.trim()) {\n            loadFiles();\n        }\n    }, 5000);\n    \n    // Initialize configuration modal\n    initConfigModal();\n    initToolsModal();\n    initUsersModal();\n});\n\n// 加载聊天记录\nasync function loadChatHistory(taskId, shouldRemoveWelcome = false) {\n    if (!taskId) {\n        console.log('loadChatHistory: taskId is empty, skip loading');\n        return;\n    }\n    \n    console.log('loadChatHistory: Start loading chat history，taskId =', taskId, 'shouldRemoveWelcome =', shouldRemoveWelcome);\n    \n    try {\n        const response = await fetch(`/api/chat/history?task_id=${encodeURIComponent(taskId)}`, {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        console.log('loadChatHistory: API response:', data);\n        \n        if (data.error) {\n            console.error('Failed to load chat history:', data.error);\n            return;\n        }\n        \n        // Save welcome message reference first（如果存在）\n        const welcomeMsg = messagesContainer.querySelector('.welcome-message');\n        \n        // Load history messages\n        if (data.messages && data.messages.length > 0) {\n            // If there is history, remove welcome message\n            if (welcomeMsg) {\n                // 如果是用户明确操作（shouldRemoveWelcome=true），用淡出动画\n                // If page initialization load, remove directly（不淡出）\n                if (shouldRemoveWelcome) {\n                    welcomeMsg.classList.add('fade-out');\n                    // 返回 Promise，等待淡出动画完成\n                    return new Promise((resolve) => {\n                        setTimeout(() => {\n                            welcomeMsg.remove();\n                            // Clear existing messages and load history\n                            messagesContainer.innerHTML = '';\n                            loadHistoryMessages(data.messages);\n                            resolve();\n                        }, 300);\n                    });\n                } else {\n                    // 页面初始化，直接移除（不淡出）\n                    welcomeMsg.remove();\n                    messagesContainer.innerHTML = '';\n                    loadHistoryMessages(data.messages);\n                }\n            } else {\n                // No welcome message, clear and load directly\n                messagesContainer.innerHTML = '';\n                loadHistoryMessages(data.messages);\n            }\n        } else {\n            console.log('loadChatHistory: 没有找到消息（data.messages 为空或长度为 0）');\n            // 如果没有历史记录，根据 shouldRemoveWelcome 参数决定是否移除欢迎消息\n            // Only remove when user explicitly operates\n            if (shouldRemoveWelcome && welcomeMsg) {\n                welcomeMsg.classList.add('fade-out');\n                setTimeout(() => {\n                    welcomeMsg.remove();\n                }, 300);\n            }\n        }\n    } catch (error) {\n        console.error('Failed to load chat history:', error);\n    }\n}\n\n// Load history messages（辅助函数）\nfunction loadHistoryMessages(messages) {\n    const normalizedMessages = normalizeHistoryMessages(messages);\n    console.log('loadHistoryMessages: found', normalizedMessages.length, 'messages after normalization, start rendering');\n    normalizedMessages.forEach((msg, index) => {\n        console.log(`loadHistoryMessages: rendering message ${index + 1}/${messages.length}:`, {\n            agent: msg.agent,\n            type: msg.type,\n            isUser: msg.isUser,\n            contentLength: msg.content ? msg.content.length : 0\n        });\n        // 直接渲染消息，不保存（避免重复）\n        try {\n            renderMessage(msg.agent, msg.type, msg.content, msg.isUser, false);\n        } catch (error) {\n            console.error(`loadHistoryMessages: rendering message ${index + 1} failed:`, error, msg);\n        }\n    });\n    \n    // Scroll to bottom\n    setTimeout(() => {\n        messagesContainer.scrollTop = messagesContainer.scrollHeight;\n    }, 100);\n    console.log('loadHistoryMessages: chat history loaded');\n}\n\nfunction isThinkingPlaceholderMessage(msg) {\n    if (!msg || typeof msg !== 'object') return false;\n    const type = String(msg.type || '').trim().toLowerCase();\n    if (!['thinking', 'reasoning', 'thinking_start', 'thinking_end'].includes(type)) return false;\n    const content = String(msg.content || '').trim();\n    if (!content) return true;\n    return /^thinking(\\.\\.\\.)?$/i.test(content) || /^model reasoning(\\.\\.\\.)?$/i.test(content);\n}\n\nfunction normalizeHistoryMessages(messages) {\n    if (!Array.isArray(messages)) return [];\n    const filtered = messages.filter(msg => !isThinkingPlaceholderMessage(msg));\n    const merged = [];\n\n    for (const msg of filtered) {\n        const type = String(msg?.type || '').trim().toLowerCase();\n        if ((type === 'thinking' || type === 'reasoning') && merged.length > 0) {\n            const prev = merged[merged.length - 1];\n            const prevType = String(prev?.type || '').trim().toLowerCase();\n            if (\n                prev &&\n                prevType === type &&\n                String(prev.agent || '') === String(msg.agent || '') &&\n                !prev.isUser &&\n                !msg.isUser\n            ) {\n                const prevContent = String(prev.content || '').trim();\n                const nextContent = String(msg.content || '').trim();\n                if (nextContent && nextContent !== prevContent) {\n                    prev.content = nextContent;\n                }\n                continue;\n            }\n        }\n        merged.push({ ...msg });\n    }\n\n    return merged;\n}\n\n// Process save queue\nasync function processSaveQueue() {\n    if (isSaving || saveQueue.length === 0) {\n        return;\n    }\n    \n    isSaving = true;\n    \n    while (saveQueue.length > 0) {\n        const { agent, type, displayContent, isUser } = saveQueue.shift();\n        await saveChatMessageDirect(agent, type, displayContent, isUser);\n    }\n    \n    isSaving = false;\n}\n\n// 直接保存消息到聊天记录（内部函数，由队列调用）\nasync function saveChatMessageDirect(agent, type, displayContent, isUser) {\n    const taskId = taskIdInput.value.trim();\n    if (!taskId) {\n        console.log('saveChatMessageDirect: taskId is empty, skip saving');\n        return;\n    }\n    \n    // 🔧 保存用户看到的内容（美化后的），这样恢复时显示的就是用户之前看到的\n    // Note: timestamp will be replaced with sequence number on backend for privacy\n    const message = {\n        agent: agent,\n        type: type,\n        content: displayContent,  // 保存用户看到的内容（美化后的）\n        isUser: isUser\n        // timestamp removed - will be replaced with sequence number on backend\n    };\n    \n    console.log('saveChatMessageDirect: saving message:', {\n        agent: agent,\n        type: type,\n        isUser: isUser,\n        contentLength: displayContent ? displayContent.length : 0\n    });\n    \n    try {\n        const response = await fetch('/api/chat/save', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                task_id: taskId,\n                message: message\n            })\n        });\n        \n        const result = await response.json();\n        if (result.error) {\n            console.error('saveChatMessageDirect: saving failed:', result.error);\n        } else {\n            console.log('saveChatMessageDirect: saving successful');\n        }\n    } catch (error) {\n        console.error('saveChatMessageDirect: saving chat history failed:', error);\n    }\n}\n\n// 保存消息到聊天记录（添加到队列，串行处理）\nfunction saveChatMessage(agent, type, displayContent, isUser) {\n    // 🔧 添加到队列，确保串行保存，避免并发问题\n    saveQueue.push({ agent, type, displayContent, isUser });\n    \n    // 异步处理队列（不阻塞）\n    processSaveQueue().catch(error => {\n        console.error('processSaveQueue: processing save queue failed:', error);\n        isSaving = false;\n    });\n}\n\n// 确认任务ID\nasync function confirmTask() {\n    // 如果任务正在运行，不允许确认新任务\n    if (isRunning) {\n        alert('Task is running, please stop it first');\n        return;\n    }\n    \n    const taskId = taskIdInput.value.trim();\n    \n    if (!taskId) {\n        alert('Please enter Task ID');\n        return;\n    }\n    \n    confirmTaskBtn.disabled = true;\n    confirmTaskBtn.textContent = 'Confirming...';\n    \n    try {\n        const response = await fetch('/api/task/confirm', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({ task_id: taskId })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            alert(`Confirmation failed: ${data.error}`);\n        } else {\n            // 更新显示\n            taskIdInput.value = data.task_id;\n            // Save to localStorage\n            localStorage.setItem('mla_task_id', data.task_id);\n            // 更新已确认的taskid\n            confirmedTaskId = data.task_id;\n            \n            updateWorkspacePath();\n            loadFiles();\n            \n            // 显示成功消息\n            const message = data.is_new ? 'New task created' : 'Entered existing task';\n            statusText.textContent = message;\n            \n            // Save welcome message reference first（在加载历史记录前）\n            const welcomeMsgBeforeLoad = messagesContainer.querySelector('.welcome-message');\n            \n            // 先加载聊天记录（如果是现有任务，可能已有历史记录）\n            // 传入 shouldRemoveWelcome=true，因为这是用户明确操作，应该移除欢迎消息\n            console.log('confirmTask: Task confirmed successfully，taskId =', data.task_id);\n            await loadChatHistory(data.task_id, true);\n            \n            // Check if messages already exist（加载历史记录后）\n            const existingMessages = messagesContainer.querySelectorAll('.message');\n            const welcomeMsgAfterLoad = messagesContainer.querySelector('.welcome-message');\n            \n            // Check if same confirmation message already exists\n            const messageContent = `${message}: ${data.task_id}`;\n            let messageExists = false;\n            existingMessages.forEach(msg => {\n                const textContent = msg.querySelector('.message-text')?.textContent || '';\n                if (textContent.includes(messageContent)) {\n                    messageExists = true;\n                }\n            });\n            \n            // If welcome message still exists（loadChatHistory 没有处理它，比如没有历史记录的情况）\n            // 且是之前就存在的，则用淡出动画移除\n            // Note: loadChatHistory already handled有历史记录的情况，这里只处理没有历史记录但欢迎消息还在的情况\n            if (welcomeMsgAfterLoad && welcomeMsgAfterLoad === welcomeMsgBeforeLoad && welcomeMsgBeforeLoad && !messageExists) {\n                // 如果 loadChatHistory 没有移除它（没有历史记录），这里移除\n                if (!welcomeMsgAfterLoad.classList.contains('fade-out')) {\n                    welcomeMsgAfterLoad.classList.add('fade-out');\n                    setTimeout(() => {\n                        welcomeMsgAfterLoad.remove();\n                    }, 300);\n                }\n            }\n            \n            // If no duplicate, show confirmation message（保存到历史记录，因为用户看到了）\n            if (!messageExists) {\n                // If welcome message is fading out, slightly delay adding confirmation message\n                if (welcomeMsgAfterLoad && welcomeMsgAfterLoad.classList.contains('fade-out')) {\n                    setTimeout(() => {\n                        addMessage('system', 'info', messageContent, false, true);\n                    }, 150);\n                } else {\n                    addMessage('system', 'info', messageContent, false, true);\n                }\n            }\n            \n            // Refresh task list\n            loadTasks();\n        }\n    } catch (error) {\n        console.error('Task confirmation failed:', error);\n        alert(`Confirmation failed: ${error.message}`);\n    } finally {\n        confirmTaskBtn.disabled = false;\n        confirmTaskBtn.textContent = 'Confirm';\n    }\n}\n\n// Load task list（带防抖，避免频繁请求）\nlet loadTasksTimeout = null;\nasync function loadTasks() {\n    // 清除之前的定时器\n    if (loadTasksTimeout) {\n        clearTimeout(loadTasksTimeout);\n    }\n    \n    // 防抖：如果连续调用，只执行最后一次\n    loadTasksTimeout = setTimeout(async () => {\n        try {\n            const response = await fetch('/api/tasks/list', {\n                credentials: 'include'\n            });\n            \n            const data = await response.json();\n            \n            if (data.error) {\n                console.error('Failed to load task list:', data.error);\n                return;\n            }\n            \n            // Save currently selected value\n            const currentValue = taskSelect.value;\n            \n            // Check if task list has changed（通过比较数量）\n            const currentOptions = Array.from(taskSelect.options).slice(1); // Exclude first \"Select existing task\"\n            const currentTaskNames = currentOptions.map(opt => opt.textContent).sort();\n            const newTaskNames = (data.tasks || []).map(task => task.name).sort();\n            \n            // 如果列表没有变化，不更新DOM（避免闪烁）\n            const hasChanged = JSON.stringify(currentTaskNames) !== JSON.stringify(newTaskNames);\n            \n            if (hasChanged || currentTaskNames.length === 0) {\n                // Clear existing options（保留第一个\"选择现有任务\"选项）\n                taskSelect.innerHTML = '<option value=\"\">Select existing task</option>';\n                \n                // 添加任务选项\n                if (data.tasks && data.tasks.length > 0) {\n                    data.tasks.forEach(task => {\n                        const option = document.createElement('option');\n                        option.value = task.path;  // 使用相对路径\n                        option.textContent = task.name;\n                        taskSelect.appendChild(option);\n                    });\n                }\n                \n                // Restore previously selected value（如果还存在）\n                if (currentValue) {\n                    const optionExists = Array.from(taskSelect.options).some(opt => opt.value === currentValue);\n                    if (optionExists) {\n                        taskSelect.value = currentValue;\n                    }\n                }\n            }\n        } catch (error) {\n            console.error('Failed to load task list:', error);\n        }\n    }, 100); // 100ms 防抖延迟\n}\n\n// Update task-related button disabled state\nfunction updateTaskButtonsState() {\n    if (isRunning) {\n        // When task is running, disable confirm, clear task, and copy task buttons\n        // Download task can still work even when task is running\n        confirmTaskBtn.disabled = true;\n        clearTaskBtn.disabled = true;\n        copyTaskBtn.disabled = true;\n        confirmTaskBtn.style.opacity = '0.5';\n        confirmTaskBtn.style.cursor = 'not-allowed';\n        clearTaskBtn.style.opacity = '0.5';\n        clearTaskBtn.style.cursor = 'not-allowed';\n        copyTaskBtn.style.opacity = '0.5';\n        copyTaskBtn.style.cursor = 'not-allowed';\n        // Download button remains enabled\n        downloadTaskBtn.disabled = false;\n        downloadTaskBtn.style.opacity = '1';\n        downloadTaskBtn.style.cursor = 'pointer';\n    } else {\n        // After task stops, restore button state\n        confirmTaskBtn.disabled = false;\n        clearTaskBtn.disabled = false;\n        copyTaskBtn.disabled = false;\n        downloadTaskBtn.disabled = false;\n        confirmTaskBtn.style.opacity = '1';\n        confirmTaskBtn.style.cursor = 'pointer';\n        clearTaskBtn.style.opacity = '1';\n        clearTaskBtn.style.cursor = 'pointer';\n        copyTaskBtn.style.opacity = '1';\n        copyTaskBtn.style.cursor = 'pointer';\n        downloadTaskBtn.style.opacity = '1';\n        downloadTaskBtn.style.cursor = 'pointer';\n    }\n}\n\n// Update send button state（根据输入框是否有内容或是否有 HIL 任务）\nfunction updateSendButtonState() {\n    const hasContent = userInput.value.trim().length > 0;\n    \n    // If there's an interaction waiting, enable the button (even if input is empty)\n    if (currentHILTask || currentToolConfirmation) {\n        sendBtn.disabled = false;\n        return;\n    }\n    \n    // Only update button state based on input when task is not running\n    if (!isRunning) {\n        sendBtn.disabled = !hasContent;\n    }\n}\n\n// 清空任务\nasync function clearTask() {\n    // If task is running, don't allow clearing\n    if (isRunning) {\n        alert('Task is running, please stop it first');\n        return;\n    }\n    \n    const taskId = taskIdInput.value.trim();\n    \n    if (!taskId) {\n        alert('Please enter Task ID first');\n        return;\n    }\n    \n    // Confirmation dialog\n    const confirmed = confirm(\n        `⚠️ Warning: Are you sure you want to clear task \"${taskId}\" and all its files?\\n\\n` +\n        `This operation will delete all contents in this directory, including:\\n` +\n        `- All generated files\\n` +\n        `- Chat history\\n` +\n        `- Uploaded files\\n` +\n        `- All other data\\n\\n` +\n        `This operation cannot be undone!`\n    );\n    \n    if (!confirmed) {\n        return;\n    }\n    \n    // 二次确认\n    const doubleConfirmed = confirm(\n        `⚠️ Last confirmation: really delete all files in \"${taskId}\" directory?\\n\\n` +\n        `Click \"Confirm\" to immediately execute deletion operation, cannot be undone!`\n    );\n    \n    if (!doubleConfirmed) {\n        return;\n    }\n    \n    clearTaskBtn.disabled = true;\n    clearTaskBtn.textContent = 'Clearing...';\n    \n    try {\n        const response = await fetch('/api/task/clear', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({ task_id: taskId })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            alert(`Clear failed: ${data.error}`);\n        } else {\n            // Clear UI\n            messagesContainer.innerHTML = '<div class=\"welcome-message\"><p>👋 Welcome to MLA-V3 Web UI</p><p>Please set Task ID and Agent above, then enter a task to start conversation.</p></div>';\n            fileTree.innerHTML = '<div class=\"file-tree-empty\">Please set Task ID to view files</div>';\n            fileBrowserPath.textContent = 'Path not set';\n            currentBrowsePath = '';\n            currentViewingFile = null;\n            \n            // 清空 localStorage 中的 task_id\n            localStorage.removeItem('mla_task_id');\n            \n            // 显示成功消息\n            statusText.innerHTML = `<i class=\"fas fa-check-circle\"></i> ${data.message}`;\n            alert(`✓ ${data.message}`);\n            \n            // Refresh task list\n            loadTasks();\n            // 清空已确认的taskid\n            confirmedTaskId = null;\n        }\n    } catch (error) {\n        console.error('Clear task failed:', error);\n        alert(`Clear failed: ${error.message}`);\n    } finally {\n        clearTaskBtn.disabled = false;\n        clearTaskBtn.textContent = 'Clear Task';\n    }\n}\n\n// Copy task function\nasync function copyTask() {\n    // If task is running, don't allow copying\n    if (isRunning) {\n        alert('Task is running, please stop it first');\n        return;\n    }\n    \n    const currentTaskId = taskIdInput.value.trim();\n    if (!currentTaskId) {\n        alert('Please select a task first');\n        return;\n    }\n    \n    // Show input dialog\n    const newTaskName = prompt('Enter new task name:');\n    if (!newTaskName || !newTaskName.trim()) {\n        return; // User cancelled or entered empty\n    }\n    \n    const trimmedName = newTaskName.trim();\n    \n    // Validate input (check for invalid characters)\n    if (trimmedName.includes('..') || trimmedName.includes('/') || trimmedName.includes('\\\\')) {\n        alert('Invalid task name: cannot contain \"..\", \"/\", or \"\\\\\"');\n        return;\n    }\n    \n    copyTaskBtn.disabled = true;\n    copyTaskBtn.textContent = 'Copying...';\n    \n    // Create progress modal\n    const progressModal = createProgressModal();\n    document.body.appendChild(progressModal);\n    \n    let progressInterval = null;\n    \n    try {\n        // Start copy operation\n        const response = await fetch('/api/task/copy', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                source_task_id: currentTaskId,\n                target_task_id: trimmedName\n            })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            closeProgressModal(progressModal);\n            alert(`Copy failed: ${data.error}`);\n            return;\n        }\n        \n        // Start polling for progress\n        progressInterval = setInterval(async () => {\n            try {\n                const progressResponse = await fetch(`/api/task/copy/progress?task_id=${encodeURIComponent(trimmedName)}`, {\n                    credentials: 'include'\n                });\n                const progressData = await progressResponse.json();\n                \n                updateProgressModal(progressModal, progressData);\n                \n                // If completed or error, stop polling\n                if (progressData.status === 'completed' || progressData.status === 'error') {\n                    clearInterval(progressInterval);\n                    \n                    if (progressData.status === 'completed') {\n                        // Wait a bit before closing modal and switching\n                        setTimeout(async () => {\n                            closeProgressModal(progressModal);\n                            // Switch to new task\n                            taskIdInput.value = data.task_id;\n                            await confirmTask();\n                            alert(`Task copied successfully! Switched to \"${data.task_id}\"`);\n                        }, 1000);\n                    } else {\n                        closeProgressModal(progressModal);\n                        alert(`Copy failed: ${progressData.message}`);\n                    }\n                }\n            } catch (error) {\n                console.error('Failed to get progress:', error);\n            }\n        }, 500); // Poll every 500ms\n        \n    } catch (error) {\n        if (progressInterval) {\n            clearInterval(progressInterval);\n        }\n        closeProgressModal(progressModal);\n        console.error('Copy task failed:', error);\n        alert('Copy task failed: ' + error.message);\n    } finally {\n        copyTaskBtn.disabled = false;\n        copyTaskBtn.textContent = 'Copy Task';\n    }\n}\n\n// Create progress modal\nfunction createProgressModal() {\n    const modal = document.createElement('div');\n    modal.id = 'copy-progress-modal';\n    modal.style.cssText = `\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background: rgba(0, 0, 0, 0.5);\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        z-index: 10000;\n    `;\n    \n    const content = document.createElement('div');\n    content.style.cssText = `\n        background: white;\n        padding: 30px;\n        border-radius: 8px;\n        min-width: 400px;\n        max-width: 600px;\n        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n    `;\n    \n    const title = document.createElement('h3');\n    title.textContent = 'Copying Task...';\n    title.style.cssText = 'margin-top: 0; margin-bottom: 20px;';\n    \n    const progressBarContainer = document.createElement('div');\n    progressBarContainer.style.cssText = `\n        width: 100%;\n        height: 20px;\n        background: #f0f0f0;\n        border-radius: 10px;\n        overflow: hidden;\n        margin-bottom: 10px;\n    `;\n    \n    const progressBar = document.createElement('div');\n    progressBar.id = 'copy-progress-bar';\n    progressBar.style.cssText = `\n        height: 100%;\n        background: #4CAF50;\n        width: 0%;\n        transition: width 0.3s ease;\n    `;\n    \n    const progressText = document.createElement('div');\n    progressText.id = 'copy-progress-text';\n    progressText.style.cssText = 'text-align: center; color: #666; font-size: 14px;';\n    progressText.textContent = 'Preparing...';\n    \n    progressBarContainer.appendChild(progressBar);\n    content.appendChild(title);\n    content.appendChild(progressBarContainer);\n    content.appendChild(progressText);\n    modal.appendChild(content);\n    \n    return modal;\n}\n\n// Update progress modal\nfunction updateProgressModal(modal, progressData) {\n    const progressBar = modal.querySelector('#copy-progress-bar');\n    const progressText = modal.querySelector('#copy-progress-text');\n    \n    if (progressBar && progressText) {\n        const progress = progressData.progress || 0;\n        progressBar.style.width = `${progress}%`;\n        progressText.textContent = progressData.message || `Progress: ${progress}%`;\n    }\n}\n\n// Close progress modal\nfunction closeProgressModal(modal) {\n    if (modal && modal.parentNode) {\n        modal.parentNode.removeChild(modal);\n    }\n}\n\n// Download task function\nasync function downloadTask() {\n    const currentTaskId = taskIdInput.value.trim();\n    if (!currentTaskId) {\n        alert('Please select a task first');\n        return;\n    }\n    \n    downloadTaskBtn.disabled = true;\n    downloadTaskBtn.textContent = 'Downloading...';\n    \n    try {\n        // Create download URL\n        const downloadUrl = `/api/task/download?task_id=${encodeURIComponent(currentTaskId)}`;\n        \n        // Create temporary anchor element and trigger download\n        const link = document.createElement('a');\n        link.href = downloadUrl;\n        // Sanitize task_id for filename\n        const safeTaskId = currentTaskId.replace(/\\//g, '_').replace(/\\\\/g, '_').replace(/\\.\\./g, '_');\n        link.download = `${safeTaskId}.zip`;\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n        \n        // Show success message after a short delay (to allow download to start)\n        setTimeout(() => {\n            alert(`Task \"${currentTaskId}\" download started`);\n        }, 500);\n    } catch (error) {\n        console.error('Download task failed:', error);\n        alert('Download task failed: ' + error.message);\n    } finally {\n        downloadTaskBtn.disabled = false;\n        downloadTaskBtn.textContent = 'Download Task';\n    }\n}\n\n// 更新 workspace 路径显示\nfunction updateWorkspacePath() {\n    const taskId = taskIdInput.value.trim();\n    workspacePath.textContent = taskId || 'Please set a path for workspace';\n    fileBrowserPath.textContent = taskId || 'Please set a path for workspace';\n    // 重置浏览路径到根目录\n    currentBrowsePath = '';\n}\n\n// 加载文件列表\nasync function loadFiles(path = null) {\n    const taskId = taskIdInput.value.trim();\n    \n    if (!taskId) {\n        fileTree.innerHTML = '<div class=\"file-tree-empty\">Please set Task ID to view files</div>';\n        currentBrowsePath = '';\n        return;\n    }\n    \n    // 如果 path 是事件对象或无效值，忽略它\n    if (path && typeof path === 'object' && path.constructor && path.constructor.name === 'PointerEvent') {\n        path = null;\n    }\n    if (path && typeof path !== 'string') {\n        path = null;\n    }\n    \n    // 使用指定路径或当前浏览路径或任务ID\n    const browsePath = path || currentBrowsePath || taskId;\n    currentBrowsePath = browsePath;\n    \n    // 更新路径显示（显示相对路径，如果为空则显示根目录）\n    fileBrowserPath.textContent = browsePath || '/';\n    \n    try {\n        const response = await fetch(`/api/files/list?path=${encodeURIComponent(browsePath)}`, {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (data.error) {\n            fileTree.innerHTML = `<div class=\"file-tree-empty\">${data.error}</div>`;\n            return;\n        }\n        \n        fileTree.innerHTML = '';\n        \n        // If not root directory, add parent button（无论目录是否为空）\n        // Root directory determination：如果 browsePath 为空或等于 taskId，则认为是根目录\n        const isRoot = !browsePath || browsePath === taskId || browsePath === '';\n        if (!isRoot) {\n            const backItem = document.createElement('div');\n            backItem.className = 'file-item';\n            backItem.innerHTML = `\n                <span class=\"file-icon\"><i class=\"fas fa-arrow-up\"></i></span>\n                <span class=\"file-name\">.. (Go back to parent directory)</span>\n            `;\n            backItem.addEventListener('click', () => {\n                // Calculate parent path\n                const pathParts = browsePath.split('/').filter(p => p);\n                if (pathParts.length > 1) {\n                    // Has parent directory\n                    pathParts.pop();\n                    const parentPath = pathParts.join('/');\n                    loadFiles(parentPath);\n                } else {\n                    // Return to root directory（taskId）\n                    loadFiles(taskId);\n                }\n            });\n            fileTree.appendChild(backItem);\n        }\n        \n        if (data.files && data.files.length > 0) {\n            data.files.forEach(file => {\n                const fileItem = document.createElement('div');\n                fileItem.className = 'file-item';\n                fileItem.dataset.path = file.path;\n                fileItem.dataset.type = file.type;\n                \n                const icon = file.type === 'directory' ? '<i class=\"fas fa-folder\"></i>' : '<i class=\"fas fa-file\"></i>';\n                const size = file.type === 'file' ? ` (${formatFileSize(file.size)})` : '';\n                \n                fileItem.innerHTML = `\n                    <span class=\"file-icon\">${icon}</span>\n                    <span class=\"file-name\">${escapeHtml(file.name)}${size}</span>\n                    ${file.type === 'file' ? '<button class=\"file-item-download-btn\" title=\"Download file\"><i class=\"fas fa-download\"></i></button>' : ''}\n                `;\n                \n                // 添加下载按钮的事件监听器（如果是文件）\n                if (file.type === 'file') {\n                    const downloadBtn = fileItem.querySelector('.file-item-download-btn');\n                    if (downloadBtn) {\n                        downloadBtn.addEventListener('click', (e) => {\n                            e.stopPropagation(); // 阻止事件冒泡到文件项\n                            downloadFileFromList(file.path, file.name);\n                        });\n                    }\n                }\n                \n                fileItem.addEventListener('click', (e) => {\n                    // 如果点击的是下载按钮，不处理\n                    if (e.target.classList.contains('file-item-download-btn') || e.target.closest('.file-item-download-btn')) {\n                        return;\n                    }\n                    // 移除其他选中状态\n                    fileTree.querySelectorAll('.file-item').forEach(item => {\n                        item.classList.remove('selected');\n                    });\n                    // 添加选中状态\n                    fileItem.classList.add('selected');\n                    \n                    if (file.type === 'file') {\n                        openFile(file.path, file.name);\n                    } else {\n                        // 点击目录，进入该目录\n                        loadFiles(file.path);\n                    }\n                });\n                \n                // 右键菜单（下载或删除）\n                fileItem.addEventListener('contextmenu', (e) => {\n                    e.preventDefault();\n                    if (file.type === 'file') {\n                        // 文件：显示下载和删除选项\n                        const action = confirm(`File: \"${file.name}\"\\n\\nClick OK to download, or Cancel to delete.`);\n                        if (action === null) {\n                            return; // 用户点击了取消对话框\n                        } else if (action) {\n                            // 用户点击了 OK，下载文件\n                            downloadFileFromList(file.path, file.name);\n                        } else {\n                            // 用户点击了 Cancel，删除文件\n                    if (confirm(`Are you sure you want to delete \"${file.name}\"?`)) {\n                        deleteFileOrDir(file.path, file.name);\n                            }\n                        }\n                    } else {\n                        // 目录：只显示删除选项\n                        if (confirm(`Are you sure you want to delete \"${file.name}\"?`)) {\n                            deleteFileOrDir(file.path, file.name);\n                        }\n                    }\n                });\n                \n                fileTree.appendChild(fileItem);\n            });\n        } else {\n            // 如果目录为空，显示提示（但保留返回上级按钮）\n            const emptyMsg = document.createElement('div');\n            emptyMsg.className = 'file-tree-empty';\n            emptyMsg.textContent = 'Directory is empty';\n            fileTree.appendChild(emptyMsg);\n        }\n    } catch (error) {\n        console.error('Load file list failed:', error);\n        fileTree.innerHTML = `<div class=\"file-tree-empty\">Load failed: ${error.message}</div>`;\n    }\n}\n\n// 检查文件是否是图片\nfunction isImageFile(fileName) {\n    if (!fileName) return false;\n    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.ico'];\n    const lowerFileName = fileName.toLowerCase();\n    return imageExtensions.some(ext => lowerFileName.endsWith(ext));\n}\n\n// 打开文件\nasync function openFile(filePath, fileName) {\n    try {\n        // 清空之前的样式类\n        fileViewerContent.classList.remove('image-mode', 'text-mode');\n        \n        // 检查是否是图片文件\n        if (isImageFile(fileName)) {\n            // 图片文件：直接使用预览 API URL\n            const previewUrl = `/api/files/preview?path=${encodeURIComponent(filePath)}`;\n            \n            // 设置图片模式样式\n            fileViewerContent.classList.add('image-mode');\n            \n            // 清空内容并显示图片\n            fileViewerContent.innerHTML = '';\n            const img = document.createElement('img');\n            img.src = previewUrl;\n            img.alt = fileName;\n            img.onerror = function() {\n                fileViewerContent.classList.remove('image-mode');\n                fileViewerContent.classList.add('text-mode');\n                fileViewerContent.innerHTML = `<div style=\"color: #ff6b6b; padding: 20px; text-align: center;\">Failed to load image: ${escapeHtml(fileName)}</div>`;\n            };\n            img.onload = function() {\n                // 图片加载成功，保持 image-mode\n            };\n            \n            fileViewerContent.appendChild(img);\n        } else {\n            // 文本文件：读取内容并显示\n            fileViewerContent.classList.add('text-mode');\n            \n        const response = await fetch(`/api/files/read?path=${encodeURIComponent(filePath)}`, {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (data.error) {\n                fileViewerContent.innerHTML = `<div style=\"color: #ff6b6b; padding: 20px;\">Error: ${escapeHtml(data.error)}</div>`;\n        } else {\n            fileViewerContent.textContent = data.content;\n            }\n        }\n        \n        fileViewerTitle.textContent = fileName;\n        currentViewingFile = filePath;\n        fileViewer.style.display = 'flex';\n    } catch (error) {\n        console.error('Read file failed:', error);\n        fileViewerContent.classList.remove('image-mode');\n        fileViewerContent.classList.add('text-mode');\n        fileViewerContent.innerHTML = `<div style=\"color: #ff6b6b; padding: 20px;\">Read failed: ${escapeHtml(error.message)}</div>`;\n        fileViewerTitle.textContent = fileName;\n        currentViewingFile = filePath;\n        fileViewer.style.display = 'flex';\n    }\n}\n\n// 从文件列表下载文件（全局函数，供 inline onclick 调用）\nasync function downloadFileFromList(filePath, fileName) {\n    try {\n        // filePath 已经是相对于用户工作空间的完整路径（包含 task_id）\n        // 所以不需要传递 task_id 参数，直接使用路径即可\n        const url = `/api/files/download?path=${encodeURIComponent(filePath)}`;\n        \n        // 使用 fetch 来下载文件，这样可以更好地处理错误\n        const response = await fetch(url, {\n            method: 'GET',\n            credentials: 'include'\n        });\n        \n        // 检查响应状态码\n        if (!response.ok) {\n            // 如果状态码不是 2xx，尝试解析错误信息\n            // 注意：即使 content-type 是 application/json，如果状态码不是 200，也可能是错误\n            const contentType = response.headers.get('content-type') || '';\n            if (contentType.includes('application/json')) {\n                try {\n                    const data = await response.json();\n                    alert(`Download failed: ${data.error || `HTTP ${response.status}: ${response.statusText}`}`);\n                } catch (e) {\n                    alert(`Download failed: HTTP ${response.status}: ${response.statusText}`);\n                }\n            } else {\n                alert(`Download failed: HTTP ${response.status}: ${response.statusText}`);\n            }\n            return;\n        }\n        \n        // 如果状态码是 200，直接下载文件（无论 content-type 是什么，包括 application/json）\n        // 因为用户可能就是要下载 JSON 文件\n        const blob = await response.blob();\n        const link = document.createElement('a');\n        link.href = URL.createObjectURL(blob);\n        link.download = fileName || filePath.split('/').pop() || 'download';\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n        URL.revokeObjectURL(link.href);\n    } catch (error) {\n        console.error('Download file failed:', error);\n        alert(`Download failed: ${error.message}`);\n    }\n}\n\n// 下载文件（从文件查看器或选中的文件）\nasync function handleDownloadFile() {\n    let filePath = currentViewingFile;\n    let fileName = filePath ? filePath.split('/').pop() : null;\n    \n    // 如果文件查看器中当前没有文件，检查是否有选中的文件\n    if (!filePath) {\n        const selectedItem = fileTree.querySelector('.file-item.selected');\n        if (!selectedItem) {\n            alert('Please select a file to download first');\n            return;\n        }\n        // 检查选中的是文件还是目录\n        if (selectedItem.dataset.type === 'directory') {\n            alert('Cannot download directory. Please select a file.');\n            return;\n        }\n        filePath = selectedItem.dataset.path;\n        fileName = selectedItem.querySelector('.file-name')?.textContent?.split(' (')[0] || filePath.split('/').pop();\n    }\n    \n    await downloadFileFromList(filePath, fileName);\n}\n\n// 删除文件\nasync function handleDeleteFile() {\n    if (!currentViewingFile) {\n        const selectedItem = fileTree.querySelector('.file-item.selected');\n        if (!selectedItem) {\n            alert('Please select a file to delete first');\n            return;\n        }\n        currentViewingFile = selectedItem.dataset.path;\n    }\n    \n    const fileName = currentViewingFile.split('/').pop() || currentViewingFile;\n    if (!confirm(`Are you sure you want to delete \"${fileName}\"?`)) {\n        return;\n    }\n    \n    try {\n        const response = await fetch('/api/files/delete', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({ path: currentViewingFile })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            alert(`Delete failed: ${data.error}`);\n        } else {\n            alert('Deleted successfully');\n            // Close file viewer\n            fileViewer.style.display = 'none';\n            currentViewingFile = null;\n            // 刷新文件列表\n            loadFiles();\n        }\n    } catch (error) {\n        console.error('Delete file failed:', error);\n        alert(`Delete failed: ${error.message}`);\n    }\n}\n\n// 处理文件上传\nasync function handleFileUpload(event) {\n    const files = event.target.files;\n    if (!files || files.length === 0) {\n        return;\n    }\n    \n    const taskId = taskIdInput.value.trim();\n    if (!taskId) {\n        alert('Please set Task ID first');\n        return;\n    }\n    \n    // 使用当前浏览路径或任务ID作为目标目录\n    const targetDir = currentBrowsePath || taskId;\n    \n    for (const file of files) {\n        try {\n            const formData = new FormData();\n            formData.append('file', file);\n            formData.append('target_dir', targetDir);\n            \n            const response = await fetch('/api/files/files', {\n                method: 'POST',\n                credentials: 'include',\n                body: formData\n            });\n            \n            const data = await response.json();\n            \n            if (data.error) {\n                alert(`Upload \"${file.name}\" failed: ${data.error}`);\n            } else {\n                console.log(`Upload \"${file.name}\" successful`);\n            }\n        } catch (error) {\n            console.error('Upload file failed:', error);\n            alert(`Upload \"${file.name}\" failed: ${error.message}`);\n        }\n    }\n    \n    // 清空文件选择\n    event.target.value = '';\n    \n    // 刷新文件列表\n    loadFiles();\n}\n\n// 格式化文件大小\nfunction formatFileSize(bytes) {\n    if (bytes < 1024) return bytes + ' B';\n    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n    return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n}\n\n// 删除文件或目录\nasync function deleteFileOrDir(filePath, fileName) {\n    try {\n        const response = await fetch('/api/files/delete', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({ path: filePath })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            alert(`Delete failed: ${data.error}`);\n        } else {\n            // If deleting currently viewing file，关闭查看器\n            if (currentViewingFile === filePath) {\n                fileViewer.style.display = 'none';\n                currentViewingFile = null;\n            }\n            // 刷新文件列表\n            loadFiles();\n        }\n    } catch (error) {\n        console.error('Delete failed:', error);\n        alert(`Delete failed: ${error.message}`);\n    }\n}\n\n// HTML 转义\nfunction escapeHtml(text) {\n    const div = document.createElement('div');\n    div.textContent = text;\n    return div.innerHTML;\n}\n\n// Agent selection functions\nfunction updateAgentSelectButton() {\n    if (agentSelectText) {\n        agentSelectText.textContent = selectedAgent;\n    }\n}\n\n// Initialize agent system selector\nasync function initAgentSystemSelector() {\n    try {\n        const response = await fetch('/api/agent-systems', { credentials: 'include' });\n        const data = await response.json();\n        \n        if (data.systems && agentSystemSelect) {\n            agentSystemSelect.innerHTML = '';\n            data.systems.forEach(sys => {\n                const option = document.createElement('option');\n                option.value = sys;\n                option.textContent = sys;\n                if (sys === agentSystem) option.selected = true;\n                agentSystemSelect.appendChild(option);\n            });\n            \n            // Ensure current value is valid\n            if (!data.systems.includes(agentSystem)) {\n                agentSystem = data.systems[0] || 'Researcher';\n                localStorage.setItem('mla_agent_system', agentSystem);\n                agentSystemSelect.value = agentSystem;\n            }\n            \n            // Change event: switch agent system → reload agents list + agent tree\n            agentSystemSelect.addEventListener('change', async (e) => {\n                agentSystem = e.target.value;\n                localStorage.setItem('mla_agent_system', agentSystem);\n                \n                // Reset selected agent to default for new system\n                selectedAgent = 'alpha_agent';\n                localStorage.setItem('mla_selected_agent', selectedAgent);\n                const agentSelectText = document.getElementById('agent-select-text');\n                if (agentSelectText) agentSelectText.textContent = selectedAgent;\n                \n                console.log('Switched agent system to:', agentSystem);\n            });\n        }\n    } catch (error) {\n        console.error('Failed to load agent systems:', error);\n    }\n}\n\n// Load agents list\nasync function loadAgentsList() {\n    try {\n        const response = await fetch('/api/agents?agent_system=' + agentSystem, {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (data.error) {\n            agentSelectList.innerHTML = `<div class=\"agent-select-error\">Error: ${data.error}</div>`;\n            return;\n        }\n        \n        return data.agents || [];\n    } catch (error) {\n        console.error('Failed to load agents:', error);\n        agentSelectList.innerHTML = `<div class=\"agent-select-error\">Failed to load agents: ${error.message}</div>`;\n        return [];\n    }\n}\n\n// Render agents list\nfunction renderAgentsList(agents, searchTerm = '') {\n    if (!agentSelectList) return;\n    \n    if (agents.length === 0) {\n        agentSelectList.innerHTML = '<div class=\"agent-select-empty\">No agents found</div>';\n        return;\n    }\n    \n    // Filter agents by search term\n    const filteredAgents = searchTerm \n        ? agents.filter(agent => \n            agent.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n            (agent.description && agent.description.toLowerCase().includes(searchTerm.toLowerCase()))\n          )\n        : agents;\n    \n    if (filteredAgents.length === 0) {\n        agentSelectList.innerHTML = '<div class=\"agent-select-empty\">No agents match your search</div>';\n        return;\n    }\n    \n    // Group by level\n    const agentsByLevel = {};\n    filteredAgents.forEach(agent => {\n        const level = agent.level || 0;\n        if (!agentsByLevel[level]) {\n            agentsByLevel[level] = [];\n        }\n        agentsByLevel[level].push(agent);\n    });\n    \n    // Render\n    let html = '';\n    const levels = Object.keys(agentsByLevel).sort((a, b) => parseInt(b) - parseInt(a));\n    \n    levels.forEach(level => {\n        html += `<div class=\"agent-select-level-group\">\n            <div class=\"agent-select-level-header\">Level ${level}</div>\n            <div class=\"agent-select-level-agents\">`;\n        \n        agentsByLevel[level].forEach(agent => {\n            const isSelected = agent.name === selectedAgent;\n            html += `<div class=\"agent-select-item ${isSelected ? 'selected' : ''}\" data-agent-name=\"${agent.name}\">\n                <div class=\"agent-select-item-header\">\n                    <span class=\"agent-select-item-name\">${agent.name}</span>\n                    <span class=\"agent-select-item-level\">L${level}</span>\n                </div>\n                ${agent.description ? `<div class=\"agent-select-item-description\">${agent.description}</div>` : ''}\n            </div>`;\n        });\n        \n        html += `</div></div>`;\n    });\n    \n    agentSelectList.innerHTML = html;\n    \n    // Add click handlers\n    agentSelectList.querySelectorAll('.agent-select-item').forEach(item => {\n        item.addEventListener('click', () => {\n            const agentName = item.getAttribute('data-agent-name');\n            selectAgent(agentName);\n        });\n    });\n}\n\n// Select agent\nasync function selectAgent(agentName) {\n    selectedAgent = agentName;\n    localStorage.setItem('mla_selected_agent', agentName);\n    updateAgentSelectButton();\n    \n    // Load and display agent tree (keep modal open to show tree)\n    await loadAgentTreeForAgent(agentName);\n    \n    // Update selected state in list\n    if (agentSelectList) {\n        agentSelectList.querySelectorAll('.agent-select-item').forEach(item => {\n            const itemAgentName = item.getAttribute('data-agent-name');\n            if (itemAgentName === agentName) {\n                item.classList.add('selected');\n            } else {\n                item.classList.remove('selected');\n            }\n        });\n    }\n}\n\n// Load agent tree for specific agent\nasync function loadAgentTreeForAgent(agentName) {\n    if (!agentTreePanelContent) return;\n    \n    agentTreePanelContent.innerHTML = '<div class=\"agent-tree-loading\">Loading agent tree...</div>';\n    \n    try {\n        const response = await fetch(`/api/config/agent-tree?root_agent=${encodeURIComponent(agentName)}&agent_system=${encodeURIComponent(agentSystem)}`, {\n            credentials: 'include'\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            agentTreePanelContent.innerHTML = `<div class=\"agent-tree-error\">Error: ${data.error}</div>`;\n            return;\n        }\n        \n        // Render tree\n        agentTreePanelContent.innerHTML = '';\n        if (data.trees && data.trees.length > 0) {\n            const treeElement = renderAgentTreeNodeForPanel(data.trees[0], 0, true);\n            agentTreePanelContent.appendChild(treeElement);\n        } else {\n            agentTreePanelContent.innerHTML = '<div class=\"agent-tree-empty\">No tree found</div>';\n        }\n    } catch (error) {\n        console.error('Failed to load agent tree:', error);\n        agentTreePanelContent.innerHTML = `<div class=\"agent-tree-error\">Failed to load agent tree: ${error.message}</div>`;\n    }\n}\n\n// Render agent tree node for panel\nfunction renderAgentTreeNodeForPanel(node, depth = 0, isRoot = false) {\n    const nodeDiv = document.createElement('div');\n    nodeDiv.className = `agent-tree-node ${isRoot ? 'root' : ''}`;\n    \n    // Node content\n    const content = document.createElement('div');\n    content.className = 'agent-tree-node-content';\n    content.style.paddingLeft = `${depth * 24}px`;\n    \n    // Level badge\n    const levelBadge = document.createElement('span');\n    levelBadge.className = `agent-tree-level level-${node.level}`;\n    levelBadge.textContent = `L${node.level}`;\n    \n    // Agent name\n    const nameSpan = document.createElement('span');\n    nameSpan.className = 'agent-tree-name';\n    nameSpan.textContent = node.name;\n    \n    // Expand/collapse button (only if has children)\n    let expandBtn = null;\n    if (node.children && node.children.length > 0) {\n        expandBtn = document.createElement('button');\n        expandBtn.className = 'agent-tree-expand';\n        expandBtn.innerHTML = '<i class=\"fas fa-chevron-down\"></i>';\n    }\n    \n    content.appendChild(levelBadge);\n    content.appendChild(nameSpan);\n    if (expandBtn) {\n        content.appendChild(expandBtn);\n    }\n    \n    nodeDiv.appendChild(content);\n    \n    // Children container\n    const childrenDiv = document.createElement('div');\n    childrenDiv.className = 'agent-tree-children';\n    childrenDiv.style.display = 'block'; // Default expanded\n    \n    // Render child agents\n    if (node.children && node.children.length > 0) {\n        node.children.forEach(child => {\n            const childElement = renderAgentTreeNodeForPanel(child, depth + 1, false);\n            childrenDiv.appendChild(childElement);\n        });\n    }\n    \n    nodeDiv.appendChild(childrenDiv);\n    \n    // Toggle expand/collapse\n    if (expandBtn) {\n        let isExpanded = true;\n        expandBtn.addEventListener('click', (e) => {\n            e.stopPropagation();\n            isExpanded = !isExpanded;\n            childrenDiv.style.display = isExpanded ? 'block' : 'none';\n            expandBtn.innerHTML = isExpanded \n                ? '<i class=\"fas fa-chevron-down\"></i>' \n                : '<i class=\"fas fa-chevron-right\"></i>';\n        });\n    }\n    \n    return nodeDiv;\n}\n\n// Open agent select modal\nasync function openAgentSelectModal() {\n    if (!agentSelectModal) return;\n    \n    agentSelectModal.style.display = 'flex';\n    agentSelectList.innerHTML = '<div class=\"agent-select-loading\">Loading agents...</div>';\n    \n    // Load agents list\n    const agents = await loadAgentsList();\n    renderAgentsList(agents);\n    \n    // Load current agent tree if available\n    if (selectedAgent) {\n        await loadAgentTreeForAgent(selectedAgent);\n    } else {\n        if (agentTreePanelContent) {\n            agentTreePanelContent.innerHTML = '<div class=\"agent-tree-empty\">Select an agent to view tree</div>';\n        }\n    }\n    \n    // Focus search input\n    if (agentSearchInput) {\n        agentSearchInput.focus();\n    }\n}\n\n// Close agent select modal\nfunction closeAgentSelectModal() {\n    if (agentSelectModal) {\n        agentSelectModal.style.display = 'none';\n    }\n    if (agentSearchInput) {\n        agentSearchInput.value = '';\n    }\n}\n\n// Initialize agent selection\nfunction initAgentSelection() {\n    updateAgentSelectButton();\n    \n    // Event listeners\n    if (agentSelectBtn) {\n        agentSelectBtn.addEventListener('click', openAgentSelectModal);\n    }\n    \n    if (closeAgentSelectBtn) {\n        closeAgentSelectBtn.addEventListener('click', closeAgentSelectModal);\n    }\n    \n    // Search functionality\n    if (agentSearchInput) {\n        let searchTimeout;\n        agentSearchInput.addEventListener('input', (e) => {\n            clearTimeout(searchTimeout);\n            searchTimeout = setTimeout(async () => {\n                const agents = await loadAgentsList();\n                renderAgentsList(agents, e.target.value);\n            }, 300);\n        });\n    }\n    \n    // Close modal on outside click\n    if (agentSelectModal) {\n        agentSelectModal.addEventListener('click', (e) => {\n            if (e.target === agentSelectModal) {\n                closeAgentSelectModal();\n            }\n        });\n    }\n}\n\n// 恢复中断的任务\nasync function resumeTask() {\n    const taskId = taskIdInput.value.trim();\n    if (!taskId) {\n        alert('请先输入 Task ID');\n        return;\n    }\n    \n    if (isRunning) {\n        alert('当前有任务正在运行');\n        return;\n    }\n    \n    try {\n        // 检查是否有可恢复的任务\n        const response = await fetch(`/api/resume/check?task_id=${encodeURIComponent(taskId)}`, {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        \n        if (!data.found) {\n            alert(`没有找到可恢复的任务: ${data.message || '无中断任务'}`);\n            return;\n        }\n        \n        // 确认恢复\n        const confirmMsg = `发现中断的任务:\\n\\nAgent: ${data.agent_name}\\n任务: ${data.user_input}\\n中断于: ${data.interrupted_at}\\n栈深度: ${data.stack_depth}\\n\\n是否恢复此任务？`;\n        if (!confirm(confirmMsg)) {\n            return;\n        }\n        \n        // 确保 taskId 已确认\n        if (confirmedTaskId !== taskId) {\n            const confirmResponse = await fetch('/api/task/confirm', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application/json' },\n                credentials: 'include',\n                body: JSON.stringify({ task_id: taskId })\n            });\n            const confirmData = await confirmResponse.json();\n            if (confirmData.error) {\n                alert(`Task confirmation failed: ${confirmData.error}`);\n                return;\n            }\n            confirmedTaskId = taskId;\n            localStorage.setItem('mla_task_id', taskId);\n        }\n        \n        // 设置运行状态\n        isRunning = true;\n        sendBtn.disabled = true;\n        sendBtn.style.display = 'none';\n        stopBtn.style.display = 'inline-block';\n        userInput.disabled = true;\n        statusText.textContent = 'Resuming...';\n        updateTaskButtonsState();\n        startHILTaskChecking();\n        \n        // 添加恢复提示消息\n        addMessage('system', 'system', `▶️ 恢复任务: ${data.agent_name} - ${data.user_input}`, true, false);\n        \n        // 使用原始的 agent_name 和 user_input 发起 SSE 连接\n        startSSEConnection(taskId, data.agent_name, data.user_input, agentSystem);\n        \n    } catch (error) {\n        console.error('Resume task failed:', error);\n        alert(`恢复任务失败: ${error.message}`);\n    }\n}\n\n// 发送消息\nasync function sendMessage() {\n    const taskId = taskIdInput.value.trim();\n    const agentName = selectedAgent || 'alpha_agent';  // Use selected agent\n    const userInputText = userInput.value.trim();\n    // agentSystem is already a global variable, no need to redeclare\n    \n    if (!taskId) {\n        alert('Please enter Task ID');\n        return;\n    }\n    \n    // If there's a HIL task waiting, respond to it instead of starting a new task\n    if (currentHILTask) {\n        await respondToHILTask(userInputText);\n        return;\n    }\n\n    // Tool confirmation takes precedence over starting a new task\n    if (currentToolConfirmation) {\n        const normalized = userInputText.trim().toLowerCase();\n        if (!['y', 'yes', 'n', 'no'].includes(normalized)) {\n            alert('Please enter yes/y or no/n for tool confirmation');\n            return;\n        }\n        await respondToToolConfirmation(normalized === 'y' || normalized === 'yes');\n        return;\n    }\n    \n    // If input is empty or button is disabled, return directly（不弹出提示）\n    if (!userInputText || sendBtn.disabled) {\n        return;\n    }\n    \n    if (isRunning) {\n        alert('A task is already running, please wait for it to complete');\n        return;\n    }\n    \n    // If taskid not confirmed, auto-confirm first\n    if (confirmedTaskId !== taskId) {\n        console.log('sendMessage: taskid not confirmed, auto-confirm first');\n        try {\n            // Call confirmation logic（但不显示确认消息，因为用户没有点击确定按钮）\n            const response = await fetch('/api/task/confirm', {\n                method: 'POST',\n                headers: {\n                    'Content-Type': 'application/json'\n                },\n                credentials: 'include',\n                body: JSON.stringify({ task_id: taskId })\n            });\n            \n            const data = await response.json();\n            \n            if (data.error) {\n                alert(`Task confirmation failed: ${data.error}`);\n                return;\n            }\n            \n            // 更新已确认的taskid\n            confirmedTaskId = data.task_id;\n            // 更新localStorage\n            localStorage.setItem('mla_task_id', data.task_id);\n            // 更新工作空间路径和文件列表\n            updateWorkspacePath();\n            loadFiles();\n            // 加载聊天记录（静默加载，不显示确认消息）\n            await loadChatHistory(data.task_id, true);\n        } catch (error) {\n            console.error('Auto-confirm task failed:', error);\n            alert(`Auto-confirm task failed: ${error.message}`);\n            return;\n        }\n    }\n    \n    // Disable input\n    isRunning = true;\n    sendBtn.disabled = true;\n    sendBtn.style.display = 'none';\n    stopBtn.style.display = 'inline-block';\n    userInput.disabled = true;\n    statusText.textContent = 'Running...';\n    statusText.style.color = '';\n    updateTaskButtonsState(); // Update task button state\n    \n    // Start checking for HIL tasks\n    startHILTaskChecking();\n    \n    // Remove welcome message with fade-out animation\n    const welcomeMsg = messagesContainer.querySelector('.welcome-message');\n    if (welcomeMsg) {\n        welcomeMsg.classList.add('fade-out');\n        setTimeout(() => {\n            welcomeMsg.remove();\n            // Wait for animation to complete before adding user message\n            addMessage('user', 'user', userInputText, true, true);\n        }, 300);\n    } else {\n        // 如果没有欢迎消息，直接添加用户消息\n        addMessage('user', 'user', userInputText, true, true);\n    }\n    \n    // 清空输入框\n    userInput.value = '';\n    \n    // 在任务末尾添加时间戳（与 CLI 行为一致）\n    const now = new Date();\n    const timestamp = now.getFullYear() + '-' + \n        String(now.getMonth() + 1).padStart(2, '0') + '-' + \n        String(now.getDate()).padStart(2, '0') + ' ' + \n        String(now.getHours()).padStart(2, '0') + ':' + \n        String(now.getMinutes()).padStart(2, '0') + ':' + \n        String(now.getSeconds()).padStart(2, '0');\n    const userInputWithTimestamp = `${userInputText} [时间: ${timestamp}]`;\n    \n    // 启动 SSE 连接（发送带时间戳的输入）\n    startSSEConnection(taskId, agentName, userInputWithTimestamp, agentSystem);\n}\n\n// 停止任务\nasync function stopTask() {\n    if (!isRunning) {\n        return;\n    }\n    \n    try {\n        const response = await fetch('/api/stop', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include'\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            alert(`Stop failed: ${data.error}`);\n        } else {\n            statusText.textContent = 'Stopping...';\n            // Remove all loading animations\n            removeAllLoadingAnimations();\n            \n            // 关闭 SSE 连接\n            if (currentEventSource) {\n                currentEventSource.close();\n                currentEventSource = null;\n            }\n            // Reset state\n            isRunning = false;\n            \n            // Stop HIL checking\n            stopHILTaskChecking();\n            clearHILState();\n            clearToolConfirmationState();\n            sendBtn.disabled = false;\n            sendBtn.style.display = 'inline-block';\n            stopBtn.style.display = 'none';\n            userInput.disabled = false;\n            statusText.textContent = 'Stopped';\n            updateTaskButtonsState(); // Update task button state\n            updateSendButtonState(); // Update send button state\n        }\n    } catch (error) {\n        console.error('Stop task failed:', error);\n        alert(`Stop failed: ${error.message}`);\n    }\n}\n\n// 启动 SSE 连接\nfunction startSSEConnection(taskId, agentName, userInputText, agentSystem) {\n    // 关闭现有连接\n    if (currentEventSource) {\n        currentEventSource.close();\n    }\n    \n    // 使用 POST 方法（通过 fetch）进行流式读取\n    fetch('/api/run', {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        credentials: 'include',\n        body: JSON.stringify({\n            task_id: taskId,\n            agent_name: agentName,\n            user_input: userInputText,\n            agent_system: agentSystem\n        })\n    }).then(response => {\n        if (!response.ok) {\n            return response.json().then(data => {\n                throw new Error(data.error || `HTTP error! status: ${response.status}`);\n            });\n        }\n        \n        const reader = response.body.getReader();\n        const decoder = new TextDecoder();\n        let buffer = '';\n        \n        function readStream() {\n            reader.read().then(({ done, value }) => {\n                if (done) {\n                    // Task completed\n                isRunning = false;\n                sendBtn.disabled = false;\n                sendBtn.style.display = 'inline-block';\n                stopBtn.style.display = 'none';\n                userInput.disabled = false;\n                statusText.textContent = 'Ready';\n                updateTaskButtonsState(); // Update task button state\n                updateSendButtonState(); // Update send button state\n                    return;\n                }\n                \n                buffer += decoder.decode(value, { stream: true });\n                const lines = buffer.split('\\n');\n                buffer = lines.pop() || ''; // 保留最后不完整的行\n                \n                for (const line of lines) {\n                    if (line.trim() === '' || line.startsWith(':')) {\n                        continue; // 跳过空行和心跳\n                    }\n                    \n                    if (line.startsWith('data: ')) {\n                        try {\n                            const jsonStr = line.slice(6);\n                            const data = JSON.parse(jsonStr);\n                            // JSON.parse 应该已经将 \\n 转换为真正的换行符\n                            // 但如果 content 中还有字符串形式的 \\n，需要额外处理\n                            if (data.content && typeof data.content === 'string') {\n                                // 确保字符串中的 \\n 是真正的换行符（JSON.parse 应该已经处理了）\n                                // 但如果还有转义的 \\n（即 \\\\n），需要转换\n                                data.content = data.content.replace(/\\\\n/g, '\\n');\n                                data.content = data.content.replace(/\\\\r\\\\n/g, '\\r\\n');\n                                data.content = data.content.replace(/\\\\r/g, '\\r');\n                            }\n                            handleSSEMessage(data);\n                        } catch (e) {\n                            console.error('Parse SSE message failed:', e, line);\n                        }\n                    }\n                }\n                \n                readStream();\n            }).catch(error => {\n                console.error('Read stream failed:', error);\n                finalizeAllLiveStreams();\n                // Remove all loading animations\n                removeAllLoadingAnimations();\n                \n                isRunning = false;\n                sendBtn.disabled = false;\n                sendBtn.style.display = 'inline-block';\n                stopBtn.style.display = 'none';\n                userInput.disabled = false;\n                statusText.textContent = 'Error';\n                clearToolConfirmationState();\n                updateTaskButtonsState(); // Update task button state\n                updateSendButtonState(); // Update send button state\n                showMessage('system', 'error', `Connection error: ${error.message}`);\n            });\n        }\n        \n        readStream();\n    }).catch(error => {\n        console.error('请求失败:', error);\n        finalizeAllLiveStreams();\n        // Remove all loading animations\n        removeAllLoadingAnimations();\n        \n        isRunning = false;\n        sendBtn.disabled = false;\n        sendBtn.style.display = 'inline-block';\n        stopBtn.style.display = 'none';\n        userInput.disabled = false;\n        statusText.textContent = 'Error';\n        clearToolConfirmationState();\n        showMessage('system', 'error', `Request failed: ${error.message}`);\n    });\n}\n\n// 处理 SSE 消息\nfunction handleSSEMessage(data) {\n    const type = data.type || 'info';\n    const agent = data.agent || 'unknown';\n    const content = data.content || '';\n    pruneEmptyThinkingCards();\n    \n    if (type === 'end') {\n        finalizeAllLiveStreams();\n        // Remove all loading animations\n        removeAllLoadingAnimations();\n        \n        isRunning = false;\n        sendBtn.disabled = false;\n        sendBtn.style.display = 'inline-block';\n        stopBtn.style.display = 'none';\n        userInput.disabled = false;\n        statusText.textContent = 'Completed';\n        updateTaskButtonsState(); // Update task button state\n        updateSendButtonState(); // Update send button state\n        // Stop HIL checking when task ends\n        stopHILTaskChecking();\n        // Clear HIL state\n        clearHILState();\n        clearToolConfirmationState();\n        // Refresh file list when task completes\n        loadFiles();\n    } else {\n        if (type === 'thinking_start') {\n            removeAllLoadingAnimations();\n            finalizeAgentStream();\n            finalizeReasoningStream();\n            pendingThinkingMeta = { agent };\n            return;\n        }\n\n        if (type === 'token') {\n            removeAllLoadingAnimations();\n            finalizeReasoningStream();\n            finalizeThinkingStream();\n            streamAgentToken(agent, content);\n            return;\n        }\n\n        if (type === 'reasoning_token') {\n            removeAllLoadingAnimations();\n            finalizeAgentStream();\n            finalizeThinkingStream();\n            streamReasoningToken(agent, content);\n            return;\n        }\n\n        if (type === 'thinking_token') {\n            removeAllLoadingAnimations();\n            finalizeAgentStream();\n            finalizeReasoningStream();\n            streamThinkingToken(agent, content);\n            return;\n        }\n\n        if (type === 'thinking_end') {\n            removeAllLoadingAnimations();\n            if (!liveThinkingStream && content) {\n                streamThinkingToken(agent, content);\n            }\n            finalizeThinkingStream();\n            return;\n        }\n\n        finalizeAllLiveStreams();\n        addMessage(agent, type, content, false, true);\n\n        if (type === 'human_in_loop') {\n            currentHILTask = {\n                hil_id: data.hil_id,\n                instruction: data.instruction || content\n            };\n            userInput.disabled = false;\n            userInput.classList.add('hil-waiting');\n            userInput.placeholder = '🔔 ' + (currentHILTask.instruction || 'Waiting for your response...');\n            statusText.textContent = '🔔 HIL Task Waiting';\n            statusText.style.color = '#ff6b6b';\n            updateSendButtonState();\n        } else if (type === 'tool_confirmation') {\n            currentToolConfirmation = {\n                confirm_id: data.confirm_id,\n                tool_name: data.tool_name,\n                arguments: data.arguments || {}\n            };\n            userInput.disabled = false;\n            userInput.classList.add('hil-waiting');\n            userInput.placeholder = `⚠️ Confirm tool \"${currentToolConfirmation.tool_name}\" with yes/no`;\n            statusText.textContent = '⚠️ Tool Confirmation Waiting';\n            statusText.style.color = '#ffd43b';\n            updateSendButtonState();\n        }\n    }\n}\n\nfunction createLiveMessage(agent, type, title) {\n    if (type === 'reasoning' || type === 'thinking') {\n        const wrapper = document.createElement('div');\n        wrapper.className = 'message-thinking';\n        wrapper.innerHTML = `\n            <div class=\"thinking-card\">\n                <details open>\n                    <summary>${escapeHtml(title || agent)}</summary>\n                    <div class=\"thinking-content\"></div>\n                </details>\n            </div>\n        `;\n        messagesContainer.appendChild(wrapper);\n        scrollToBottom();\n        return {\n            wrapper,\n            textDiv: wrapper.querySelector('.thinking-content'),\n            summaryEl: wrapper.querySelector('summary'),\n            detailsEl: wrapper.querySelector('details'),\n            agent\n        };\n    }\n\n    const messageDiv = document.createElement('div');\n    messageDiv.className = `message agent type-${type}`;\n\n    const avatar = document.createElement('div');\n    avatar.className = 'message-avatar';\n    avatar.style.background = getAgentColor(agent);\n    avatar.innerHTML = agentAvatars[agent] || agentAvatars['default'];\n    messageDiv.appendChild(avatar);\n\n    const contentDiv = document.createElement('div');\n    contentDiv.className = 'message-content';\n\n    const header = document.createElement('div');\n    header.className = 'message-header';\n\n    const agentSpan = document.createElement('span');\n    agentSpan.className = 'message-agent';\n    agentSpan.textContent = title || agent;\n    header.appendChild(agentSpan);\n    contentDiv.appendChild(header);\n\n    const textDiv = document.createElement('div');\n    textDiv.className = 'message-text';\n    contentDiv.appendChild(textDiv);\n\n    messageDiv.appendChild(contentDiv);\n    messagesContainer.appendChild(messageDiv);\n    scrollToBottom();\n    return { wrapper: messageDiv, textDiv, agent };\n}\n\nfunction renderLiveText(textDiv, text) {\n    if (!textDiv) return;\n    const escaped = escapeHtml(String(text || ''));\n    textDiv.innerHTML = replaceEmojiWithIcons(escaped);\n}\n\nfunction scrollToBottom() {\n    if (!messagesContainer) return;\n    requestAnimationFrame(() => {\n        messagesContainer.scrollTop = messagesContainer.scrollHeight;\n    });\n}\n\nfunction startThinkingStream(agent) {\n    if (!liveThinkingStream) {\n        liveThinkingStream = createLiveMessage(agent, 'thinking', `${agent} · Thinking`);\n        liveThinkingStream.text = '';\n    }\n}\n\nfunction ensureReasoningStream(agent) {\n    if (!liveReasoningStream) {\n        liveReasoningStream = createLiveMessage(agent, 'reasoning', `${agent} · Model Reasoning`);\n        liveReasoningStream.text = '';\n    }\n}\n\nfunction hasMeaningfulText(text) {\n    return String(text || '').trim().length > 0;\n}\n\nfunction pruneEmptyThinkingCards() {\n    const cards = messagesContainer.querySelectorAll('.message-thinking');\n    cards.forEach(card => {\n        const content = card.querySelector('.thinking-content');\n        if (content && !String(content.textContent || '').trim()) {\n            card.remove();\n        }\n    });\n}\n\nfunction streamAgentToken(agent, text) {\n    if (!text) return;\n    if (!liveAgentStream) {\n        liveAgentStream = createLiveMessage(agent, 'info', agent);\n        liveAgentStream.text = '';\n    }\n    liveAgentStream.text += text;\n    liveAgentStream.textDiv.textContent = liveAgentStream.text;\n    scrollToBottom();\n}\n\nfunction finalizeAgentStream() {\n    if (!liveAgentStream) return;\n    if (liveAgentStream.text) {\n        renderLiveText(liveAgentStream.textDiv, liveAgentStream.text);\n        saveChatMessage(liveAgentStream.agent, 'info', liveAgentStream.text, false);\n    } else {\n        liveAgentStream.wrapper.remove();\n    }\n    liveAgentStream = null;\n}\n\nfunction streamReasoningToken(agent, text) {\n    if (!text) return;\n    const nextText = `${liveReasoningStream?.text || ''}${text}`;\n    if (!liveReasoningStream && !hasMeaningfulText(nextText)) return;\n    ensureReasoningStream(agent);\n    liveReasoningStream.text += text;\n    liveReasoningStream.textDiv.textContent = liveReasoningStream.text;\n    scrollToBottom();\n}\n\nfunction finalizeReasoningStream() {\n    if (!liveReasoningStream) return;\n    if (hasMeaningfulText(liveReasoningStream.text)) {\n        renderLiveText(liveReasoningStream.textDiv, liveReasoningStream.text);\n        saveChatMessage(liveReasoningStream.agent, 'reasoning', liveReasoningStream.text, false);\n        if (liveReasoningStream.detailsEl) liveReasoningStream.detailsEl.open = false;\n        if (liveReasoningStream.summaryEl) liveReasoningStream.summaryEl.textContent = 'Model Reasoning (click to expand)';\n    } else {\n        liveReasoningStream.wrapper.remove();\n    }\n    liveReasoningStream = null;\n}\n\nfunction streamThinkingToken(agent, text) {\n    if (!text) return;\n    const nextText = `${liveThinkingStream?.text || ''}${text}`;\n    if (!liveThinkingStream && !hasMeaningfulText(nextText)) return;\n    startThinkingStream(agent);\n    liveThinkingStream.text += text;\n    liveThinkingStream.textDiv.textContent = liveThinkingStream.text;\n    scrollToBottom();\n}\n\nfunction finalizeThinkingStream() {\n    if (!liveThinkingStream) return;\n    if (hasMeaningfulText(liveThinkingStream.text)) {\n        renderLiveText(liveThinkingStream.textDiv, liveThinkingStream.text);\n        saveChatMessage(liveThinkingStream.agent, 'thinking', liveThinkingStream.text, false);\n        if (liveThinkingStream.detailsEl) liveThinkingStream.detailsEl.open = false;\n        if (liveThinkingStream.summaryEl) liveThinkingStream.summaryEl.textContent = 'Thinking (click to expand)';\n    } else {\n        liveThinkingStream.wrapper.remove();\n    }\n    liveThinkingStream = null;\n}\n\nfunction finalizeAllLiveStreams() {\n    finalizeAgentStream();\n    finalizeReasoningStream();\n    finalizeThinkingStream();\n    pendingThinkingMeta = null;\n    pendingReasoningMeta = null;\n}\n\n// 移除所有消息的加载动画\nfunction removeAllLoadingAnimations() {\n    const loadingMessages = messagesContainer.querySelectorAll('.message.loading');\n    loadingMessages.forEach(msg => {\n        msg.classList.remove('loading');\n    });\n}\n\n// 添加消息到界面\nfunction addMessage(agent, type, content, isUser = false, saveToHistory = true) {\n    // 如果是新消息且任务正在运行，移除之前消息的加载动画\n    if (isRunning && !isUser) {\n        removeAllLoadingAnimations();\n    }\n    \n    const messageDiv = document.createElement('div');\n    // Add different class based on whether it is user message\n    const messageClass = isUser ? 'user' : 'agent';\n    messageDiv.className = `message ${messageClass} type-${type}`;\n    \n    // 如果任务正在运行且不是用户消息，添加加载动画\n    if (isRunning && !isUser) {\n        messageDiv.classList.add('loading');\n    }\n    \n    // Avatar\n    const avatar = document.createElement('div');\n    avatar.className = 'message-avatar';\n    if (isUser) {\n        // 用户头像\n        avatar.innerHTML = '<i class=\"fas fa-user\"></i>';\n        avatar.style.background = 'linear-gradient(135deg, #4ec9b0 0%, #38f9d7 100%)';\n    } else {\n        // Agent 头像\n        avatar.style.background = getAgentColor(agent);\n        avatar.innerHTML = agentAvatars[agent] || agentAvatars['default'];\n    }\n    messageDiv.appendChild(avatar);\n    \n    // 内容\n    const contentDiv = document.createElement('div');\n    contentDiv.className = 'message-content';\n    \n    // 头部\n    const header = document.createElement('div');\n    header.className = 'message-header';\n    \n    const agentSpan = document.createElement('span');\n    agentSpan.className = 'message-agent';\n    agentSpan.textContent = agent;\n    header.appendChild(agentSpan);\n    \n    // Timestamp display removed for privacy\n    // const timeSpan = document.createElement('span');\n    // timeSpan.className = 'message-time';\n    // timeSpan.textContent = new Date().toLocaleTimeString('zh-CN');\n    // header.appendChild(timeSpan);\n    \n    contentDiv.appendChild(header);\n    \n    // 文本（美化显示）\n    const textDiv = document.createElement('div');\n    textDiv.className = 'message-text';\n    \n    // 美化内容\n    let displayContent = content;\n    const normalizedType = String(type || '').trim().toLowerCase();\n    \n    if (typeof displayContent === 'string') {\n        // 1. 先处理转义字符：将字符串形式的转义字符转换为实际字符\n        // 注意：顺序很重要，先处理复合转义序列，再处理简单转义\n        // 可能需要循环处理，因为可能有双重转义的情况\n        \n        let previousContent = '';\n        // 循环处理，直到没有更多转义字符需要处理\n        while (displayContent !== previousContent) {\n            previousContent = displayContent;\n            \n            // 先处理换行符（复合序列，按长度从长到短）\n            displayContent = displayContent.replace(/\\\\r\\\\n/g, '\\r\\n');\n            displayContent = displayContent.replace(/\\\\n/g, '\\n');\n            displayContent = displayContent.replace(/\\\\r/g, '\\r');\n            // 处理转义的制表符\n            displayContent = displayContent.replace(/\\\\t/g, '\\t');\n            // 处理转义的双引号（优先处理，因为代码中常见）\n            displayContent = displayContent.replace(/\\\\\"/g, '\"');\n            // 处理转义的单引号\n            displayContent = displayContent.replace(/\\\\'/g, \"'\");\n            // 处理行尾的反斜杠（用于续行）\n            displayContent = displayContent.replace(/\\\\\\s*\\n/g, '\\n');\n            // 处理其他转义字符\n            displayContent = displayContent.replace(/\\\\f/g, '\\f');\n            displayContent = displayContent.replace(/\\\\b/g, '\\b');\n            displayContent = displayContent.replace(/\\\\v/g, '\\v');\n            // 最后处理转义的反斜杠（单独的反斜杠，不是转义序列的一部分）\n            // 使用负向前瞻，确保不是转义序列的一部分\n            displayContent = displayContent.replace(/\\\\(?![nrtfbv\"'\\\\])/g, '');\n        }\n        \n        // 2. 去除 markdown 格式的加粗标记 **XXX** -> XXX\n        // 先处理双星号（加粗），使用非贪婪匹配\n        displayContent = displayContent.replace(/\\*\\*([^*]+?)\\*\\*/g, '$1');\n        // 再处理单星号（斜体），但要避免匹配已经处理过的和数学表达式\n        // 只匹配不在代码块中的单星号\n        displayContent = displayContent.replace(/(?<![*\\\\])\\*([^*\\n]+?)\\*(?![*])/g, '$1');\n    }\n\n    if ((normalizedType === 'thinking' || normalizedType === 'reasoning') && (!String(displayContent || '').trim() || isThinkingPlaceholderMessage({ type, content: displayContent }))) {\n        return;\n    }\n    \n    // 如果是参数或 final_output 类型，去掉 { } 并美化\n    if (type === 'params' || type === 'final_output') {\n        // 移除 \"参数:\" 或 \"final_output:\" 前缀\n        displayContent = displayContent.replace(/^📋\\s*参数:\\s*/i, '');\n        displayContent = displayContent.replace(/^final_output:\\s*/i, '');\n        \n        // 去掉所有的 { } 字符\n        displayContent = displayContent.replace(/\\{|\\}/g, '');\n        \n        // 清理多余的空白和换行（保留单个换行）\n        displayContent = displayContent.replace(/\\n\\s*\\n\\s*\\n/g, '\\n\\n'); // 多个连续换行（3个以上）合并为两个\n        displayContent = displayContent.replace(/^\\s+|\\s+$/gm, ''); // 去掉每行首尾空白\n        // 对于 final_output，确保调用信息和结果之间有换行\n        if (type === 'final_output') {\n            // 如果调用信息和结果连在一起（没有换行），添加换行\n            // 匹配模式：工具调用信息后直接跟文本（没有换行）\n            displayContent = displayContent.replace(/(\\] calls tool: final_output)([^\\n])/g, '$1\\n\\n$2');\n        }\n        displayContent = displayContent.trim();\n    }\n    \n    // 先转义 HTML 以确保安全性\n    const escapedContent = escapeHtml(displayContent);\n    \n    // 然后替换 emoji 为图标（在转义之后，这样图标标签不会被转义）\n    // 注意：转义后的 emoji 仍然是原样，所以可以直接替换\n    const finalContent = replaceEmojiWithIcons(escapedContent);\n    \n    textDiv.innerHTML = finalContent;\n    contentDiv.appendChild(textDiv);\n    \n    messageDiv.appendChild(contentDiv);\n    \n    // 添加到容器\n    messagesContainer.appendChild(messageDiv);\n    \n    // Scroll to bottom\n    messagesContainer.scrollTop = messagesContainer.scrollHeight;\n    \n    // 保存到聊天记录（如果需要）\n    // 🔧 保存用户看到的内容（美化后的），而不是原始内容\n    if (saveToHistory) {\n        saveChatMessage(agent, type, displayContent, isUser);\n    }\n}\n\n// 渲染消息（不保存到历史记录，用于加载历史记录时使用）\nfunction renderMessage(agent, type, content, isUser, saveToHistory = false) {\n    addMessage(agent, type, content, isUser, saveToHistory);\n}\n\n// 显示系统消息（保存到历史记录，因为用户看到了）\nfunction showMessage(agent, type, content) {\n    addMessage(agent, type, content, false, true);\n}\n\n// HIL (Human-in-Loop) Task Management\n\n// Start checking for HIL tasks\nfunction startHILTaskChecking() {\n    // Clear any existing interval\n    stopHILTaskChecking();\n    \n    // Use longer polling interval (10 seconds) as fallback\n    // Most checks will be triggered by tool_call events, so we don't need frequent polling\n    hilCheckInterval = setInterval(checkHILTask, 10000);\n}\n\n// Stop checking for HIL tasks\nfunction stopHILTaskChecking() {\n    if (hilCheckInterval) {\n        clearInterval(hilCheckInterval);\n        hilCheckInterval = null;\n    }\n}\n\n// Check for pending HIL tasks\nasync function checkHILTask() {\n    // Only check when task is running\n    if (!isRunning) {\n        return;\n    }\n    \n    const taskId = taskIdInput.value.trim();\n    if (!taskId) {\n        return;\n    }\n    \n    try {\n        const response = await fetch('/api/hil/check', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({ task_id: taskId })\n        });\n        \n        const data = await response.json();\n        \n        if (data.found && data.hil_id) {\n            // New HIL task detected\n            if (!currentHILTask || currentHILTask.hil_id !== data.hil_id) {\n                currentHILTask = {\n                    hil_id: data.hil_id,\n                    instruction: data.instruction\n                };\n                \n                // Enable input and button, show red blinking effect\n                userInput.disabled = false;\n                userInput.classList.add('hil-waiting');\n                userInput.placeholder = '🔔 ' + (data.instruction || 'Waiting for your response...');\n                updateSendButtonState();\n                \n                // Show status message\n                statusText.textContent = '🔔 HIL Task Waiting';\n                statusText.style.color = '#ff6b6b';\n                \n                // Once HIL task is found, check more frequently (every 2 seconds) until responded\n                // This ensures we don't miss the completion or status changes\n                stopHILTaskChecking();\n                hilCheckInterval = setInterval(checkHILTask, 2000);\n            }\n        } else {\n            // No HIL task, clear state if previously set\n            if (currentHILTask) {\n                clearHILState();\n                // Reset to slower polling once HIL is cleared\n                stopHILTaskChecking();\n                hilCheckInterval = setInterval(checkHILTask, 10000);\n            }\n        }\n    } catch (error) {\n        // Silently fail - the backend may be unavailable during polling\n        console.error('Check HIL task failed:', error);\n    }\n}\n\n// Respond to HIL task\nasync function respondToHILTask(responseText) {\n    if (!currentHILTask) {\n        return;\n    }\n    \n    const hilId = currentHILTask.hil_id;\n    \n    try {\n        // Add user message to chat\n        addMessage('user', 'user', responseText, true, true);\n        \n        // Send HIL response\n        const response = await fetch('/api/hil/respond', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                hil_id: hilId,\n                response: responseText\n            })\n        });\n        \n        const data = await response.json();\n        \n        if (data.success) {\n            // Clear input\n            userInput.value = '';\n            \n            // Clear HIL state\n            clearHILState();\n            \n            // Show success message\n            statusText.textContent = '✅ HIL Response Sent';\n            statusText.style.color = '#51cf66';\n            setTimeout(() => {\n                if (isRunning) {\n                    statusText.textContent = 'Running...';\n                    statusText.style.color = '';\n                }\n            }, 2000);\n        } else {\n            alert(`Failed to respond to HIL task: ${data.error || 'Unknown error'}`);\n        }\n    } catch (error) {\n        alert(`Failed to respond to HIL task: ${error.message}`);\n    }\n}\n\n// Respond to tool confirmation\nasync function respondToToolConfirmation(approved) {\n    if (!currentToolConfirmation) {\n        return;\n    }\n\n    try {\n        const responseText = userInput.value.trim();\n        addMessage('user', 'user', responseText, true, true);\n\n        const response = await fetch('/api/tool-confirm/respond', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                confirm_id: currentToolConfirmation.confirm_id,\n                approved\n            })\n        });\n\n        const data = await response.json();\n        if (!data.success) {\n            alert(`Failed to respond to tool confirmation: ${data.error || 'Unknown error'}`);\n            return;\n        }\n\n        userInput.value = '';\n        clearToolConfirmationState();\n        statusText.textContent = approved ? '✅ Tool approved' : '❌ Tool rejected';\n        statusText.style.color = approved ? '#51cf66' : '#ff6b6b';\n        setTimeout(() => {\n            if (isRunning) {\n                statusText.textContent = 'Running...';\n                statusText.style.color = '';\n            }\n        }, 2000);\n    } catch (error) {\n        alert(`Failed to respond to tool confirmation: ${error.message}`);\n    }\n}\n\n// Clear HIL state\nfunction clearHILState() {\n    currentHILTask = null;\n    userInput.classList.remove('hil-waiting');\n    userInput.placeholder = 'Enter task description...';\n    userInput.disabled = isRunning;  // Disable if task is running (and no HIL)\n    updateSendButtonState();\n    statusText.style.color = '';\n    \n    // Reset polling interval to slower rate when HIL is cleared\n    if (isRunning) {\n        stopHILTaskChecking();\n        hilCheckInterval = setInterval(checkHILTask, 10000);\n    }\n}\n\nfunction clearToolConfirmationState() {\n    currentToolConfirmation = null;\n    userInput.classList.remove('hil-waiting');\n    userInput.placeholder = 'Enter task description...';\n    userInput.disabled = isRunning;\n    updateSendButtonState();\n    statusText.style.color = '';\n}\n\n// Configuration Modal Functions\nlet currentConfigFile = 'llm_config.yaml';\nlet currentConfigType = 'run_env'; // 'run_env' or 'agent'\nlet lastLoadedGuidedLlmConfig = {};\nlet lastLoadedGuidedAppConfig = {};\n\nconst MODEL_EDITOR_SLOT_CONFIG_KEYS = {\n    shared: null,\n    main: 'models',\n    read: 'read_figure_models',\n    figure: 'figure_models',\n    compressor: 'compressor_models',\n    thinking: 'thinking_models'\n};\n\nconst MODEL_EDITOR_PROVIDER_OPTIONS = `\n    <option value=\"openrouter\">OpenRouter</option>\n    <option value=\"openai_compatible\">OpenAI-compatible API</option>\n    <option value=\"openai_official\">OpenAI Official</option>\n    <option value=\"google_official\">Google Official</option>\n    <option value=\"anthropic_official\">Anthropic Official</option>\n    <option value=\"local_openai_compatible\">Local / Keyless OpenAI-compatible</option>\n`;\n\nlet modelEditorEntryCounter = 0;\nlet modelEditorState = createEmptyModelEditorState();\n\nfunction getActiveConfigTabName() {\n    return document.querySelector('.config-tab.active')?.dataset?.tab || 'guided';\n}\n\nfunction readPositiveNumber(value, fallback) {\n    const parsed = Number(value);\n    return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nfunction readNonNegativeNumber(value, fallback) {\n    const parsed = Number(value);\n    return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;\n}\n\nfunction createEmptyModelEditorState() {\n    return {\n        shared: [],\n        main: [],\n        read: [],\n        figure: [],\n        compressor: [],\n        thinking: []\n    };\n}\n\nfunction nextModelEditorId() {\n    modelEditorEntryCounter += 1;\n    return `guided-model-entry-${modelEditorEntryCounter}`;\n}\n\nfunction inferModelProviderKind(modelName, entryBaseUrl, globalBaseUrl, hasApiKey) {\n    const name = String(modelName || '').trim();\n    const effectiveBaseUrl = String(entryBaseUrl || globalBaseUrl || '').trim().toLowerCase();\n    if (name.startsWith('openrouter/')) return 'openrouter';\n    if (effectiveBaseUrl.includes('openrouter.ai')) return 'openrouter';\n    if (name.startsWith('google/')) return 'google_official';\n    if (name.startsWith('anthropic/')) return 'anthropic_official';\n    if (name.startsWith('openai/')) {\n        if (entryBaseUrl) return hasApiKey ? 'openai_compatible' : 'local_openai_compatible';\n        return 'openai_official';\n    }\n    if (entryBaseUrl) return hasApiKey ? 'openai_compatible' : 'local_openai_compatible';\n    return 'openai_official';\n}\n\nfunction stripModelNameForProvider(providerKind, modelName, entryBaseUrl, globalBaseUrl) {\n    let name = String(modelName || '').trim();\n    const effectiveBaseUrl = String(entryBaseUrl || globalBaseUrl || '').trim().toLowerCase();\n    if (!name) return '';\n    if (providerKind === 'openrouter') {\n        if (name.startsWith('openrouter/')) return name.slice('openrouter/'.length);\n        if (effectiveBaseUrl.includes('openrouter.ai') && name.startsWith('openai/') && name.slice('openai/'.length).includes('/')) {\n            return name.slice('openai/'.length);\n        }\n        return name;\n    }\n    if (providerKind === 'google_official' && name.startsWith('google/')) return name.slice('google/'.length);\n    if (providerKind === 'anthropic_official' && name.startsWith('anthropic/')) return name.slice('anthropic/'.length);\n    if (name.startsWith('openai/')) return name.slice('openai/'.length);\n    return name;\n}\n\nfunction normalizeModelNameForProvider(providerKind, modelName) {\n    const raw = String(modelName || '').trim();\n    if (!raw) return '';\n    if (providerKind === 'openrouter') {\n        return raw.startsWith('openrouter/') ? raw : `openrouter/${raw}`;\n    }\n    const expectedPrefix = {\n        openai_compatible: 'openai/',\n        openai_official: 'openai/',\n        google_official: 'google/',\n        anthropic_official: 'anthropic/',\n        local_openai_compatible: 'openai/'\n    }[providerKind] || 'openai/';\n    if (raw.startsWith(expectedPrefix)) return raw;\n    return `${expectedPrefix}${raw.replace(/^(openrouter|openai|google|anthropic)\\//, '')}`;\n}\n\nfunction makeBlankModelEditorEntry() {\n    return {\n        id: nextModelEditorId(),\n        provider: 'openrouter',\n        model: '',\n        source: 'default',\n        base_url: '',\n        api_key: '',\n        tool_choice: ''\n    };\n}\n\nfunction deserializeModelEditorEntry(rawEntry, globalBaseUrl) {\n    const isObject = rawEntry && typeof rawEntry === 'object' && !Array.isArray(rawEntry);\n    const modelName = isObject ? String(rawEntry.name || '') : String(rawEntry || '');\n    const baseUrl = isObject ? String(rawEntry.base_url || '') : '';\n    const apiKey = isObject ? String(rawEntry.api_key || '') : '';\n    const toolChoice = isObject ? String(rawEntry.tool_choice || '') : '';\n    const provider = inferModelProviderKind(modelName, baseUrl, globalBaseUrl, !!apiKey);\n    return {\n        id: nextModelEditorId(),\n        provider,\n        model: stripModelNameForProvider(provider, modelName, baseUrl, globalBaseUrl),\n        source: (baseUrl || apiKey) ? 'custom' : 'default',\n        base_url: baseUrl,\n        api_key: apiKey,\n        tool_choice: toolChoice\n    };\n}\n\nfunction serializeModelEditorComparable(entry) {\n    return JSON.stringify({\n        provider: String(entry?.provider || '').trim(),\n        model: String(entry?.model || '').trim(),\n        source: String(entry?.source || 'default').trim(),\n        base_url: String(entry?.base_url || '').trim(),\n        api_key: String(entry?.api_key || '').trim(),\n        tool_choice: String(entry?.tool_choice || '').trim()\n    });\n}\n\nfunction cloneModelEditorEntry(entry) {\n    return {\n        id: nextModelEditorId(),\n        provider: entry.provider,\n        model: entry.model,\n        source: entry.source,\n        base_url: entry.base_url,\n        api_key: entry.api_key,\n        tool_choice: entry.tool_choice\n    };\n}\n\nfunction computeSharedModelEntries(slotEntries) {\n    const orderedBase = slotEntries.main || [];\n    if (!orderedBase.length) return [];\n    const otherSlots = ['read', 'figure', 'compressor', 'thinking'];\n    return orderedBase\n        .filter((entry) => otherSlots.every((slot) => (slotEntries[slot] || []).some((candidate) => serializeModelEditorComparable(candidate) === serializeModelEditorComparable(entry))))\n        .map((entry) => cloneModelEditorEntry(entry));\n}\n\nfunction createModelEntryPayload(entry) {\n    const resolvedName = normalizeModelNameForProvider(entry.provider, entry.model);\n    if (!resolvedName) return null;\n    const sourceMode = entry.source === 'custom' ? 'custom' : 'default';\n    const payload = { name: resolvedName };\n    if (sourceMode === 'custom' && String(entry.base_url || '').trim()) payload.base_url = String(entry.base_url || '').trim();\n    if (sourceMode === 'custom' && String(entry.api_key || '').trim()) payload.api_key = String(entry.api_key || '').trim();\n    if (String(entry.tool_choice || '').trim()) payload.tool_choice = String(entry.tool_choice || '').trim();\n    return Object.keys(payload).length === 1 ? payload.name : payload;\n}\n\nfunction buildGuidedLlmConfig() {\n    const config = { ...(lastLoadedGuidedLlmConfig || {}) };\n    config.temperature = Number(document.getElementById('guided-temperature')?.value) || 0;\n    config.max_tokens = Number(document.getElementById('guided-max-tokens')?.value) || 0;\n    config.max_context_window = Number(document.getElementById('guided-max-context')?.value) || 500000;\n    config.base_url = document.getElementById('guided-base-url')?.value?.trim() || '';\n    config.api_key = document.getElementById('guided-api-key')?.value?.trim() || '';\n    config.timeout = Number(document.getElementById('guided-timeout')?.value) || 600;\n    config.stream_timeout = Number(document.getElementById('guided-stream-timeout')?.value) || 30;\n    config.first_chunk_timeout = Number(document.getElementById('guided-first-chunk-timeout')?.value) || 30;\n    config.multimodal = !!document.getElementById('guided-multimodal')?.checked;\n    config.compressor_multimodal = !!document.getElementById('guided-compressor-multimodal')?.checked;\n\n    const sharedPayload = modelEditorState.shared.map(createModelEntryPayload).filter(Boolean);\n    Object.entries(MODEL_EDITOR_SLOT_CONFIG_KEYS).forEach(([slotKey, configKey]) => {\n        if (!configKey) return;\n        const slotPayload = (modelEditorState[slotKey] || []).map(createModelEntryPayload).filter(Boolean);\n        config[configKey] = [...sharedPayload, ...slotPayload];\n    });\n    return config;\n}\n\nfunction getModelEditorEntry(slotKey, entryId) {\n    return (modelEditorState[slotKey] || []).find((entry) => entry.id === entryId);\n}\n\nfunction renderModelEditorEntry(slotKey, entry) {\n    const resolvedName = normalizeModelNameForProvider(entry.provider, entry.model);\n    const customVisible = entry.source === 'custom' ? '' : 'display:none;';\n    return `\n        <div class=\"model-entry-card\" data-slot=\"${slotKey}\" data-id=\"${entry.id}\">\n            <div class=\"model-entry-topbar\">\n                <div class=\"form-group form-half\">\n                    <label class=\"form-label\">Provider</label>\n                    <select class=\"form-input\" data-model-field=\"provider\">\n                        ${MODEL_EDITOR_PROVIDER_OPTIONS}\n                    </select>\n                </div>\n                <div class=\"form-group form-half\">\n                    <label class=\"form-label\">Source</label>\n                    <select class=\"form-input\" data-model-field=\"source\">\n                        <option value=\"default\">Use default URL / Key</option>\n                        <option value=\"custom\">Custom URL / Key</option>\n                    </select>\n                </div>\n                <div class=\"form-group form-half\">\n                    <label class=\"form-label\">Tool Choice</label>\n                    <select class=\"form-input\" data-model-field=\"tool_choice\">\n                        <option value=\"\">Default</option>\n                        <option value=\"required\">required</option>\n                        <option value=\"auto\">auto</option>\n                        <option value=\"none\">none</option>\n                    </select>\n                </div>\n                <div class=\"model-entry-actions\">\n                    <button class=\"btn-secondary\" type=\"button\" data-model-action=\"delete\">Delete</button>\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <label class=\"form-label\">Model Name</label>\n                <input type=\"text\" class=\"form-input\" data-model-field=\"model\" placeholder=\"For OpenRouter use vendor/model, e.g. google/gemini-3-flash-preview\" value=\"${escapeHtml(entry.model)}\">\n                <div class=\"model-entry-preview\">Resolved model id: <code>${escapeHtml(resolvedName || '(empty)')}</code></div>\n            </div>\n            <div class=\"form-row model-entry-custom-source\" style=\"${customVisible}\">\n                <div class=\"form-group form-half\">\n                    <label class=\"form-label\">Custom Base URL</label>\n                    <input type=\"text\" class=\"form-input\" data-model-field=\"base_url\" placeholder=\"https://...\" value=\"${escapeHtml(entry.base_url)}\">\n                </div>\n                <div class=\"form-group form-half\">\n                    <label class=\"form-label\">Custom API Key</label>\n                    <input type=\"text\" class=\"form-input\" data-model-field=\"api_key\" placeholder=\"sk-...\" value=\"${escapeHtml(entry.api_key)}\">\n                </div>\n            </div>\n        </div>\n    `;\n}\n\nfunction renderModelEditorSlot(slotKey) {\n    const container = document.getElementById(`model-${slotKey}-list`);\n    if (!container) return;\n    const entries = modelEditorState[slotKey] || [];\n    if (!entries.length) {\n        container.innerHTML = '<div class=\"model-slot-empty\">No models configured for this section.</div>';\n        return;\n    }\n    container.innerHTML = entries.map((entry) => renderModelEditorEntry(slotKey, entry)).join('');\n    entries.forEach((entry) => {\n        const card = container.querySelector(`[data-id=\"${entry.id}\"]`);\n        if (!card) return;\n        const providerEl = card.querySelector('[data-model-field=\"provider\"]');\n        const sourceEl = card.querySelector('[data-model-field=\"source\"]');\n        const toolChoiceEl = card.querySelector('[data-model-field=\"tool_choice\"]');\n        if (providerEl) providerEl.value = entry.provider;\n        if (sourceEl) sourceEl.value = entry.source;\n        if (toolChoiceEl) toolChoiceEl.value = entry.tool_choice || '';\n    });\n}\n\nfunction renderAllModelEditorSlots() {\n    ['shared', 'main', 'read', 'figure', 'compressor', 'thinking'].forEach(renderModelEditorSlot);\n}\n\nfunction loadGuidedModelSettings(config) {\n    const globalBaseUrl = String(config?.base_url || '').trim();\n    const parsedSlots = {\n        main: Array.isArray(config?.models) ? config.models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n        read: Array.isArray(config?.read_figure_models) ? config.read_figure_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n        figure: Array.isArray(config?.figure_models) ? config.figure_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n        compressor: Array.isArray(config?.compressor_models) ? config.compressor_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : [],\n        thinking: Array.isArray(config?.thinking_models) ? config.thinking_models.map((item) => deserializeModelEditorEntry(item, globalBaseUrl)) : []\n    };\n    const shared = computeSharedModelEntries(parsedSlots);\n    const sharedKeys = new Set(shared.map((entry) => serializeModelEditorComparable(entry)));\n    modelEditorState = {\n        shared,\n        main: parsedSlots.main.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n        read: parsedSlots.read.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n        figure: parsedSlots.figure.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n        compressor: parsedSlots.compressor.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry),\n        thinking: parsedSlots.thinking.filter((entry) => !sharedKeys.has(serializeModelEditorComparable(entry))).map(cloneModelEditorEntry)\n    };\n    renderAllModelEditorSlots();\n}\n\nfunction addModelEditorEntry(slotKey) {\n    if (!modelEditorState[slotKey]) return;\n    modelEditorState[slotKey].push(makeBlankModelEditorEntry());\n    renderModelEditorSlot(slotKey);\n}\n\nfunction bindModelEditorList(slotKey) {\n    const container = document.getElementById(`model-${slotKey}-list`);\n    if (!container) return;\n    container.addEventListener('click', (event) => {\n        const button = event.target.closest('[data-model-action=\"delete\"]');\n        if (!button) return;\n        const card = button.closest('.model-entry-card');\n        if (!card) return;\n        const entryId = card.dataset.id;\n        modelEditorState[slotKey] = (modelEditorState[slotKey] || []).filter((entry) => entry.id !== entryId);\n        renderModelEditorSlot(slotKey);\n    });\n    container.addEventListener('input', (event) => {\n        const field = event.target?.dataset?.modelField;\n        if (!field) return;\n        const card = event.target.closest('.model-entry-card');\n        if (!card) return;\n        const entry = getModelEditorEntry(slotKey, card.dataset.id);\n        if (!entry) return;\n        entry[field] = event.target.value;\n        if (field === 'model' || field === 'base_url' || field === 'api_key') {\n            const preview = card.querySelector('.model-entry-preview code');\n            if (preview) preview.textContent = normalizeModelNameForProvider(entry.provider, entry.model) || '(empty)';\n        }\n    });\n    container.addEventListener('change', (event) => {\n        const field = event.target?.dataset?.modelField;\n        if (!field) return;\n        const card = event.target.closest('.model-entry-card');\n        if (!card) return;\n        const entry = getModelEditorEntry(slotKey, card.dataset.id);\n        if (!entry) return;\n        entry[field] = event.target.value;\n        if (field === 'source' || field === 'provider') {\n            renderModelEditorSlot(slotKey);\n        }\n    });\n}\n\nfunction buildGuidedAppConfig() {\n    const base = { ...(lastLoadedGuidedAppConfig || {}) };\n    base.env = { ...(base.env || {}) };\n    base.runtime = { ...(base.runtime || {}) };\n    base.context = { ...(base.context || {}) };\n    base.mcp = { ...(base.mcp || {}) };\n    base.market = { ...(base.market || {}) };\n\n    const thinkingEnabled = !!document.getElementById('guided-thinking-enabled')?.checked;\n    const thinkingSteps = readPositiveNumber(document.getElementById('guided-thinking-steps')?.value, 30);\n    const visibleSkills = String(document.getElementById('guided-visible-skills')?.value || '')\n        .split('\\n')\n        .map((line) => line.trim())\n        .filter(Boolean);\n\n    base.runtime.action_window_steps = thinkingSteps;\n    base.runtime.thinking_interval = thinkingSteps;\n    base.runtime.thinking_enabled = thinkingEnabled;\n    base.runtime.thinking_steps = thinkingSteps;\n    base.runtime.no_tool_retry_limit = readPositiveNumber(document.getElementById('guided-no-tool-retry-limit')?.value, 7);\n    base.runtime.max_turns = readPositiveNumber(document.getElementById('guided-max-turns')?.value, 100000);\n    base.runtime.visible_skills = visibleSkills;\n\n    base.context.user_history_compress_threshold_tokens = readNonNegativeNumber(document.getElementById('guided-user-history-threshold')?.value, 1500);\n    base.context.user_history_recent_items = readNonNegativeNumber(document.getElementById('guided-user-history-recent-items')?.value, 0);\n    base.context.structured_call_info_compress_threshold_agents = readPositiveNumber(document.getElementById('guided-structured-call-agent-threshold')?.value, 10);\n    base.context.structured_call_info_compress_threshold_tokens = readNonNegativeNumber(document.getElementById('guided-structured-call-token-threshold')?.value, 2200);\n    return base;\n}\n\nfunction fillGuidedConfig(llmConfig, appConfig) {\n    lastLoadedGuidedLlmConfig = llmConfig || {};\n    lastLoadedGuidedAppConfig = appConfig || {};\n    loadGuidedModelSettings(lastLoadedGuidedLlmConfig);\n\n    document.getElementById('guided-temperature').value = Number(lastLoadedGuidedLlmConfig.temperature ?? 0) || '';\n    document.getElementById('guided-max-tokens').value = Number(lastLoadedGuidedLlmConfig.max_tokens ?? 0) || '';\n    document.getElementById('guided-max-context').value = Number(lastLoadedGuidedLlmConfig.max_context_window ?? 500000) || '';\n    document.getElementById('guided-base-url').value = String(lastLoadedGuidedLlmConfig.base_url || '');\n    document.getElementById('guided-api-key').value = String(lastLoadedGuidedLlmConfig.api_key || '');\n    document.getElementById('guided-timeout').value = Number(lastLoadedGuidedLlmConfig.timeout ?? 600) || '';\n    document.getElementById('guided-stream-timeout').value = Number(lastLoadedGuidedLlmConfig.stream_timeout ?? 30) || '';\n    document.getElementById('guided-first-chunk-timeout').value = Number(lastLoadedGuidedLlmConfig.first_chunk_timeout ?? 30) || '';\n    document.getElementById('guided-multimodal').checked = !!lastLoadedGuidedLlmConfig.multimodal;\n    document.getElementById('guided-compressor-multimodal').checked = !!lastLoadedGuidedLlmConfig.compressor_multimodal;\n\n    const runtime = lastLoadedGuidedAppConfig.runtime || {};\n    const context = lastLoadedGuidedAppConfig.context || {};\n    document.getElementById('guided-thinking-enabled').checked = runtime.thinking_enabled !== false;\n    document.getElementById('guided-thinking-steps').value = Number(runtime.thinking_steps ?? runtime.thinking_interval ?? runtime.action_window_steps ?? 30) || '';\n    document.getElementById('guided-no-tool-retry-limit').value = Number(runtime.no_tool_retry_limit ?? 7) || '';\n    document.getElementById('guided-max-turns').value = Number(runtime.max_turns ?? 100000) || '';\n    document.getElementById('guided-user-history-threshold').value = Number(context.user_history_compress_threshold_tokens ?? 1500) || '';\n    document.getElementById('guided-user-history-recent-items').value = Number(context.user_history_recent_items ?? 0);\n    document.getElementById('guided-structured-call-agent-threshold').value = Number(context.structured_call_info_compress_threshold_agents ?? 10) || '';\n    document.getElementById('guided-structured-call-token-threshold').value = Number(context.structured_call_info_compress_threshold_tokens ?? 2200) || '';\n    document.getElementById('guided-visible-skills').value = Array.isArray(runtime.visible_skills) ? runtime.visible_skills.join('\\n') : '';\n}\n\nasync function loadGuidedConfig() {\n    const statusDiv = document.getElementById('config-status');\n    const fileNameSpan = document.getElementById('config-file-name');\n    fileNameSpan.textContent = 'Guided runtime config';\n    statusDiv.textContent = '';\n    statusDiv.className = 'config-status';\n\n    try {\n        const response = await fetch('/api/config/guided', {\n            credentials: 'include'\n        });\n        const data = await response.json();\n        if (data.error) {\n            statusDiv.textContent = `Error: ${data.error}`;\n            statusDiv.className = 'config-status error';\n            return;\n        }\n        fillGuidedConfig(data.llm_config || {}, data.app_config || {});\n    } catch (error) {\n        statusDiv.textContent = `Failed to load guided config: ${error.message}`;\n        statusDiv.className = 'config-status error';\n    }\n}\n\nasync function saveGuidedConfig() {\n    const statusDiv = document.getElementById('config-status');\n    const saveBtn = document.getElementById('save-config-btn');\n\n    saveBtn.disabled = true;\n    saveBtn.textContent = 'Saving...';\n    statusDiv.textContent = 'Saving...';\n    statusDiv.className = 'config-status';\n\n    try {\n        const response = await fetch('/api/config/guided', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                llm_config: buildGuidedLlmConfig(),\n                app_config: buildGuidedAppConfig(),\n            })\n        });\n        const data = await response.json();\n        if (data.error) {\n            statusDiv.textContent = `Error: ${data.error}`;\n            statusDiv.className = 'config-status error';\n        } else {\n            statusDiv.textContent = data.message || 'Guided configuration saved successfully';\n            statusDiv.className = 'config-status success';\n            await loadConfigFileLists();\n            await loadGuidedConfig();\n        }\n    } catch (error) {\n        statusDiv.textContent = `Failed to save: ${error.message}`;\n        statusDiv.className = 'config-status error';\n    } finally {\n        saveBtn.disabled = false;\n        saveBtn.innerHTML = '<i class=\"fas fa-save\"></i> Save';\n    }\n}\n\n[\n    ['shared', 'add-shared-model-btn'],\n    ['main', 'add-main-model-btn'],\n    ['read', 'add-read-model-btn'],\n    ['figure', 'add-figure-model-btn'],\n    ['compressor', 'add-compressor-model-btn'],\n    ['thinking', 'add-thinking-model-btn']\n].forEach(([slotKey, buttonId]) => {\n    document.getElementById(buttonId)?.addEventListener('click', () => addModelEditorEntry(slotKey));\n    bindModelEditorList(slotKey);\n});\n\n// Open configuration modal\nfunction openConfigModal() {\n    const modal = document.getElementById('config-modal');\n    modal.style.display = 'flex';\n    loadConfigFileLists();\n    loadConfigFile(currentConfigFile, currentConfigType);\n    loadGuidedConfig();\n    switchConfigTab('guided');\n}\n\n// Close configuration modal\nfunction closeConfigModal() {\n    const modal = document.getElementById('config-modal');\n    modal.style.display = 'none';\n}\n\n// Load configuration file lists for both sections\nasync function loadConfigFileLists() {\n    // Load run_env config files\n    try {\n        const runEnvResponse = await fetch('/api/config/list?type=run_env', {\n            credentials: 'include'\n        });\n        const runEnvData = await runEnvResponse.json();\n        \n        const runEnvList = document.getElementById('run-env-config-list');\n        runEnvList.innerHTML = '';\n        \n        if (runEnvData.files && runEnvData.files.length > 0) {\n            let firstFile = null;\n            runEnvData.files.forEach((file, index) => {\n                const item = document.createElement('div');\n                item.className = 'config-file-item';\n                item.dataset.file = file.name;\n                item.dataset.type = 'run_env';\n                \n                // Set icon based on filename\n                let icon = 'fas fa-file-code';\n                if (file.name.includes('llm')) icon = 'fas fa-brain';\n                else if (file.name.includes('app_config')) icon = 'fas fa-sliders-h';\n                else if (file.name.includes('tool')) icon = 'fas fa-tools';\n                else if (file.name.includes('api')) icon = 'fas fa-plug';\n                else if (file.name.includes('gemini')) icon = 'fas fa-robot';\n                \n                item.innerHTML = `<i class=\"${icon}\"></i> ${file.name}`;\n                item.addEventListener('click', () => {\n                    currentConfigFile = file.name;\n                    currentConfigType = 'run_env';\n                    loadConfigFile(file.name, 'run_env');\n                    switchConfigTab('editor');\n                });\n                runEnvList.appendChild(item);\n                \n                // Remember first file\n                if (index === 0) {\n                    firstFile = file.name;\n                }\n            });\n            \n            // Auto-load first file if no file is currently selected\n            if (!currentConfigFile || currentConfigType !== 'run_env') {\n                if (firstFile) {\n                    currentConfigFile = firstFile;\n                    currentConfigType = 'run_env';\n                    loadConfigFile(firstFile, 'run_env');\n                }\n            }\n        } else {\n            runEnvList.innerHTML = '<div class=\"config-file-empty\">No files found</div>';\n        }\n    } catch (error) {\n        console.error('Failed to load run_env config files:', error);\n    }\n    \n    // Load agent config files\n    try {\n        const agentResponse = await fetch(`/api/config/list?type=agent&agent_system=${encodeURIComponent(agentSystem)}`, {\n            credentials: 'include'\n        });\n        const agentData = await agentResponse.json();\n        \n        const agentList = document.getElementById('agent-config-list');\n        agentList.innerHTML = '';\n        \n        if (agentData.files && agentData.files.length > 0) {\n            agentData.files.forEach(file => {\n                const item = document.createElement('div');\n                item.className = 'config-file-item';\n                item.dataset.file = file.name;\n                item.dataset.type = 'agent';\n                \n                // Set icon based on filename\n                let icon = 'fas fa-file-code';\n                if (file.name.includes('level_0')) icon = 'fas fa-wrench';\n                else if (file.name.includes('level_1')) icon = 'fas fa-layer-group';\n                else if (file.name.includes('level_2')) icon = 'fas fa-sitemap';\n                else if (file.name.includes('level_3')) icon = 'fas fa-crown';\n                else if (file.name.includes('judge')) icon = 'fas fa-gavel';\n                else if (file.name.includes('prompts')) icon = 'fas fa-comments';\n                \n                item.innerHTML = `<i class=\"${icon}\"></i> ${file.name}`;\n                item.addEventListener('click', () => {\n                    currentConfigFile = file.name;\n                    currentConfigType = 'agent';\n                    loadConfigFile(file.name, 'agent');\n                    switchConfigTab('editor');\n                });\n                agentList.appendChild(item);\n            });\n        } else {\n            agentList.innerHTML = '<div class=\"config-file-empty\">No files found</div>';\n        }\n    } catch (error) {\n        console.error('Failed to load agent config files:', error);\n    }\n}\n\n// Load configuration file\nasync function loadConfigFile(filename, type = 'run_env') {\n    const textarea = document.getElementById('config-editor-textarea');\n    const fileNameSpan = document.getElementById('config-file-name');\n    const statusDiv = document.getElementById('config-status');\n    \n    // Update active file item\n    document.querySelectorAll('.config-file-item').forEach(item => {\n        item.classList.remove('active');\n        if (item.dataset.file === filename && item.dataset.type === type) {\n            item.classList.add('active');\n        }\n    });\n    \n    fileNameSpan.textContent = filename;\n    textarea.value = 'Loading...';\n    statusDiv.textContent = '';\n    statusDiv.className = 'config-status';\n    \n    try {\n        const response = await fetch(`/api/config/read?file=${encodeURIComponent(filename)}&type=${encodeURIComponent(type)}&agent_system=${encodeURIComponent(agentSystem)}`, {\n            credentials: 'include'\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            textarea.value = '';\n            statusDiv.textContent = `Error: ${data.error}`;\n            statusDiv.className = 'config-status error';\n        } else {\n            textarea.value = data.content;\n            statusDiv.textContent = 'File loaded successfully';\n            statusDiv.className = 'config-status success';\n            setTimeout(() => {\n                statusDiv.textContent = '';\n            }, 2000);\n        }\n    } catch (error) {\n        textarea.value = '';\n        statusDiv.textContent = `Failed to load file: ${error.message}`;\n        statusDiv.className = 'config-status error';\n    }\n}\n\n// Save configuration file\nasync function saveConfigFile() {\n    if (getActiveConfigTabName() === 'guided') {\n        await saveGuidedConfig();\n        return;\n    }\n    const textarea = document.getElementById('config-editor-textarea');\n    const fileNameSpan = document.getElementById('config-file-name');\n    const statusDiv = document.getElementById('config-status');\n    const saveBtn = document.getElementById('save-config-btn');\n    \n    const filename = fileNameSpan.textContent;\n    const content = textarea.value;\n    \n    saveBtn.disabled = true;\n    saveBtn.textContent = 'Saving...';\n    statusDiv.textContent = 'Saving...';\n    statusDiv.className = 'config-status';\n    \n    try {\n        const response = await fetch('/api/config/save', {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json'\n            },\n            credentials: 'include',\n            body: JSON.stringify({\n                file: filename,\n                content: content,\n                type: currentConfigType,\n                agent_system: agentSystem\n            })\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            statusDiv.textContent = `Error: ${data.error}`;\n            statusDiv.className = 'config-status error';\n        } else {\n            statusDiv.textContent = data.message || 'Configuration saved successfully';\n            statusDiv.className = 'config-status success';\n        }\n    } catch (error) {\n        statusDiv.textContent = `Failed to save: ${error.message}`;\n        statusDiv.className = 'config-status error';\n    } finally {\n        saveBtn.disabled = false;\n        saveBtn.innerHTML = '<i class=\"fas fa-save\"></i> Save';\n    }\n}\n\n// Switch config tab\nfunction switchConfigTab(tabName) {\n    const fileNameSpan = document.getElementById('config-file-name');\n    // Update tab buttons\n    document.querySelectorAll('.config-tab').forEach(tab => {\n        tab.classList.remove('active');\n        if (tab.dataset.tab === tabName) {\n            tab.classList.add('active');\n        }\n    });\n    \n    // Update tab content\n    document.querySelectorAll('.config-tab-content').forEach(content => {\n        content.classList.remove('active');\n    });\n    \n    if (tabName === 'guided') {\n        document.getElementById('tab-guided').classList.add('active');\n        document.getElementById('config-editor-actions').style.display = 'flex';\n        if (fileNameSpan) fileNameSpan.textContent = 'Guided runtime config';\n        loadGuidedConfig();\n    } else if (tabName === 'editor') {\n        document.getElementById('tab-editor').classList.add('active');\n        document.getElementById('config-editor-actions').style.display = 'flex';\n        if (fileNameSpan) fileNameSpan.textContent = currentConfigFile;\n    } else if (tabName === 'tree') {\n        document.getElementById('tab-tree').classList.add('active');\n        document.getElementById('config-editor-actions').style.display = 'none';\n        loadAgentTree();\n    }\n}\n\n// Load and render agent tree\nasync function loadAgentTree() {\n    const container = document.getElementById('agent-tree-container');\n    container.innerHTML = '<div class=\"agent-tree-loading\">Loading agent tree...</div>';\n    \n    try {\n        const response = await fetch(`/api/config/agent-tree?agent_system=${encodeURIComponent(agentSystem)}`, {\n            credentials: 'include'\n        });\n        \n        const data = await response.json();\n        \n        if (data.error) {\n            container.innerHTML = `<div class=\"agent-tree-error\">Error: ${data.error}</div>`;\n            return;\n        }\n        \n        // Render tree\n        container.innerHTML = '';\n        if (data.trees && data.trees.length > 0) {\n            data.trees.forEach(tree => {\n                const treeElement = renderAgentTreeNode(tree, 0);\n                container.appendChild(treeElement);\n            });\n        } else {\n            container.innerHTML = '<div class=\"agent-tree-empty\">No agents found</div>';\n        }\n    } catch (error) {\n        container.innerHTML = `<div class=\"agent-tree-error\">Failed to load agent tree: ${error.message}</div>`;\n    }\n}\n\n// Render a single agent tree node\nfunction renderAgentTreeNode(node, depth = 0) {\n    const nodeDiv = document.createElement('div');\n    nodeDiv.className = 'agent-tree-node';\n    \n    // Node content\n    const content = document.createElement('div');\n    content.className = 'agent-tree-node-content';\n    content.style.paddingLeft = `${depth * 24}px`;\n    \n    // Level badge\n    const levelBadge = document.createElement('span');\n    levelBadge.className = `agent-tree-level level-${node.level}`;\n    levelBadge.textContent = `L${node.level}`;\n    \n    // Agent name\n    const nameSpan = document.createElement('span');\n    nameSpan.className = 'agent-tree-name';\n    nameSpan.textContent = node.name;\n    \n    // Expand/collapse button (only if has children)\n    let expandBtn = null;\n    if (node.children && node.children.length > 0) {\n        expandBtn = document.createElement('button');\n        expandBtn.className = 'agent-tree-expand';\n        expandBtn.innerHTML = '<i class=\"fas fa-chevron-down\"></i>';\n    }\n    \n    content.appendChild(levelBadge);\n    content.appendChild(nameSpan);\n    if (expandBtn) {\n        content.appendChild(expandBtn);\n    }\n    \n    nodeDiv.appendChild(content);\n    \n    // Children container\n    const childrenDiv = document.createElement('div');\n    childrenDiv.className = 'agent-tree-children';\n    \n    // Render child agents\n    if (node.children && node.children.length > 0) {\n        node.children.forEach(child => {\n            const childElement = renderAgentTreeNode(child, depth + 1);\n            childrenDiv.appendChild(childElement);\n        });\n    }\n    \n    nodeDiv.appendChild(childrenDiv);\n    \n    // Toggle expand/collapse\n    if (expandBtn) {\n        let isExpanded = true;\n        expandBtn.addEventListener('click', (e) => {\n            e.stopPropagation();\n            isExpanded = !isExpanded;\n            if (isExpanded) {\n                childrenDiv.style.display = '';\n                expandBtn.innerHTML = '<i class=\"fas fa-chevron-down\"></i>';\n            } else {\n                childrenDiv.style.display = 'none';\n                expandBtn.innerHTML = '<i class=\"fas fa-chevron-right\"></i>';\n            }\n        });\n    }\n    \n    return nodeDiv;\n}\n\nfunction setToolsStatus(message, isError = false) {\n    if (!toolsStatus) return;\n    toolsStatus.textContent = message || '';\n    toolsStatus.className = 'config-status';\n    if (message) {\n        toolsStatus.classList.add(isError ? 'error' : 'success');\n    }\n}\n\nasync function loadToolsList() {\n    if (!toolsList) return;\n    toolsList.innerHTML = '<div class=\"config-file-empty\">Loading tools...</div>';\n    setToolsStatus('');\n    try {\n        const response = await fetch('/api/tools/list', { credentials: 'include' });\n        const data = await response.json();\n        if (data.error) throw new Error(data.error);\n\n        const items = [\n            ...(data.tools || []).map(item => ({ ...item, failure: false })),\n            ...(data.failures || []).map(item => ({\n                name: item.name,\n                source: item.source || 'custom',\n                path: item.path || '',\n                class_name: '',\n                status: 'error',\n                error: item.error || 'Failed to load',\n                agent_systems: [],\n                bound: false,\n                failure: true,\n            }))\n        ];\n\n        if (!items.length) {\n            toolsList.innerHTML = '<div class=\"config-file-empty\">No runtime tools found.</div>';\n            return;\n        }\n\n        toolsList.innerHTML = '';\n        for (const tool of items) {\n            const bindings = (tool.agent_systems && tool.agent_systems.length)\n                ? tool.agent_systems.join(', ')\n                : 'Not bound in any agent_system YAML';\n            const card = document.createElement('div');\n            card.className = `tool-item ${tool.status === 'error' ? 'error' : ''}`;\n            card.innerHTML = `\n                <div class=\"tool-item-header\">\n                    <div>\n                        <div class=\"tool-item-title\">${escapeHtml(tool.name || 'unknown')}</div>\n                        <div class=\"tool-item-meta\">\n                            <div>Source: ${escapeHtml(tool.source || 'builtin')}</div>\n                            ${tool.class_name ? `<div>Class: ${escapeHtml(tool.class_name)}</div>` : ''}\n                            ${tool.path ? `<div>Path: ${escapeHtml(tool.path)}</div>` : ''}\n                            <div>Bindings: ${escapeHtml(bindings)}</div>\n                            ${tool.error ? `<div>Error: ${escapeHtml(tool.error)}</div>` : ''}\n                        </div>\n                    </div>\n                    <span class=\"tool-item-status ${tool.status === 'error' ? 'error' : ''}\">${escapeHtml(tool.status || 'loaded')}</span>\n                </div>\n                <div class=\"tool-item-actions\">\n                    ${tool.source === 'custom' ? `<button class=\"btn-danger tool-delete-btn\" data-tool=\"${escapeHtml(tool.name || '')}\"><i class=\"fas fa-trash\"></i> Delete</button>` : ''}\n                </div>\n            `;\n            toolsList.appendChild(card);\n        }\n\n        toolsList.querySelectorAll('.tool-delete-btn').forEach(btn => {\n            btn.addEventListener('click', async () => {\n                const toolName = btn.dataset.tool;\n                if (!confirm(`Delete custom tool \"${toolName}\"?`)) return;\n                try {\n                    const response = await fetch(`/api/tools/${encodeURIComponent(toolName)}`, {\n                        method: 'DELETE',\n                        credentials: 'include'\n                    });\n                    const data = await response.json();\n                    if (data.error) throw new Error(data.error);\n                    setToolsStatus(`Deleted tool: ${toolName}`, false);\n                    await loadToolsList();\n                } catch (error) {\n                    setToolsStatus(error.message, true);\n                }\n            });\n        });\n    } catch (error) {\n        toolsList.innerHTML = '<div class=\"config-file-empty\">Failed to load tools.</div>';\n        setToolsStatus(error.message, true);\n    }\n}\n\nasync function uploadToolFile(event) {\n    const file = event.target.files?.[0];\n    if (!file) return;\n\n    const formData = new FormData();\n    formData.append('file', file);\n    try {\n        const response = await fetch('/api/tools/upload', {\n            method: 'POST',\n            credentials: 'include',\n            body: formData\n        });\n        const data = await response.json();\n        if (data.error) throw new Error(data.error);\n        setToolsStatus(`Uploaded tool: ${data.tool_name}`, false);\n        await loadToolsList();\n    } catch (error) {\n        setToolsStatus(error.message, true);\n    } finally {\n        event.target.value = '';\n    }\n}\n\nasync function reloadToolsRegistry() {\n    try {\n        const response = await fetch('/api/tools/reload', {\n            method: 'POST',\n            credentials: 'include'\n        });\n        const data = await response.json();\n        if (data.error) throw new Error(data.error);\n        setToolsStatus('Runtime registry reloaded', false);\n        await loadToolsList();\n    } catch (error) {\n        setToolsStatus(error.message, true);\n    }\n}\n\nfunction openToolsModal() {\n    if (!toolsModal) return;\n    toolsModal.style.display = 'flex';\n    loadToolsList();\n}\n\nfunction closeToolsModal() {\n    if (!toolsModal) return;\n    toolsModal.style.display = 'none';\n}\n\nfunction initToolsModal() {\n    if (toolsBtn) toolsBtn.addEventListener('click', openToolsModal);\n    if (closeToolsBtn) closeToolsBtn.addEventListener('click', closeToolsModal);\n    if (uploadToolBtn && toolUploadInput) {\n        uploadToolBtn.addEventListener('click', () => toolUploadInput.click());\n        toolUploadInput.addEventListener('change', uploadToolFile);\n    }\n    if (reloadToolsBtn) reloadToolsBtn.addEventListener('click', reloadToolsRegistry);\n    if (toolsModal) {\n        toolsModal.addEventListener('click', (e) => {\n            if (e.target === toolsModal) closeToolsModal();\n        });\n    }\n}\n\nfunction initUsersModal() {\n    if (usersBtn) usersBtn.addEventListener('click', openUsersModal);\n    if (closeUsersBtn) closeUsersBtn.addEventListener('click', closeUsersModal);\n    if (reloadUsersBtn) reloadUsersBtn.addEventListener('click', loadUsers);\n    if (newUserBtn) newUserBtn.addEventListener('click', resetUserEditor);\n    if (saveUserBtn) saveUserBtn.addEventListener('click', saveUserRecord);\n    if (deleteUserBtn) deleteUserBtn.addEventListener('click', deleteSelectedUser);\n    if (usersModal) {\n        usersModal.addEventListener('click', (e) => {\n            if (e.target === usersModal) closeUsersModal();\n        });\n    }\n}\n\n// Initialize configuration modal event listeners (called in main DOMContentLoaded)\nfunction initConfigModal() {\n    // Close button\n    const closeConfigBtn = document.getElementById('close-config-btn');\n    if (closeConfigBtn) {\n        closeConfigBtn.addEventListener('click', closeConfigModal);\n    }\n    \n    // Tab switching\n    document.querySelectorAll('.config-tab').forEach(tab => {\n        tab.addEventListener('click', () => {\n            const tabName = tab.dataset.tab;\n            switchConfigTab(tabName);\n        });\n    });\n    \n    // Save button\n    const saveConfigBtn = document.getElementById('save-config-btn');\n    if (saveConfigBtn) {\n        saveConfigBtn.addEventListener('click', saveConfigFile);\n    }\n    \n    // Reload button\n    const reloadConfigBtn = document.getElementById('reload-config-btn');\n    if (reloadConfigBtn) {\n        reloadConfigBtn.addEventListener('click', () => {\n            if (getActiveConfigTabName() === 'guided') {\n                loadGuidedConfig();\n                return;\n            }\n            const fileNameSpan = document.getElementById('config-file-name');\n            loadConfigFile(fileNameSpan.textContent, currentConfigType);\n        });\n    }\n    \n    // Close modal when clicking outside\n    const configModal = document.getElementById('config-modal');\n    if (configModal) {\n        configModal.addEventListener('click', (e) => {\n            if (e.target === configModal) {\n                closeConfigModal();\n            }\n        });\n    }\n    \n    // Close modal with Escape key\n    document.addEventListener('keydown', (e) => {\n        if (e.key === 'Escape' && configModal && configModal.style.display === 'flex') {\n            closeConfigModal();\n        }\n    });\n}\n"
  },
  {
    "path": "web_ui/static/style.css",
    "content": "/**\n * MLA-V3 Web UI - Stylesheet\n * \n * Author: Songmiao Wang\n * MLA System: Chenlin Yu, Songmiao Wang\n */\n\n/* Global styles */\n* {\n    margin: 0;\n    padding: 0;\n    box-sizing: border-box;\n}\n\nbody {\n    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n        'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n        sans-serif;\n    background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1419 100%);\n    color: #e0e6ed;\n    height: 100vh;\n    overflow: hidden;\n    animation: fadeIn 0.8s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* Main interface fade-in animation */\n@keyframes fadeIn {\n    from {\n        opacity: 0;\n    }\n    to {\n        opacity: 1;\n    }\n}\n\n@keyframes fadeInUp {\n    from {\n        opacity: 0;\n        transform: translateY(20px);\n    }\n    to {\n        opacity: 1;\n        transform: translateY(0);\n    }\n}\n\n/* Logout fade-out animation */\n@keyframes fadeOutDown {\n    from {\n        opacity: 1;\n        transform: translateY(0) scale(1);\n    }\n    to {\n        opacity: 0;\n        transform: translateY(30px) scale(0.95);\n    }\n}\n\n@keyframes fadeOut {\n    from {\n        opacity: 1;\n    }\n    to {\n        opacity: 0;\n    }\n}\n\n.container {\n    display: flex;\n    flex-direction: column;\n    height: 100vh;\n    animation: fadeInUp 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* Top control bar */\n.header {\n    background: linear-gradient(180deg, rgba(20, 30, 50, 0.95) 0%, rgba(15, 20, 35, 0.95) 100%);\n    border-bottom: 1px solid rgba(0, 212, 255, 0.15);\n    padding: 16px 24px;\n    flex-shrink: 0;\n    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4), 0 0 1px rgba(0, 212, 255, 0.1);\n    backdrop-filter: blur(10px);\n}\n\n.header-content {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n.header-content h1 {\n    font-size: 20px;\n    margin: 0;\n    color: #ffffff;\n    font-weight: 600;\n    letter-spacing: -0.3px;\n    text-shadow: 0 0 10px rgba(0, 212, 255, 0.3), 0 1px 2px rgba(0, 0, 0, 0.5);\n}\n\n/* Username badge style */\n.username-badge {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    padding: 6px 14px;\n    background: rgba(0, 212, 255, 0.1);\n    border: 1px solid rgba(0, 212, 255, 0.3);\n    border-radius: 8px;\n    color: #00d4ff;\n    font-size: 13px;\n    font-weight: 500;\n    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 0 8px rgba(0, 212, 255, 0.15);\n    backdrop-filter: blur(10px);\n    transition: all 0.2s ease;\n}\n\n.username-badge::before {\n    content: '\\f007'; /* Font Awesome fa-user Unicode */\n    font-family: 'Font Awesome 6 Free';\n    font-weight: 900;\n    font-size: 14px;\n    opacity: 0.9;\n    margin-right: 6px;\n}\n\n.username-badge:hover {\n    background: rgba(0, 212, 255, 0.15);\n    border-color: rgba(0, 212, 255, 0.4);\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 0 12px rgba(0, 212, 255, 0.2);\n    transform: translateY(-1px);\n}\n\n/* Logout button style - consistent with username badge */\n.logout-btn {\n    padding: 6px 14px !important;\n    font-size: 13px !important;\n    font-weight: 500;\n    min-height: 32px; /* Consistent height with username badge */\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.form-input {\n    width: 100%;\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    color: #e0e6ed;\n    padding: 10px 12px;\n    border-radius: 8px;\n    font-size: 13px;\n    box-sizing: border-box;\n}\n\n.form-input:focus {\n    outline: none;\n    border-color: rgba(0, 212, 255, 0.45);\n    box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.12);\n}\n\n.form-label {\n    color: #cbd5e1;\n    font-size: 13px;\n    font-weight: 500;\n}\n\n.controls {\n    display: flex;\n    gap: 16px;\n    align-items: center;\n    flex-wrap: wrap;\n}\n\n.control-group {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.control-group label {\n    font-size: 13px;\n    color: #cccccc;\n    white-space: nowrap;\n}\n\n.control-group input[type=\"text\"],\n.control-group select,\n#task-select {\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    color: #e0e6ed;\n    padding: 8px 12px;\n    border-radius: 6px;\n    font-size: 13px;\n    min-width: 200px;\n    transition: all 0.2s ease;\n    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n    height: 36px; /* Unified height */\n    box-sizing: border-box;\n    line-height: 20px; /* Ensure text vertical centering */\n}\n\n#task-select {\n    min-width: 150px;\n    height: 36px; /* Unified height */\n    box-sizing: border-box;\n}\n\n.control-group input[type=\"text\"]:focus,\n.control-group select:focus,\n#task-select:focus {\n    outline: none;\n    border-color: #00d4ff;\n    background: rgba(25, 35, 55, 0.8);\n    box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.2), inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 8px rgba(0, 212, 255, 0.15);\n}\n\n/* Button styles */\n.btn-primary,\n.btn-secondary {\n    padding: 8px 18px;\n    border: none;\n    border-radius: 6px;\n    font-size: 13px;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    font-weight: 500;\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n    height: 36px; /* Unified height */\n    box-sizing: border-box;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    line-height: 1;\n}\n\n.btn-primary {\n    background: linear-gradient(135deg, #00b8d4 0%, #0097a7 100%);\n    color: white;\n    min-width: 80px; /* Ensure consistent width with clear task button */\n    box-shadow: 0 2px 8px rgba(0, 184, 212, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n}\n\n.btn-primary:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n    background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);\n}\n\n.btn-primary:hover:not(:disabled) {\n    background: linear-gradient(135deg, #00d4ff 0%, #00b8d4 100%);\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px rgba(0, 212, 255, 0.4), 0 0 12px rgba(0, 212, 255, 0.2);\n}\n\n.btn-primary:active:not(:disabled) {\n    transform: translateY(0);\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.btn-primary:disabled {\n    background: #3c3c3c;\n    cursor: not-allowed;\n}\n\n.btn-secondary {\n    background: linear-gradient(135deg, rgba(20, 30, 50, 0.8) 0%, rgba(15, 25, 40, 0.8) 100%);\n    color: #e0e6ed;\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    min-width: 80px; /* Ensure consistent width with other buttons */\n}\n\n.btn-secondary:hover {\n    background: linear-gradient(135deg, rgba(25, 35, 55, 0.9) 0%, rgba(20, 30, 50, 0.9) 100%);\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 212, 255, 0.1);\n    border-color: rgba(0, 212, 255, 0.3);\n}\n\n.btn-secondary:active {\n    transform: translateY(0);\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.btn-danger {\n    background: linear-gradient(135deg, #d32f2f 0%, #b71c1c 100%);\n    color: white;\n    border: none;\n    padding: 8px 18px;\n    border-radius: 6px;\n    font-size: 13px;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    min-width: 80px; /* Ensure consistent width with other buttons */\n    font-weight: 500;\n    box-shadow: 0 2px 4px rgba(211, 47, 47, 0.3);\n    height: 36px; /* Unified height with other buttons */\n    box-sizing: border-box;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    line-height: 1;\n}\n\n.btn-danger:hover:not(:disabled) {\n    background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);\n    transform: translateY(-1px);\n    box-shadow: 0 4px 8px rgba(211, 47, 47, 0.4);\n}\n\n.btn-danger:active:not(:disabled) {\n    transform: translateY(0);\n    box-shadow: 0 2px 4px rgba(211, 47, 47, 0.3);\n}\n\n.btn-danger:disabled {\n    background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);\n    cursor: not-allowed;\n    box-shadow: none;\n    opacity: 0.5;\n}\n\n/* Main content area */\n.main-content {\n    display: flex;\n    flex: 1;\n    overflow: hidden;\n}\n\n/* Left wrapper: contains chat window and input area */\n.chat-wrapper {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    min-width: 0;\n    overflow: hidden;\n}\n\n/* Chat window */\n.chat-container {\n    flex: 1;\n    overflow-y: auto;\n    background: linear-gradient(180deg, rgba(10, 14, 39, 0.5) 0%, rgba(15, 20, 35, 0.5) 100%);\n    padding: 24px;\n    min-width: 0; /* Allow flex shrink */\n    position: relative;\n    min-height: 0; /* Allow flex shrink */\n}\n\n.chat-container::before {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 1px;\n    background: linear-gradient(90deg, transparent, rgba(0, 212, 255, 0.3), transparent);\n    box-shadow: 0 0 8px rgba(0, 212, 255, 0.2);\n}\n\n.messages {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    flex-direction: column;\n}\n\n.message {\n    display: flex;\n    gap: 12px;\n    margin-bottom: 16px;\n    animation: fadeIn 0.3s;\n}\n\n@keyframes fadeIn {\n    from {\n        opacity: 0;\n        transform: translateY(10px);\n    }\n    to {\n        opacity: 1;\n        transform: translateY(0);\n    }\n}\n\n.message-avatar {\n    width: 42px;\n    height: 42px;\n    border-radius: 50%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 20px;\n    flex-shrink: 0;\n    font-weight: bold;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n    border: 2px solid rgba(255, 255, 255, 0.1);\n    transition: all 0.2s ease;\n}\n\n.message-avatar:hover {\n    transform: scale(1.05);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);\n}\n\n/* User message (right side, avatar on right) */\n.message.user {\n    flex-direction: row !important;\n    justify-content: flex-start !important;\n    align-self: flex-end;\n    margin-left: auto;\n    margin-right: 0;\n    width: auto;\n    max-width: 100%;\n}\n\n.message.user .message-avatar {\n    order: 2 !important;\n}\n\n.message.user .message-content {\n    order: 1 !important;\n}\n\n/* Agent message (left side, avatar on left) */\n.message.agent {\n    flex-direction: row !important;\n    justify-content: flex-start !important;\n    align-self: flex-start;\n    margin-right: auto;\n    max-width: 100%;\n    width: fit-content;\n    margin-left: 0;\n}\n\n.message.agent .message-avatar {\n    order: 1 !important;\n}\n\n.message.agent .message-content {\n    order: 2 !important;\n}\n\n.message-content {\n    max-width: 66.67%;  /* Two-thirds, close to golden ratio */\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    border-radius: 12px;\n    padding: 14px 18px;\n    position: relative;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n    transition: all 0.2s ease;\n    backdrop-filter: blur(10px);\n}\n\n.message-content:hover {\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 212, 255, 0.1);\n    border-color: rgba(0, 212, 255, 0.3);\n}\n\n/* User message style - aligned to right */\n.message.user .message-content {\n    margin-left: auto;\n    background: linear-gradient(135deg, rgba(0, 150, 180, 0.15) 0%, rgba(0, 120, 150, 0.15) 100%);\n    border-color: rgba(0, 212, 255, 0.4);\n    box-shadow: 0 2px 8px rgba(0, 184, 212, 0.2), 0 0 0 0 rgba(0, 212, 255, 0);\n    max-width: 80%;  /* 用户消息允许更宽 */\n    width: fit-content;  /* 根据内容自动调整宽度 */\n    min-width: auto;  /* 不强制最小宽度 */\n}\n\n.message.user .message-content:hover {\n    box-shadow: 0 4px 12px rgba(0, 184, 212, 0.3), 0 0 12px rgba(0, 212, 255, 0.15);\n    border-color: rgba(0, 212, 255, 0.5);\n}\n\n/* Agent message style - aligned to left */\n.message.agent .message-content {\n    margin-right: auto;\n    background: rgba(20, 30, 50, 0.6);\n    border-color: rgba(0, 212, 255, 0.2);\n    width: fit-content;  /* 根据内容自动调整宽度 */\n    min-width: auto;  /* 不强制最小宽度 */\n}\n\n.message-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 8px;\n}\n\n.message-agent {\n    font-weight: 600;\n    color: #00d4ff;\n    font-size: 14px;\n    text-shadow: 0 0 8px rgba(0, 212, 255, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);\n}\n\n.message-time {\n    font-size: 11px;\n    color: #858585;\n    opacity: 0.8;\n}\n\n.message-text {\n    color: #cccccc;\n    line-height: 1.6;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n    font-size: 13px;\n}\n\n/* User message text - 使用 pre-line 而不是 pre-wrap，只保留显式换行，不保留空格 */\n.message.user .message-text {\n    white-space: pre-line;  /* 只保留换行符，不保留空格 */\n    word-wrap: break-word;\n}\n\n/* Message type style */\n.message.type-info .message-text {\n    color: #cccccc;\n}\n\n.message.type-agent_call .message-text {\n    color: #569cd6;\n    font-weight: 500;\n}\n\n.message.type-tool_call .message-text {\n    color: #4ec9b0;\n}\n\n.message.type-params .message-text {\n    color: #cccccc;\n    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n    font-size: 13px;\n    white-space: pre-wrap;\n}\n\n.message.type-success .message-text {\n    color: #4ec9b0;\n}\n\n.message.type-error .message-text {\n    color: #f48771;\n}\n\n.message.type-warning .message-text {\n    color: #dcdcaa;\n}\n\n.message.type-result .message-text {\n    color: #ce9178;\n    background: #2d2d2d;\n    padding: 8px;\n    border-radius: 4px;\n    margin-top: 8px;\n}\n\n.message.type-thinking .message-text {\n    color: #c586c0;\n    font-style: italic;\n}\n\n.message.type-reasoning .message-text {\n    color: #9cdcfe;\n    font-style: italic;\n}\n\n.message-thinking {\n    padding: 6px 24px;\n    max-width: 820px;\n    width: 100%;\n}\n\n.thinking-card {\n    background: rgba(34, 24, 58, 0.72);\n    border: 1px solid rgba(138, 113, 196, 0.45);\n    border-radius: 12px;\n    padding: 10px 14px;\n    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);\n}\n\n.thinking-card summary {\n    cursor: pointer;\n    font-weight: 600;\n    font-size: 13px;\n    color: #b9a5ff;\n    letter-spacing: 0.2px;\n}\n\n.thinking-card .thinking-content {\n    margin-top: 8px;\n    white-space: pre-wrap;\n    word-break: break-word;\n    line-height: 1.6;\n    max-height: 320px;\n    overflow-y: auto;\n    color: #ddd5ff;\n    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n    font-size: 13px;\n}\n\n.message.type-final_output .message-text {\n    color: #4ec9b0;\n    background: #1e3a2e;\n    padding: 12px;\n    border-radius: 4px;\n    border-left: 4px solid #4ec9b0;\n    font-weight: 500;\n    margin-top: 8px;\n}\n\n/* Loading animation - processing blink */\n.message.loading .message-content::after {\n    content: 'processing';\n    position: absolute;\n    right: -60px;\n    bottom: 0px;\n    font-size: 8px;\n    line-height: 1;\n    color: #4ec9b0;\n    font-family: 'Consolas', 'Monaco', monospace;\n    font-weight: 500;\n    letter-spacing: 0.5px;\n    animation: processing-blink 1.5s ease-in-out infinite;\n    white-space: nowrap;\n    opacity: 0.6;\n}\n\n@keyframes processing-blink {\n    0%, 100% {\n        opacity: 0.3;\n    }\n    50% {\n        opacity: 1;\n    }\n}\n\n/* Agent avatar colors - now dynamically generated via JavaScript, ensuring each agent has unique color */\n.message-avatar {\n    /* Default color (if JavaScript not set) */\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n}\n\n/* File browser */\n.file-browser {\n    position: relative; /* Provide positioning context for file-viewer */\n    width: 350px;\n    background: linear-gradient(180deg, rgba(20, 30, 50, 0.95) 0%, rgba(15, 20, 35, 0.95) 100%);\n    border-left: 1px solid rgba(0, 212, 255, 0.15);\n    display: flex;\n    flex-direction: column;\n    flex-shrink: 0;\n    box-shadow: -2px 0 12px rgba(0, 0, 0, 0.4), -1px 0 0 rgba(0, 212, 255, 0.1);\n    backdrop-filter: blur(10px);\n    height: 100%; /* Extend downward */\n}\n\n.file-browser-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 14px 18px;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.15);\n    background: linear-gradient(180deg, rgba(25, 35, 55, 0.8) 0%, rgba(20, 30, 50, 0.8) 100%);\n}\n\n.file-browser-actions {\n    display: flex;\n    gap: 4px;\n}\n\n.file-browser-header h3 {\n    font-size: 14px;\n    font-weight: 600;\n    color: #ffffff;\n    margin: 0;\n}\n\n/* File Browser 标题中的文件夹图标：淡蓝色 */\n.file-browser-header h3 i.fa-folder {\n    color: #6bb6ff;\n    margin-right: 8px;\n}\n\n.btn-icon {\n    background: transparent;\n    border: none;\n    color: #cccccc;\n    cursor: pointer;\n    padding: 6px 10px;\n    border-radius: 6px;\n    font-size: 16px;\n    transition: all 0.2s ease;\n}\n\n.btn-icon:hover {\n    background: rgba(0, 212, 255, 0.15);\n    transform: scale(1.1);\n    color: #00d4ff;\n    box-shadow: 0 0 8px rgba(0, 212, 255, 0.2);\n}\n\n.btn-icon:active {\n    transform: scale(0.95);\n}\n\n.file-browser-path {\n    padding: 10px 18px;\n    font-size: 11px;\n    color: #a0a8b0;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.15);\n    word-break: break-all;\n    background: linear-gradient(180deg, rgba(15, 20, 35, 0.8) 0%, rgba(10, 15, 30, 0.8) 100%);\n    font-family: 'Consolas', 'Monaco', monospace;\n}\n\n.file-tree {\n    flex: 1;\n    overflow-y: auto;\n    padding: 8px;\n}\n\n.file-tree-empty {\n    padding: 20px;\n    text-align: center;\n    color: #858585;\n    font-size: 13px;\n}\n\n.file-item {\n    padding: 8px 12px;\n    cursor: pointer;\n    border-radius: 6px;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    font-size: 13px;\n    transition: all 0.2s ease;\n    margin-bottom: 2px;\n}\n\n.file-item:hover {\n    background: linear-gradient(90deg, rgba(0, 184, 212, 0.15) 0%, rgba(0, 150, 180, 0.15) 100%);\n    transform: translateY(-1px);\n    box-shadow: 0 2px 6px rgba(0, 184, 212, 0.3), 0 0 8px rgba(0, 212, 255, 0.2);\n    /* border-left: 2px solid rgba(0, 212, 255, 0.4); */\n}\n\n.file-item.selected {\n    background: linear-gradient(90deg, rgba(0, 184, 212, 0.2) 0%, rgba(0, 150, 180, 0.2) 100%);\n    box-shadow: 0 2px 6px rgba(0, 184, 212, 0.3), 0 0 8px rgba(0, 212, 255, 0.15);\n    border-left: 2px solid #00d4ff;\n}\n\n.file-icon {\n    font-size: 16px;\n    width: 20px;\n    text-align: center;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    flex-shrink: 0;\n}\n\n.file-icon i {\n    font-size: 16px;\n}\n\n/* 文件夹图标：淡蓝色 */\n.file-item[data-type=\"directory\"] .file-icon i.fa-folder {\n    color: #6bb6ff; /* 比 #00d4ff 更淡的蓝色 */\n}\n\n/* 文件图标：白色 */\n.file-item[data-type=\"file\"] .file-icon i.fa-file {\n    color: #ffffff;\n}\n\n/* 返回上级目录图标：淡蓝色 */\n.file-icon i.fa-arrow-up {\n    color: #6bb6ff;\n}\n\n.file-name {\n    flex: 1;\n    word-break: break-all;\n}\n\n.file-item-download-btn {\n    background: transparent;\n    border: none;\n    color: #00d4ff;\n    cursor: pointer;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 14px;\n    transition: all 0.2s ease;\n    opacity: 0.7;\n    margin-left: auto;\n    flex-shrink: 0;\n}\n\n.file-item-download-btn:hover {\n    opacity: 1;\n    background: rgba(0, 212, 255, 0.2);\n    transform: scale(1.1);\n}\n\n.file-item-download-btn:active {\n    transform: scale(0.95);\n}\n\n.file-viewer {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: linear-gradient(180deg, #1e1e1e 0%, #252526 100%);\n    display: flex;\n    flex-direction: column;\n    z-index: 10;\n    border-left: 1px solid rgba(62, 62, 66, 0.5);\n    box-shadow: -4px 0 12px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n}\n\n@keyframes slideIn {\n    from {\n        transform: translateX(100%);\n        opacity: 0;\n    }\n    to {\n        transform: translateX(0);\n        opacity: 1;\n    }\n}\n\n.file-viewer-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 14px 18px;\n    border-bottom: 1px solid rgba(62, 62, 66, 0.5);\n    background: linear-gradient(180deg, #2d2d30 0%, #252526 100%);\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.file-viewer-actions {\n    display: flex;\n    gap: 4px;\n}\n\n.file-viewer-header span {\n    font-size: 13px;\n    font-weight: 600;\n    color: #ffffff;\n    word-break: break-all;\n}\n\n.file-viewer-content {\n    flex: 1;\n    overflow: auto;\n    padding: 16px;\n    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n    font-size: 12px;\n    line-height: 1.6;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n    color: #d4d4d4;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    min-height: 0;\n}\n\n/* 图片显示样式 */\n.file-viewer-content img {\n    max-width: 100%;\n    max-height: 100%;\n    object-fit: contain;\n    border-radius: 4px;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n}\n\n/* 图片模式：居中显示，深色背景 */\n.file-viewer-content.image-mode {\n    background: rgba(0, 0, 0, 0.3);\n    align-items: center;\n    justify-content: center;\n}\n\n/* 文本模式：左对齐显示 */\n.file-viewer-content.text-mode {\n    align-items: flex-start;\n    justify-content: flex-start;\n}\n\n/* Welcome message */\n/* Welcome message fade-out animation */\n.welcome-message.fade-out {\n    animation: fadeOut 0.3s ease-out forwards;\n}\n\n@keyframes fadeOut {\n    from {\n        opacity: 1;\n        transform: translateY(0);\n    }\n    to {\n        opacity: 0;\n        transform: translateY(-10px);\n        max-height: 0;\n        margin: 0;\n        padding: 0;\n        overflow: hidden;\n    }\n}\n\n.welcome-message {\n    text-align: center;\n    padding: 80px 20px;\n    color: #a0a8b0;\n    background: linear-gradient(135deg, rgba(0, 212, 255, 0.05) 0%, rgba(0, 184, 212, 0.05) 100%);\n    border-radius: 12px;\n    margin: 20px 0;\n    border: 1px dashed rgba(0, 212, 255, 0.2);\n    backdrop-filter: blur(10px);\n}\n\n.welcome-message p {\n    margin-bottom: 16px;\n    font-size: 15px;\n    line-height: 1.6;\n}\n\n.welcome-message p:first-child {\n    font-size: 18px;\n    color: #00d4ff;\n    font-weight: 500;\n    text-shadow: 0 0 8px rgba(0, 212, 255, 0.3);\n}\n\n/* Input area */\n.input-container {\n    background: linear-gradient(180deg, rgba(20, 30, 50, 0.95) 0%, rgba(15, 20, 35, 0.95) 100%);\n    border-top: 1px solid rgba(0, 212, 255, 0.15);\n    padding: 20px 24px;\n    flex-shrink: 0;\n    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.4), 0 0 1px rgba(0, 212, 255, 0.1);\n    backdrop-filter: blur(10px);\n}\n\n.input-wrapper {\n    display: flex;\n    gap: 12px;\n    margin-bottom: 8px;\n}\n\n.input-wrapper textarea {\n    flex: 1;\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    color: #e0e6ed;\n    padding: 12px 16px;\n    border-radius: 8px;\n    font-size: 13px;\n    font-family: inherit;\n    resize: none;\n    min-height: 48px;\n    max-height: 120px;\n    transition: all 0.2s ease;\n    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 212, 255, 0);\n}\n\n.input-wrapper textarea:focus {\n    outline: none;\n    border-color: #00d4ff;\n    background: rgba(25, 35, 55, 0.8);\n    box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.2), inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 8px rgba(0, 212, 255, 0.15);\n}\n\n/* HIL (Human-in-Loop) waiting state - red blinking effect */\n@keyframes hilBlink {\n    0%, 100% {\n        border-color: #ff6b6b;\n        box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.3), inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 12px rgba(255, 107, 107, 0.4);\n    }\n    50% {\n        border-color: #ff8787;\n        box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.5), inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 16px rgba(255, 107, 107, 0.6);\n    }\n}\n\n.input-wrapper textarea.hil-waiting {\n    border-color: #ff6b6b;\n    background: rgba(40, 25, 30, 0.8);\n    animation: hilBlink 1.5s ease-in-out infinite;\n}\n\n.input-wrapper textarea.hil-waiting:focus {\n    border-color: #ff6b6b;\n    background: rgba(45, 30, 35, 0.9);\n    animation: hilBlink 1.5s ease-in-out infinite;\n}\n\n.input-wrapper textarea::placeholder {\n    color: #858585;\n}\n\n/* Input area button style - consistent with input box height */\n.input-wrapper .btn-primary,\n.input-wrapper .btn-danger {\n    height: 54px; /* Match textarea min-height */\n    min-width: 80px;\n    box-sizing: border-box;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    line-height: 1;\n    flex-shrink: 0;\n    padding: 12px 18px; /* Increase vertical padding to make button less flat */\n    border-radius: 8px; /* Match textarea border-radius */\n}\n\n/* Input area send button disabled state */\n.input-wrapper .btn-primary:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n    background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);\n}\n\n.status-bar {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    font-size: 12px;\n    color: #a0a8b0;\n    margin-top: 10px;\n    padding-top: 10px;\n    border-top: 1px solid rgba(0, 212, 255, 0.15);\n}\n\n.workspace {\n    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n    color: #00d4ff;\n    opacity: 0.9;\n    font-weight: 500;\n    text-shadow: 0 0 6px rgba(0, 212, 255, 0.3);\n}\n\n/* Scrollbar style */\n.chat-container::-webkit-scrollbar,\n.file-tree::-webkit-scrollbar,\n.file-viewer-content::-webkit-scrollbar {\n    width: 10px;\n}\n\n.chat-container::-webkit-scrollbar-track,\n.file-tree::-webkit-scrollbar-track,\n.file-viewer-content::-webkit-scrollbar-track {\n    background: rgba(30, 30, 30, 0.5);\n    border-radius: 5px;\n}\n\n.chat-container::-webkit-scrollbar-thumb,\n.file-tree::-webkit-scrollbar-thumb,\n.file-viewer-content::-webkit-scrollbar-thumb {\n    background: linear-gradient(180deg, #424242 0%, #3a3a3a 100%);\n    border-radius: 5px;\n    border: 2px solid rgba(30, 30, 30, 0.5);\n}\n\n.chat-container::-webkit-scrollbar-thumb:hover,\n.file-tree::-webkit-scrollbar-thumb:hover,\n.file-viewer-content::-webkit-scrollbar-thumb:hover {\n    background: linear-gradient(180deg, #4e4e4e 0%, #424242 100%);\n}\n\n/* Responsive design */\n@media (max-width: 768px) {\n    .controls {\n        flex-direction: column;\n        align-items: stretch;\n    }\n    \n    .control-group {\n        flex-direction: column;\n        align-items: stretch;\n    }\n    \n    .control-group input[type=\"text\"],\n    .control-group select {\n        width: 100%;\n    }\n}\n\n/* Font Awesome Icon Styles */\n/* Icon buttons */\n.btn-icon i,\n.file-item-download-btn i {\n    font-size: inherit;\n    color: inherit;\n    display: inline-block;\n    line-height: 1;\n}\n\n/* Message text icons */\n.message-text i {\n    margin-right: 4px;\n    font-size: 0.9em;\n    display: inline-block;\n    vertical-align: middle;\n}\n\n/* Icon colors for different message types */\n.message-text i.fa-check-circle {\n    color: #4ec9b0; /* Success color */\n}\n\n.message-text i.fa-times-circle {\n    color: #f48771; /* Error color */\n}\n\n.message-text i.fa-wrench {\n    color: #4ec9b0; /* Tool call color */\n}\n\n.message-text i.fa-book {\n    color: #569cd6; /* Agent call color */\n}\n\n.message-text i.fa-clipboard-list {\n    color: #4ec9b0; /* Parameters color */\n}\n\n.message-text i.fa-rocket {\n    color: #4ec9b0; /* Start color */\n}\n\n.message-text i.fa-stop {\n    color: #f48771; /* Stop color */\n}\n\n.message-text i.fa-exclamation-triangle {\n    color: #dcdcaa; /* Warning color */\n}\n\n/* Avatar icons */\n.message-avatar i {\n    font-size: 20px;\n    color: rgba(255, 255, 255, 0.9);\n    display: inline-block;\n}\n\n/* Status bar icons */\n#status-text i {\n    margin-right: 4px;\n    color: #4ec9b0;\n}\n\n/* Configuration Modal Styles */\n.config-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    background: rgba(0, 0, 0, 0.7);\n    backdrop-filter: blur(5px);\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    z-index: 10000;\n    animation: fadeIn 0.3s ease;\n}\n\n.config-modal-content {\n    background: linear-gradient(135deg, rgba(20, 30, 50, 0.98) 0%, rgba(15, 25, 40, 0.98) 100%);\n    border: 1px solid rgba(0, 212, 255, 0.3);\n    border-radius: 12px;\n    width: 90%;\n    max-width: 1200px;\n    height: 85vh;\n    max-height: 900px;\n    display: flex;\n    flex-direction: column;\n    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 212, 255, 0.1);\n    animation: fadeInUp 0.3s ease;\n}\n\n.config-modal-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20px 24px;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.2);\n    flex-shrink: 0;\n}\n\n.config-modal-header h2 {\n    margin: 0;\n    font-size: 20px;\n    color: #ffffff;\n    font-weight: 600;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.config-modal-header h2 i {\n    color: #00d4ff;\n}\n\n.config-modal-body {\n    display: flex;\n    flex: 1;\n    overflow: hidden;\n}\n\n.config-sidebar {\n    width: 280px;\n    background: rgba(10, 15, 25, 0.6);\n    border-right: 1px solid rgba(0, 212, 255, 0.2);\n    padding: 16px;\n    overflow-y: auto;\n    flex-shrink: 0;\n    display: flex;\n    flex-direction: column;\n    gap: 20px;\n}\n\n.config-section {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    min-height: 0;\n}\n\n.config-section-header {\n    font-size: 13px;\n    font-weight: 600;\n    color: #00d4ff;\n    margin-bottom: 12px;\n    padding: 8px 12px;\n    background: rgba(0, 212, 255, 0.1);\n    border-radius: 6px;\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.config-section-header i {\n    font-size: 14px;\n}\n\n.config-file-list {\n    display: flex;\n    flex-direction: column;\n    gap: 6px;\n    flex: 1;\n    overflow-y: auto;\n    min-height: 0;\n}\n\n.config-file-empty {\n    padding: 12px;\n    text-align: center;\n    color: #6b7280;\n    font-size: 13px;\n    font-style: italic;\n}\n\n.config-file-item {\n    padding: 12px 16px;\n    border-radius: 6px;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    color: #b0b8c4;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    font-size: 14px;\n    border: 1px solid transparent;\n}\n\n.config-file-item:hover {\n    background: rgba(0, 212, 255, 0.1);\n    color: #e0e6ed;\n    border-color: rgba(0, 212, 255, 0.2);\n}\n\n.config-file-item.active {\n    background: linear-gradient(135deg, rgba(0, 212, 255, 0.2) 0%, rgba(0, 184, 212, 0.15) 100%);\n    color: #00d4ff;\n    border-color: rgba(0, 212, 255, 0.4);\n    box-shadow: 0 2px 8px rgba(0, 212, 255, 0.2);\n}\n\n.config-file-item i {\n    font-size: 16px;\n}\n\n.config-editor {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    overflow: hidden;\n}\n\n\n.config-editor-buttons .btn-primary,\n.config-editor-buttons .btn-secondary {\n    min-width: 100px;\n    height: 36px;\n    padding: 8px 16px;\n    font-size: 13px;\n}\n\n.config-editor-content {\n    flex: 1;\n    padding: 20px;\n    overflow: hidden;\n    display: flex;\n    flex-direction: column;\n}\n\n.config-editor-content textarea {\n    flex: 1;\n    width: 100%;\n    background: rgba(10, 15, 25, 0.8);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    border-radius: 8px;\n    padding: 16px;\n    color: #e0e6ed;\n    font-family: 'Courier New', 'Monaco', 'Menlo', monospace;\n    font-size: 13px;\n    line-height: 1.6;\n    resize: none;\n    outline: none;\n    transition: all 0.2s ease;\n}\n\n.config-editor-content textarea:focus {\n    border-color: rgba(0, 212, 255, 0.5);\n    box-shadow: 0 0 0 3px rgba(0, 212, 255, 0.1);\n}\n\n.config-editor-content textarea::placeholder {\n    color: #6b7280;\n}\n\n.config-status {\n    padding: 12px 16px;\n    margin-top: 12px;\n    border-radius: 6px;\n    font-size: 13px;\n    font-weight: 500;\n    text-align: center;\n    transition: all 0.3s ease;\n}\n\n.config-status.success {\n    background: rgba(76, 175, 80, 0.2);\n    color: #4caf50;\n    border: 1px solid rgba(76, 175, 80, 0.3);\n}\n\n.config-status.error {\n    background: rgba(211, 47, 47, 0.2);\n    color: #f44336;\n    border: 1px solid rgba(211, 47, 47, 0.3);\n}\n\n.config-status:empty {\n    display: none;\n}\n\n.tools-modal-content {\n    max-width: 980px;\n    height: 78vh;\n}\n\n.tools-modal-body {\n    display: flex;\n    flex-direction: column;\n    gap: 16px;\n    padding: 20px 24px 24px;\n    overflow: hidden;\n    flex: 1;\n}\n\n.tools-toolbar {\n    display: flex;\n    gap: 12px;\n    flex-wrap: wrap;\n}\n\n.tools-help {\n    font-size: 13px;\n    line-height: 1.6;\n    color: #b0b8c4;\n    background: rgba(0, 212, 255, 0.08);\n    border: 1px solid rgba(0, 212, 255, 0.15);\n    border-radius: 8px;\n    padding: 12px 14px;\n}\n\n.tools-list {\n    flex: 1;\n    overflow-y: auto;\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n    min-height: 0;\n}\n\n.tool-item {\n    border: 1px solid rgba(0, 212, 255, 0.16);\n    border-radius: 10px;\n    padding: 14px 16px;\n    background: rgba(10, 15, 25, 0.72);\n}\n\n.tool-item.error {\n    border-color: rgba(244, 67, 54, 0.35);\n}\n\n.tool-item-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: flex-start;\n    gap: 12px;\n}\n\n.user-item.active {\n    border-color: rgba(0, 212, 255, 0.45);\n    box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.18);\n}\n\n.users-admin-grid {\n    display: grid;\n    grid-template-columns: minmax(320px, 1.3fr) minmax(260px, 0.9fr);\n    gap: 18px;\n    align-items: start;\n}\n\n.users-editor-panel {\n    background: rgba(16, 22, 36, 0.72);\n    border: 1px solid rgba(0, 212, 255, 0.12);\n    border-radius: 12px;\n    padding: 16px;\n    display: flex;\n    flex-direction: column;\n    gap: 14px;\n}\n\n@media (max-width: 1100px) {\n    .users-admin-grid {\n        grid-template-columns: 1fr;\n    }\n}\n\n.tool-item-title {\n    font-size: 15px;\n    font-weight: 600;\n    color: #ffffff;\n}\n\n.tool-item-meta {\n    margin-top: 8px;\n    font-size: 12px;\n    color: #8ea3b7;\n    line-height: 1.7;\n    word-break: break-word;\n}\n\n.tool-item-status {\n    font-size: 12px;\n    font-weight: 600;\n    padding: 4px 8px;\n    border-radius: 999px;\n    background: rgba(81, 207, 102, 0.14);\n    color: #7ce38f;\n    flex-shrink: 0;\n}\n\n.tool-item-status.error {\n    background: rgba(244, 67, 54, 0.14);\n    color: #ff8e8e;\n}\n\n.tool-item-actions {\n    margin-top: 12px;\n    display: flex;\n    gap: 10px;\n}\n\n/* Scrollbar styling for config sidebar */\n.config-sidebar::-webkit-scrollbar,\n.config-file-list::-webkit-scrollbar {\n    width: 6px;\n}\n\n.config-sidebar::-webkit-scrollbar-track,\n.config-file-list::-webkit-scrollbar-track {\n    background: rgba(10, 15, 25, 0.5);\n    border-radius: 3px;\n}\n\n.config-sidebar::-webkit-scrollbar-thumb,\n.config-file-list::-webkit-scrollbar-thumb {\n    background: rgba(0, 212, 255, 0.3);\n    border-radius: 3px;\n}\n\n.config-sidebar::-webkit-scrollbar-thumb:hover,\n.config-file-list::-webkit-scrollbar-thumb:hover {\n    background: rgba(0, 212, 255, 0.5);\n}\n\n/* Config Tabs */\n.config-tabs {\n    display: flex;\n    gap: 8px;\n    margin-right: auto;\n}\n\n.config-tab {\n    padding: 8px 16px;\n    background: rgba(10, 15, 25, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    border-radius: 6px;\n    color: #b0b8c4;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    font-size: 13px;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n}\n\n.config-tab:hover {\n    background: rgba(0, 212, 255, 0.1);\n    border-color: rgba(0, 212, 255, 0.3);\n    color: #e0e6ed;\n}\n\n.config-tab.active {\n    background: linear-gradient(135deg, rgba(0, 212, 255, 0.2) 0%, rgba(0, 184, 212, 0.15) 100%);\n    border-color: rgba(0, 212, 255, 0.4);\n    color: #00d4ff;\n    box-shadow: 0 2px 8px rgba(0, 212, 255, 0.2);\n}\n\n.config-editor-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16px 24px;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.2);\n    flex-shrink: 0;\n    gap: 16px;\n}\n\n.config-editor-actions {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n.config-file-name {\n    font-size: 14px;\n    font-weight: 600;\n    color: #e0e6ed;\n    margin-right: 8px;\n}\n\n.config-editor-buttons {\n    display: flex;\n    gap: 10px;\n}\n\n.config-tab-content {\n    display: none;\n    flex: 1;\n    overflow: hidden;\n    flex-direction: column;\n}\n\n.config-tab-content.active {\n    display: flex;\n}\n\n.config-guided-scroll {\n    flex: 1;\n    overflow-y: auto;\n    padding-right: 6px;\n    display: flex;\n    flex-direction: column;\n    gap: 18px;\n}\n\n.guided-section-card {\n    background: rgba(10, 15, 25, 0.62);\n    border: 1px solid rgba(0, 212, 255, 0.14);\n    border-radius: 12px;\n    padding: 18px;\n}\n\n.guided-section-card h3 {\n    margin: 0 0 16px;\n    color: #ffffff;\n    font-size: 16px;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.guided-section-card h3 i {\n    color: #00d4ff;\n}\n\n.guided-split-grid {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n.model-slot-toolbar {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 12px;\n    margin-bottom: 12px;\n    flex-wrap: wrap;\n}\n\n.model-slot-list {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n.model-slot-empty {\n    padding: 12px 14px;\n    border: 1px dashed rgba(0, 212, 255, 0.18);\n    border-radius: 10px;\n    color: #8ea3b7;\n    font-size: 12px;\n    background: rgba(10, 15, 25, 0.58);\n}\n\n.model-entry-card {\n    border: 1px solid rgba(0, 212, 255, 0.12);\n    border-radius: 12px;\n    background: rgba(10, 15, 25, 0.58);\n    padding: 14px;\n}\n\n.model-entry-topbar {\n    display: flex;\n    gap: 10px;\n    align-items: center;\n    margin-bottom: 10px;\n    flex-wrap: wrap;\n}\n\n.model-entry-topbar .form-group {\n    margin-bottom: 0;\n    min-width: 150px;\n    flex: 1;\n}\n\n.model-entry-actions {\n    margin-left: auto;\n}\n\n.model-entry-preview {\n    margin-top: 6px;\n    font-size: 11px;\n    color: #8ea3b7;\n    line-height: 1.45;\n}\n\n.model-entry-preview code {\n    background: rgba(255, 255, 255, 0.08);\n    border: 1px solid rgba(0, 212, 255, 0.14);\n    border-radius: 5px;\n    padding: 1px 5px;\n}\n\n.model-entry-custom-source {\n    margin-top: 10px;\n}\n\n.config-guided-scroll::-webkit-scrollbar {\n    width: 8px;\n}\n\n.config-guided-scroll::-webkit-scrollbar-track {\n    background: rgba(10, 15, 25, 0.5);\n    border-radius: 4px;\n}\n\n.config-guided-scroll::-webkit-scrollbar-thumb {\n    background: rgba(0, 212, 255, 0.3);\n    border-radius: 4px;\n}\n\n.config-guided-scroll::-webkit-scrollbar-thumb:hover {\n    background: rgba(0, 212, 255, 0.5);\n}\n\n/* Agent Tree Styles */\n.agent-tree-container {\n    flex: 1;\n    overflow-y: auto;\n    padding: 20px;\n    background: rgba(10, 15, 25, 0.4);\n}\n\n.agent-tree-loading,\n.agent-tree-error,\n.agent-tree-empty {\n    text-align: center;\n    padding: 40px;\n    color: #6b7280;\n    font-size: 14px;\n}\n\n.agent-tree-error {\n    color: #f44336;\n}\n\n.agent-tree-node {\n    margin-bottom: 8px;\n}\n\n.agent-tree-node-content {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    padding: 10px 12px;\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.15);\n    border-radius: 6px;\n    transition: all 0.2s ease;\n    cursor: default;\n}\n\n.agent-tree-node-content:hover {\n    background: rgba(0, 212, 255, 0.1);\n    border-color: rgba(0, 212, 255, 0.3);\n}\n\n.agent-tree-level {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    min-width: 32px;\n    height: 24px;\n    padding: 0 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-align: center;\n}\n\n.agent-tree-level.level-3 {\n    background: linear-gradient(135deg, #9c27b0 0%, #7b1fa2 100%);\n    color: white;\n}\n\n.agent-tree-level.level-2 {\n    background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%);\n    color: white;\n}\n\n.agent-tree-level.level-1 {\n    background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%);\n    color: white;\n}\n\n.agent-tree-level.level-0 {\n    background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);\n    color: white;\n}\n\n.agent-tree-level.level--1 {\n    background: linear-gradient(135deg, #607d8b 0%, #455a64 100%);\n    color: white;\n}\n\n.agent-tree-name {\n    flex: 1;\n    font-size: 14px;\n    font-weight: 500;\n    color: #e0e6ed;\n}\n\n.agent-tree-expand {\n    background: transparent;\n    border: none;\n    color: #00d4ff;\n    cursor: pointer;\n    padding: 4px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 20px;\n    height: 20px;\n    border-radius: 4px;\n    transition: all 0.2s ease;\n}\n\n.agent-tree-expand:hover {\n    background: rgba(0, 212, 255, 0.2);\n}\n\n.agent-tree-expand i {\n    font-size: 12px;\n}\n\n.agent-tree-children {\n    margin-top: 4px;\n}\n\n/* Scrollbar for agent tree */\n.agent-tree-container::-webkit-scrollbar {\n    width: 6px;\n}\n\n.agent-tree-container::-webkit-scrollbar-track {\n    background: rgba(10, 15, 25, 0.5);\n    border-radius: 3px;\n}\n\n.agent-tree-container::-webkit-scrollbar-thumb {\n    background: rgba(0, 212, 255, 0.3);\n    border-radius: 3px;\n}\n\n.agent-tree-container::-webkit-scrollbar-thumb:hover {\n    background: rgba(0, 212, 255, 0.5);\n}\n\n/* Agent Selection Modal */\n.agent-select-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    background: rgba(0, 0, 0, 0.7);\n    backdrop-filter: blur(5px);\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    z-index: 10001;\n    animation: fadeIn 0.3s ease;\n}\n\n.agent-select-modal-content {\n    background: linear-gradient(135deg, rgba(20, 30, 50, 0.98) 0%, rgba(15, 25, 40, 0.98) 100%);\n    border: 1px solid rgba(0, 212, 255, 0.3);\n    border-radius: 12px;\n    width: 90%;\n    max-width: 1400px;\n    height: 80vh;\n    max-height: 800px;\n    display: flex;\n    flex-direction: column;\n    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 212, 255, 0.1);\n    animation: fadeInUp 0.3s ease;\n}\n\n.agent-select-modal-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20px 24px;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.2);\n    flex-shrink: 0;\n}\n\n.agent-select-modal-header h2 {\n    margin: 0;\n    font-size: 20px;\n    color: #ffffff;\n    font-weight: 600;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.agent-select-modal-header h2 i {\n    color: #00d4ff;\n}\n\n.agent-select-modal-body {\n    display: flex;\n    flex-direction: row;\n    flex: 1;\n    overflow: hidden;\n    gap: 20px;\n    padding: 20px;\n}\n\n.agent-select-left {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    min-width: 0;\n    overflow: hidden;\n}\n\n.agent-select-right {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    min-width: 0;\n    overflow: hidden;\n    border-left: 1px solid rgba(0, 212, 255, 0.2);\n    padding-left: 20px;\n}\n\n.agent-select-search {\n    margin-bottom: 16px;\n    flex-shrink: 0;\n}\n\n.agent-select-search input {\n    width: 100%;\n    padding: 12px 16px;\n    background: rgba(10, 15, 25, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.2);\n    border-radius: 8px;\n    color: #e0e6ed;\n    font-size: 14px;\n    transition: all 0.2s ease;\n}\n\n.agent-select-search input:focus {\n    outline: none;\n    border-color: rgba(0, 212, 255, 0.5);\n    background: rgba(10, 15, 25, 0.8);\n    box-shadow: 0 0 0 3px rgba(0, 212, 255, 0.1);\n}\n\n.agent-select-list {\n    flex: 1;\n    overflow-y: auto;\n    overflow-x: hidden;\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n/* Custom scrollbar for agent-select-list */\n.agent-select-list::-webkit-scrollbar {\n    width: 8px;\n}\n\n.agent-select-list::-webkit-scrollbar-track {\n    background: rgba(10, 15, 25, 0.5);\n    border-radius: 4px;\n}\n\n.agent-select-list::-webkit-scrollbar-thumb {\n    background: rgba(0, 212, 255, 0.3);\n    border-radius: 4px;\n}\n\n.agent-select-list::-webkit-scrollbar-thumb:hover {\n    background: rgba(0, 212, 255, 0.5);\n}\n\n.agent-select-loading,\n.agent-select-error,\n.agent-select-empty {\n    text-align: center;\n    padding: 40px;\n    color: #6b7280;\n    font-size: 14px;\n}\n\n.agent-select-error {\n    color: #f44336;\n}\n\n.agent-select-level-group {\n    display: flex;\n    flex-direction: column;\n    gap: 8px;\n}\n\n.agent-select-level-header {\n    font-size: 12px;\n    font-weight: 600;\n    color: #00d4ff;\n    padding: 8px 12px;\n    background: rgba(0, 212, 255, 0.1);\n    border-radius: 6px;\n    border: 1px solid rgba(0, 212, 255, 0.2);\n}\n\n.agent-select-level-agents {\n    display: flex;\n    flex-direction: column;\n    gap: 8px;\n    padding-left: 12px;\n}\n\n.agent-select-item {\n    padding: 12px 16px;\n    background: rgba(20, 30, 50, 0.6);\n    border: 1px solid rgba(0, 212, 255, 0.15);\n    border-radius: 8px;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    min-width: 0;\n    overflow: hidden;\n}\n\n.agent-select-item:hover {\n    background: rgba(0, 212, 255, 0.1);\n    border-color: rgba(0, 212, 255, 0.3);\n    transform: translateX(4px);\n}\n\n.agent-select-item.selected {\n    background: rgba(0, 212, 255, 0.15);\n    border-color: rgba(0, 212, 255, 0.4);\n    box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.2);\n}\n\n.agent-select-item-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 6px;\n}\n\n.agent-select-item-name {\n    font-size: 14px;\n    font-weight: 600;\n    color: #e0e6ed;\n    flex: 1;\n    word-wrap: break-word;\n    word-break: break-word;\n    overflow-wrap: break-word;\n}\n\n.agent-select-item-level {\n    font-size: 11px;\n    font-weight: 600;\n    padding: 4px 8px;\n    border-radius: 4px;\n    background: rgba(0, 212, 255, 0.2);\n    color: #00d4ff;\n}\n\n.agent-select-item-description {\n    font-size: 12px;\n    color: #9ca3af;\n    line-height: 1.4;\n    margin-top: 4px;\n    word-wrap: break-word;\n    word-break: break-word;\n    overflow-wrap: break-word;\n    white-space: normal;\n}\n\n/* Agent Tree Panel (inside modal) */\n.agent-tree-panel {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    min-width: 0;\n    overflow: hidden;\n}\n\n.agent-tree-panel-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 0 0 16px 0;\n    border-bottom: 1px solid rgba(0, 212, 255, 0.2);\n    flex-shrink: 0;\n    margin-bottom: 16px;\n}\n\n.agent-tree-panel-header h3 {\n    margin: 0;\n    font-size: 16px;\n    color: #ffffff;\n    font-weight: 600;\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.agent-tree-panel-header h3 i {\n    color: #00d4ff;\n}\n\n.agent-tree-panel-content {\n    flex: 1;\n    overflow-y: auto;\n    overflow-x: hidden;\n    min-height: 0;\n    padding: 8px 0;\n}\n\n.agent-tree-panel-content .agent-tree-loading,\n.agent-tree-panel-content .agent-tree-error,\n.agent-tree-panel-content .agent-tree-empty {\n    text-align: center;\n    padding: 40px 20px;\n    color: #6b7280;\n    font-size: 14px;\n}\n\n.agent-tree-panel-content .agent-tree-error {\n    color: #f44336;\n}\n\n.agent-tree-node.root .agent-tree-node-content {\n    background: rgba(0, 212, 255, 0.15);\n    border-color: rgba(0, 212, 255, 0.4);\n    box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.2);\n}\n\n/* Custom scrollbar for agent-tree-panel-content */\n.agent-tree-panel-content::-webkit-scrollbar {\n    width: 8px;\n}\n\n.agent-tree-panel-content::-webkit-scrollbar-track {\n    background: rgba(10, 15, 25, 0.5);\n    border-radius: 4px;\n}\n\n.agent-tree-panel-content::-webkit-scrollbar-thumb {\n    background: rgba(0, 212, 255, 0.3);\n    border-radius: 4px;\n}\n\n.agent-tree-panel-content::-webkit-scrollbar-thumb:hover {\n    background: rgba(0, 212, 255, 0.5);\n}\n"
  },
  {
    "path": "web_ui/web_intro.md",
    "content": "# MLA-V3 Web UI User Guide\n\n## Overview\n\nMLA-V3 Web UI provides an intuitive graphical interface for interacting with Agents and managing task files.\n\n## Interface Layout\n\nThe interface is divided into two main areas:\n\n### Left Panel: Chat Area\n- **Conversation Interface**: Real-time interaction with Agents\n- **Message Stream**: Displays Agent responses, tool calls, and task progress\n- **Input Box**: Enter task instructions and replies\n\n### Right Panel: File Browser Area\n- **File Browsing**: View all files in the current workspace\n- **File Upload**: Upload files to the current workspace\n- **File Download**: Download files from the workspace\n- **Real-time Updates**: Files created or modified by Agents are displayed in real-time\n\n## Usage Workflow\n\n### 1. Create/Select Task\n\n1. Enter a **Task ID** in the top input box\n2. Click the **Confirm** button\n3. The system will automatically create or switch to the corresponding workspace\n\n### 2. Interact with Agent\n\n1. Enter task instructions in the bottom input box\n2. Press **Enter** or click **Send** to send the message\n3. The Agent will start executing the task, displaying progress and results in real-time\n4. View files generated by the Agent in the right file browser panel\n\n### 3. Human-in-Loop Interaction\n\nWhen the Agent calls the `human_in_loop` tool:\n\n1. **The chat box will flash red**, indicating that your input is required\n2. Enter your reply in the input box\n3. Click **Send** to submit your reply\n4. The Agent will continue executing the task based on your response\n\n> 💡 **Tip**: During HIL interaction, you can view files in the right file browser to better understand the task progress and make informed decisions.\n\n### 4. Copy Task\n\nAfter completing a task, if you need to save a copy of the current task:\n\n1. Click the **Copy Task** button\n2. Enter a new Task ID\n3. The system will copy all files from the current workspace to the new task\n\n### 5. Clear Task\n\nIf you need to delete a task and all its data:\n\n1. Click the **Clear Task** button\n2. The system will delete:\n   - All files in the workspace directory\n   - Conversation files in the home directory\n\n> ⚠️ **Warning**: The clear operation is irreversible. Please proceed with caution.\n\n## Video Demonstration\n\nThe walkthrough video is no longer stored in git so the repository stays lightweight.\n\n## Notes\n\n- Each Task ID corresponds to an independent workspace\n- Chat history is automatically saved and can be restored after page refresh\n- The file browser synchronizes file changes in the workspace in real-time\n- Supports multi-task switching by changing the Task ID and clicking Confirm\n"
  },
  {
    "path": "web_ui/web_intro_CN.md",
    "content": "# MLA-V3 Web UI 使用指南\n\n## 功能概览\n\nMLA-V3 Web UI 提供了一个直观的图形界面，让您能够轻松地与 Agent 进行交互并管理任务文件。\n\n## 界面布局\n\n界面分为两个主要区域：\n\n### 左侧：聊天区域\n- **对话界面**：与 Agent 进行实时交互\n- **消息流**：显示 Agent 的响应、工具调用和任务进度\n- **输入框**：输入任务指令和回复\n\n### 右侧：文件浏览器区域\n- **文件浏览**：查看当前 workspace 下的所有文件\n- **文件上传**：上传文件到当前 workspace\n- **文件下载**：下载 workspace 中的文件\n- **实时更新**：Agent 创建或修改的文件会实时显示\n\n## 使用流程\n\n### 1. 创建/选择任务\n\n1. 在顶部输入框中输入 **Task ID**\n2. 点击 **Confirm** 按钮\n3. 系统会自动创建或切换到对应的 workspace\n\n### 2. 与 Agent 交互\n\n1. 在底部输入框中输入任务指令\n2. 按 **Enter** 或点击 **Send** 发送消息\n3. Agent 会开始执行任务，实时显示进度和结果\n4. 在右侧文件浏览器中可以实时查看 Agent 生成的文件\n\n### 3. Human-in-Loop 交互\n\n当 Agent 调用 `human_in_loop` 工具时：\n\n1. **聊天框会红色闪烁**，提示需要您的输入\n2. 在输入框中输入回复内容\n3. 点击 **Send** 提交回复\n4. Agent 会根据您的回复继续执行任务\n\n> 💡 **提示**：HIL 交互期间，您可以随时查看右侧文件浏览器中的文件，以便更好地理解任务进度并做出决策。\n\n### 4. 复制任务\n\n完成任务后，如果需要保存当前任务的副本：\n\n1. 点击 **Copy Task** 按钮\n2. 输入新的 Task ID\n3. 系统会将当前 workspace 的所有文件复制到新任务\n\n### 5. 清除任务\n\n如果需要删除任务及其所有数据：\n\n1. 点击 **Clear Task** 按钮\n2. 系统会删除：\n   - workspace 目录下的所有文件\n   - 主目录下的对话历史文件（conversation files）\n\n> ⚠️ **警告**：清除操作不可恢复，请谨慎操作。\n\n## 视频演示\n\n为了减少仓库体积，演示视频已不再直接存放在 git 中。\n\n## 注意事项\n\n- 每个 Task ID 对应一个独立的 workspace\n- 对话历史会自动保存，刷新页面后可恢复\n- 文件浏览器实时同步 workspace 中的文件变化\n- 支持多任务切换，只需更改 Task ID 并点击 Confirm\n"
  }
]