From 332bbe2c86e28d39b17f7c735e27630a072714e8 Mon Sep 17 00:00:00 2001 From: Tools <> Date: Sat, 4 May 2024 16:18:49 +0200 Subject: [PATCH] Initial commit --- .github/lint.py | 25 + .github/package.py | 15 + .github/version.py | 74 +++ .github/workflows/initialize_data.yml | 54 ++ .github/workflows/linter.yml | 29 + .github/workflows/package_addon.yml | 71 +++ .github/workflows/package_preset.yml | 46 ++ .github/workflows/pr_main.yml | 60 ++ .github/workflows/pr_main_start.yml | 46 ++ .github/workflows/unit_test.yml | 28 + .gitignore | 30 + LICENSE | 674 ++++++++++++++++++++++ blender_addon_folder/__init__.py | 31 + linter/.pylintrc | 224 +++++++ linter/requirements_linter.txt | 1 + presets/.keep | 0 readme.md | 40 ++ releases/.keep | 0 tests/blends_sample/default_startup.blend | Bin 0 -> 798560 bytes tests/dependency.json | 11 + tests/launch_test_b3d.sh | 3 + tests/main.py | 54 ++ tests/requirements.txt | 2 + tests/unit_test/test_b3d_install_addon.py | 25 + tests/utils/__init__.py | 0 tests/utils/blender.py | 21 + tests/utils/blender_addon.py | 58 ++ tests/utils/container.py | 75 +++ tests/utils/forge.py | 51 ++ tests/utils/issue.py | 12 + tests/utils/misc.py | 47 ++ tests/utils/properties.py | 69 +++ 32 files changed, 1876 insertions(+) create mode 100644 .github/lint.py create mode 100644 .github/package.py create mode 100644 .github/version.py create mode 100644 .github/workflows/initialize_data.yml create mode 100644 .github/workflows/linter.yml create mode 100644 .github/workflows/package_addon.yml create mode 100644 .github/workflows/package_preset.yml create mode 100644 .github/workflows/pr_main.yml create mode 100644 .github/workflows/pr_main_start.yml create mode 100644 .github/workflows/unit_test.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 blender_addon_folder/__init__.py create mode 100644 linter/.pylintrc create mode 100644 linter/requirements_linter.txt create mode 100644 presets/.keep create mode 100644 readme.md create mode 100644 releases/.keep create mode 100644 tests/blends_sample/default_startup.blend create mode 100644 tests/dependency.json create mode 100644 tests/launch_test_b3d.sh create mode 100644 tests/main.py create mode 100644 tests/requirements.txt create mode 100644 tests/unit_test/test_b3d_install_addon.py create mode 100644 tests/utils/__init__.py create mode 100644 tests/utils/blender.py create mode 100644 tests/utils/blender_addon.py create mode 100644 tests/utils/container.py create mode 100644 tests/utils/forge.py create mode 100644 tests/utils/issue.py create mode 100644 tests/utils/misc.py create mode 100644 tests/utils/properties.py diff --git a/.github/lint.py b/.github/lint.py new file mode 100644 index 0000000..d4d0138 --- /dev/null +++ b/.github/lint.py @@ -0,0 +1,25 @@ +import sys +import os +import pathlib + +from pylint import lint + + +if __name__ == "__main__": + folder: str = '' + for v in sys.argv: + if '--module=' in v: + folder = v.replace('--module=', '') + + if folder is False: + print(f'Module folder not set.') + sys.exit(1) + + run = lint.Run([f'--rcfile={pathlib.Path(os.getcwd(), "linter", ".pylintrc")}', folder], + do_exit=False) + + if run.linter.stats.fatal or run.linter.stats.error: + print('Pylint failed.') + sys.exit(1) + + sys.exit(0) diff --git a/.github/package.py b/.github/package.py new file mode 100644 index 0000000..0778b4e --- /dev/null +++ b/.github/package.py @@ -0,0 +1,15 @@ +import glob +import os + + +def get_folder_name(): + addon = glob.glob(os.getcwd() + "/*/__init__.py", recursive=True) + + return os.path.basename(os.path.dirname(addon[0])) + + +if __name__ == "__main__": + name = get_folder_name() + + # Keep the print value, it's request to output a string value available + print(name) diff --git a/.github/version.py b/.github/version.py new file mode 100644 index 0000000..f086507 --- /dev/null +++ b/.github/version.py @@ -0,0 +1,74 @@ +import os +import re +import sys + +from pathlib import Path + + +class SetupVersion: + def __init__(self, version: str, folder: str): + self.addon_file = Path(os.getcwd(), folder, '__init__.py') + self.tag = self.conform_tag_to_blender(version) + self.update_addon_init() + + def update_addon_init(self): + """Simple function to update the bl_info to set the Git tag release""" + regex, update = r'[0-9]{1,2}\, [0-9]{1,2}\, [0-9]{1,2}', '' + + try: + with open(self.addon_file, "r") as f: + i = 0 + lines = f.readlines() + for line in lines: + if ' \'version\':' in line: + print('Actual set : ', line) + line = re.sub(regex, self.tag, line) + lines[i] = line + update = lines + print('Update version : ', line) + break + i += 1 + + with open(self.addon_file, 'w') as f: + f.writelines(update) + + except FileNotFoundError as exception: + print(f'Can\'t find a file :\n\t{exception}') + + @staticmethod + def conform_tag_to_blender(version): + """This function convert all '.' with a coma and remove the alphabetic entry, to be ready with blender 'bl + info' value """ + version = re.sub(r'\.', ', ', version) + version = version.replace('v', '') + + return version + + +class SetupError(Exception): + """No tag or folder name valid""" + pass + + +if __name__ == "__main__": + tag, name = '', '' + + for value in sys.argv: + if '--tag' in value: + tag = value.replace('--tag=', '') + print(f'[UpdateVersion] Set the tag {tag}') + + if 'name' in value: + name = value.replace('--name=', '') + print(f'[UpdateVersion] Set the folder {name}') + + try: + if not tag or not name: + raise SetupError + else: + print(f'[UpdateVersion] Set the tag {tag}, for "{name}"') + bump = SetupVersion(tag, name) + + except SetupError: + print(SetupError.__doc__) + sys.exit(1) diff --git a/.github/workflows/initialize_data.yml b/.github/workflows/initialize_data.yml new file mode 100644 index 0000000..a6449bd --- /dev/null +++ b/.github/workflows/initialize_data.yml @@ -0,0 +1,54 @@ +name: Create base release + +on: + workflow_call: + outputs: + version_type: + description: "Give the bump type for this release" + value: ${{ jobs.init-release-data.outputs.version_type }} + version_number: + description: "String about the tag version, integer only" + value: ${{ jobs.init-release-data.outputs.version_number }} + version_draft: + description: "Boolean if the release are draft or not" + value: ${{ jobs.init-release-data.outputs.version_draft }} + version_name: + description: "Number version with a prefix v." + value: v${{ jobs.init-release-data.outputs.version_name }} + +jobs: + init-release-data: + name: Initialize all data about the package + runs-on: ubuntu-latest + outputs: + version_type: ${{ steps.bump_setup.outputs.type }} + version_number: ${{ steps.semantic_setup.outputs.version }} + version_draft: ${{ steps.semantic_setup.outputs.draft }} + version_name: ${{ steps.semantic_setup.outputs.version }} + steps: + - name: Get the Semantic tag Version + id: get_semantic_setup + uses: oprypin/find-latest-tag@v1.1.0 + with: + repository: ${{ github.repository }} + releases-only: true + prefix: 'v' + token: ${{ secrets.GITHUB_TOKEN }} + + - name: From all use case, get the Tag version + id: semantic_setup + run: | + tag=${{ steps.get_semantic_setup.outputs.tag }} + if [ "${{ github.event.action }}" == "closed" ]; then + echo "Close the pull request, get the previous tag" + echo "::set-output name=version::${tag:1}" + echo "::set-output name=draft::false" + elif [ "${{ github.event.action }}" == "opened" ]; then + echo "Create a new tag from a new pull request" + echo "::set-output name=version::${{ steps.new_semantic_setup.outputs.version }}" + echo "::set-output name=draft::true" + else + echo "Update the pull request, keep the tag value" + echo "::set-output name=version::${tag:1}" + echo "::set-output name=draft::true" + fi diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 0000000..9a37468 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,29 @@ +name: Pylinter + +on: + workflow_call: + push: + branches-ignore: + - main + - develop + + +jobs: + unit-test: + name: Python Linter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install the linter app and set package name + id: config + run: | + echo "::set-output name=folder::$(python '.github/package.py')" + python -m pip install --upgrade pip + python -m pip install -r linter/requirements_linter.txt + - name: Execute Pylint + run: | + cd ${{ github.workspace }} + python '${{ github.workspace }}/.github/lint.py' --module=${{ steps.config.outputs.folder }} diff --git a/.github/workflows/package_addon.yml b/.github/workflows/package_addon.yml new file mode 100644 index 0000000..363415e --- /dev/null +++ b/.github/workflows/package_addon.yml @@ -0,0 +1,71 @@ +name: Package Blender Plugin + +# How to start the Github Action +on: + workflow_call: + inputs: + num_version: + description: 'Get the desired number version' + type: string + required: true + default: '0.0.0' + name_version: + description: 'The release name used' + type: string + required: true + default: 'v0.0.0' + draft_version: + description: 'Info about the release, publish or a draft' + type: string + required: true + default: 'false' + + +# Execute this command +jobs: + make-archive: + name: Make Addon Package + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + + - name: Setup package variable + id: folder + run: | + echo "::set-output name=folder::$(python '.github/package.py')" + echo "::set-output name=package::$(python '.github/package.py').zip" + + # Update the bl info version, update the init file and push if needed + - name: Change version number in the bl info addon data + run: python '.github/version.py' --tag=${{ inputs.num_version }} --name=${{ steps.folder.outputs.folder }} + + - name: Commit the previous update + uses: actions-js/push@v1.3 + if: ${{ github.event.action }} == 'opened' + with: + github_token: ${{secrets.GITHUB_TOKEN}} + author_name: Moderlab + author_email: a.vaillant@moderlab.com + message: '[Bot] Bump to ${{ inputs.num_version }} version.' + branch: develop + force: true + + # Make an archive with the plugin source only + - name: Create zip archive release + run: | + cd '${{ github.workspace }}' + zip -r '${{ github.workspace }}/releases/${{ steps.folder.outputs.package }}' ${{ steps.folder.outputs.folder }} + + - uses: actions/upload-artifact@v2 + with: + name: ${{ steps.folder.outputs.folder }} + path: ${{ github.workspace }}/releases/${{ steps.folder.outputs.package }} + + - name: Update the github release + if: github.event_name == 'pull_request' + uses: johnwbyrd/update-release@v1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + files: '${{ github.workspace }}/releases/${{ steps.folder.outputs.package }}' + release: ${{ inputs.name_version }} + tag: ${{ inputs.name_version }} \ No newline at end of file diff --git a/.github/workflows/package_preset.yml b/.github/workflows/package_preset.yml new file mode 100644 index 0000000..44277ab --- /dev/null +++ b/.github/workflows/package_preset.yml @@ -0,0 +1,46 @@ +name: Package Blender Plugin + +# How to start the Github Action +on: + workflow_call: + inputs: + name_version: + description: 'The release name used' + type: string + required: true + default: 'v0.0.0' + + +# Execute this command +jobs: + make-archive: + name: Make Addon Package + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + + - name: Setup package variable + id: folder + run: | + echo "::set-output name=folder::$(python '.github/package.py')_preset" + echo "::set-output name=package::$(python '.github/package.py')_preset.zip" + + # Make an archive with the plugin source only + - name: Create zip archive release + run: | + cd '${{ github.workspace }}/presets' + zip -r '../releases/${{ steps.folder.outputs.package }}' '.' + + - uses: actions/upload-artifact@v2 + with: + name: ${{ steps.folder.outputs.folder }} + path: ${{ github.workspace }}/releases/${{ steps.folder.outputs.package }} + + - name: Update the github release + if: github.event_name == 'pull_request' + uses: johnwbyrd/update-release@v1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + files: '${{ github.workspace }}/releases/${{ steps.folder.outputs.package }}' + release: ${{ inputs.name_version }} + tag: ${{ inputs.name_version }} \ No newline at end of file diff --git a/.github/workflows/pr_main.yml b/.github/workflows/pr_main.yml new file mode 100644 index 0000000..0c7921c --- /dev/null +++ b/.github/workflows/pr_main.yml @@ -0,0 +1,60 @@ +name: Create addon release + +on: + pull_request: + branches: + [main] + types: + [edited, synchronize, closed] + + +jobs: + init-release-data: + name: Initialize all data about the package + uses: Moderlab-Production/BlenderTemplate/.github/workflows/initialize_data.yml@main + + unit-test: + uses: Moderlab-Production/BlenderTemplate/.github/workflows/unit_test.yml@main + + py-linter: + uses: Moderlab-Production/BlenderTemplate/.github/workflows/linter.yml@main + + release-package-addon: + name: Generate archive package addon + needs: + - init-release-data + - unit-test + - py-linter + uses: Moderlab-Production/BlenderTemplate/.github/workflows/package_addon.yml@main + with: + num_version: ${{ needs.init-release-data.outputs.version_number }} + name_version: ${{ needs.init-release-data.outputs.version_name }} + draft_version: ${{ needs.init-release-data.outputs.version_draft }} + + release-package-preset: + name: Generate archive package preset + needs: + - init-release-data + - unit-test + - py-linter + uses: Moderlab-Production/BlenderTemplate/.github/workflows/package_preset.yml@main + with: + name_version: ${{ needs.init-release-data.outputs.version_name }} + + publish-release: + name: Publish the Github Release + needs: + - init-release-data + - release-package-addon + - release-package-preset + runs-on: ubuntu-latest + steps: + - name: Update/Publish the release + uses: tubone24/update_release@v1.3.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.init-release-data.outputs.version_name }} + with: + release_name: ${{ needs.init-release-data.outputs.version_name }} + body: '' + prerelease: ${{ needs.init-release-data.outputs.version_draft }} diff --git a/.github/workflows/pr_main_start.yml b/.github/workflows/pr_main_start.yml new file mode 100644 index 0000000..99a5157 --- /dev/null +++ b/.github/workflows/pr_main_start.yml @@ -0,0 +1,46 @@ +name: Create addon release + +on: + pull_request: + branches: + [main] + types: + [opened] + + +jobs: + init-release: + name: Generate the release + runs-on: ubuntu-latest + steps: + - name: Setup bump release + id: bump_setup + run: | + if [ ${{ contains(github.event.pull_request.labels.*.name, 'release:major') }} == true ]; then + echo "::set-output name=type::major" + elif [ ${{ contains(github.event.pull_request.labels.*.name, 'release:minor') }} == true ]; then + echo "::set-output name=type::minor" + else + echo "::set-output name=type::patch" + fi + + - uses: actions/checkout@main + + - name: Create new Semantic Version + uses: zwaldowski/semver-release-action@v2 + id: new_semantic_setup + with: + bump: ${{ steps.bump_setup.outputs.type }} + github_token: ${{ secrets.GITHUB_TOKEN }} + dry_run: true + prefix: v + + - name: Make the github release + uses: ncipollo/release-action@v1.10.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + prerelease: true + tag: ${{ steps.new_semantic_setup.outputs.version_tag }} + + unit-test: + uses: Moderlab-Production/BlenderTemplate/.github/workflows/unit_test.yml@main diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml new file mode 100644 index 0000000..6a2e732 --- /dev/null +++ b/.github/workflows/unit_test.yml @@ -0,0 +1,28 @@ +name: Unit Test + +on: + workflow_call: + push: + branches-ignore: + - main + - develop + + +jobs: + unit-test: + name: Unit Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Setup python to execute all Unit Test + run: | + python -m pip install --upgrade pip + python -m pip install -r tests/requirements.txt + + - name: Start all Unit Test + run: | + cd ${{ github.workspace }} + python tests/main.py \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9da9f05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +### PyCharm ### +.idea/ +.run/ + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +**/__pycache__/ + + +# Unit Test # +*.zip +tests/blender/** +tests/blender/*.dmg +!tests/blender/.keep + +### Blender ### +*.blend1 + +### Unreal ### +tests/unreal_sample/DerivedDataCache +tests/unreal_sample/Intermediate +tests/unreal_sample/Saved + +# Secret file +**/token.txt + +# Virtual Environment +**/venv/** +venv/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/blender_addon_folder/__init__.py b/blender_addon_folder/__init__.py new file mode 100644 index 0000000..b6aa4d0 --- /dev/null +++ b/blender_addon_folder/__init__.py @@ -0,0 +1,31 @@ +import bpy + +bl_info = { + 'name': 'Addon Name', + 'description': 'Add your description', + 'author': 'Moderlab, Aurelien Vaillant, Nicolas Salles, Jeremy Duchesne', + 'version': (0, 0, 0), + 'blender': (3, 0, 0), + 'doc_url': "", + 'tracker_url': "", + 'support': "COMMUNITY", + 'category': 'Moderlab', +} + +modules_class = [ + # Main Property +] + + +def register(): + for cls in modules_class: + bpy.utils.register_class(cls) + + +def unregister(): + for cls in reversed(modules_class): + bpy.utils.unregister_class(cls) + + +if __name__ == "__main__": + register() diff --git a/linter/.pylintrc b/linter/.pylintrc new file mode 100644 index 0000000..36d197b --- /dev/null +++ b/linter/.pylintrc @@ -0,0 +1,224 @@ +[MAIN] +analyse-fallback-blocks=no +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED +disable= +enable= +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) +exit-zero=no +extension-pkg-allow-list=bpy +extension-pkg-whitelist= +fail-on= +fail-under=10 +#from-stdin=no | not working ? +ignore=CVS +ignore-paths= +ignore-patterns=^\.# +ignored-modules=bpy, + mathutils, + bl_math, + bl_ui, + bl_operators +#jobs=0 | multiprocessing, get errors +limit-inference-results=100 +load-plugins= +msg-template= +output-format=colorized +persistent=yes +py-version=3.10 +recursive=yes +reports=no +score=yes +suggestion-mode=yes +unsafe-load-any-extension=no + + +[BASIC] +argument-naming-style=snake_case +argument-rgx= +attr-naming-style=snake_case +attr-rgx= +bad-names=foo, + bar, + baz, + toto, + tutu, + tata +bad-names-rgxs= +class-attribute-naming-style=any +class-attribute-rgx= +class-const-naming-style=UPPER_CASE +class-const-rgx= +class-naming-style=PascalCase +class-rgx=^MLB_[A-Z]{2}_[a-z_]+$|^[A-Za-z]+$ +const-naming-style=UPPER_CASE +const-rgx= +docstring-min-length=-1 +function-naming-style=snake_case +#function-rgx= +good-names=i, + _, + ob, + wm, + me, +good-names-rgxs= +include-naming-hint=no +inlinevar-naming-style=any +inlinevar-rgx= +method-naming-style=snake_case +method-rgx= +module-naming-style=snake_case +module-rgx= +name-group= +no-docstring-rgx=(poll)?|(execute)?|(invoke)? +property-classes=abc.abstractproperty +typevar-rgx= +variable-naming-style=snake_case +variable-rgx= + + +[CLASSES] +check-protected-access-in-special-methods=no +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make +valid-classmethod-first-arg=cls +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] +exclude-too-few-public-methods= +ignored-parents= +max-args=5 +max-attributes=7 +max-bool-expr=5 +max-branches=12 +#max-complexity=10 Option not working +max-locals=15 +max-parents=7 +max-public-methods=20 +max-returns=6 +max-statements=50 +min-public-methods=0 + + +[EXCEPTIONS] +overgeneral-exceptions=BaseException, + Exception + + +[FORMAT] +expected-line-ending-format= +ignore-long-lines=^\s*(# )??$ +indent-after-paren=4 +indent-string=' ' +max-line-length=119 +max-module-lines=1000 +single-line-class-stmt=no +single-line-if-stmt=no + + +[IMPORTS] +allow-any-import-level= +allow-wildcard-with-all=no +deprecated-modules= +ext-import-graph= +import-graph= +int-import-graph= +known-standard-library= +known-third-party=enchant +preferred-modules= + + +[LOGGING] +logging-format-style=old +logging-modules=logging, + + +[MISCELLANEOUS] +notes=FIXME, + TODO +notes-rgx= + + +[REFACTORING] +max-nested-blocks=5 +never-returning-functions=sys.exit,argparse.parse_error + + +[SIMILARITIES] +ignore-comments=yes +ignore-docstrings=yes +ignore-imports=yes +ignore-signatures=yes +min-similarity-lines=8 + + +[SPELLING] +max-spelling-suggestions=4 +spelling-dict= +spelling-ignore-comment-directives=fmt: on, + fmt: off, + noqa:, + noqa, + nosec, + isort:skip, + mypy: +spelling-ignore-words= +spelling-private-dict-file= +spelling-store-unknown-words=no + + +[STRING] +check-quote-consistency=no +check-str-concat-over-line-jumps=no + + +[TYPECHECK] +contextmanager-decorators=contextlib.contextmanager +generated-members= +ignore-mixin-members=yes +ignore-none=yes +ignore-on-opaque-inference=yes +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init +ignored-classes=optparse.Values, + thread._local, + _thread._local, + argparse.Namespace +missing-member-hint=yes +missing-member-hint-distance=1 +missing-member-max-choices=1 +mixin-class-rgx=.*[Mm]ixin +signature-mutators= + + +[VARIABLES] +additional-builtins= +allow-global-unused-variables=yes +allowed-redefined-builtins= +callbacks=cb_, + _cb +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ +ignored-argument-names=_.*|^ignored_|^unused_|^self|^context|^event +init-import=no +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + +#enable-all-extensions= +#errors-only= +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= diff --git a/linter/requirements_linter.txt b/linter/requirements_linter.txt new file mode 100644 index 0000000..02ba427 --- /dev/null +++ b/linter/requirements_linter.txt @@ -0,0 +1 @@ +pylint~=2.14 \ No newline at end of file diff --git a/presets/.keep b/presets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..7c91ccd --- /dev/null +++ b/readme.md @@ -0,0 +1,40 @@ +[![Python 3.10.2](https://img.shields.io/badge/python-3.10.2-sucess.svg)](https://www.python.org/downloads/release/python-3102/) +![Blender](https://img.shields.io/badge/blender-3.1.0-sucess) + +# Blender Addon +This repository is a toolbox to create a new blender addon. To used-it, clone this repository and rename the folder "blender_addon_folder" with your addon name. +It's important to change some files : +- [x] Update the file "tests/main.py", line 29, set your addon name. + ```python + # Prepare Blender and Unreal dependency + generate_archive(archives, 'blender_addon_folder') + ``` +- [x] You can remove the folder "presets" and disable the workflow (`.github/workflows/pr_main.yml`, line 38 and 53) + + +> ⚠️ It's more easy to use the "_" with your addon folder name, the "-" character can be problematic with python use. + +All features covered with this template are : +- [x] Generate addon release (.zip archive) +- [x] Generate preset release (.zip archive) +- [x] Update addon version (bl info) with tag name +- [x] Execute unit test with Github Action (check if the addon can be installed with blender) +- [x] Configuration with Pycharm to test locally + + +## Unit Test +All unit tests call docker image [stilobique/blender](https://hub.docker.com/repository/docker/stilobique/blender). It's a simple ubuntu image with blender compile. +If you want change the blender version tested, edit the `main.py` inside the `tests` folder ; change the tag version with your requested tag. + +`````python +class Container(enum.Enum): + """Enumerate about the Geometry node""" + BLENDER = ContainerObject(name='Blender', image='stilobique/blender', tag='3.1.2') +````` + + +# Addons/Plugins dependency +Update json file `tests/dependency.json` with name, archive and repository Github path. Each entry require `archive +name`, the repository url path '{owner}/{repo}' and optional parameter if the release needed to be a prerelease. + +> ⛔ The `moderlab_plugin` need to be on last entry. diff --git a/releases/.keep b/releases/.keep new file mode 100644 index 0000000..e69de29 diff --git a/tests/blends_sample/default_startup.blend b/tests/blends_sample/default_startup.blend new file mode 100644 index 0000000000000000000000000000000000000000..091f4ccdc045b618a2181d53fc8b06de76d71ac4 GIT binary patch literal 798560 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

>JcrY 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≥Lx%(#1*)3re5`YHpRrYM}Xg ze|$=6z8?IIJb&4?JMqsLBfDPaFGu1pgGQAW^~sJ1XW=gczkdB?sz=Y)W8VGwdPb-0 z@h$h+eGkiS;w|xtRx4aFqK(3BEA58O7||oRgrCGuH~w#Mj7h_%^7^-Ve%@U?Kkpkn zKkp8c2K#vb*G-CgabJjfVdwSd>-9oJwOZx_0dkeP+`D;4gtNpC&DR5dW$_a53HxY@ z&r#viAh@T@d^B@ z@)`1dX;XZ5g-?epmqR!2hSLDnlk!Ydwh01)fFO{Ifa?7Y$oS(ShvaqE&ip)X&A}0W zy!@1O{E__)_{DHx2r}eNzd$HapOQ|?;*X)k9}Q#)Zh8H(Bf?o4hoJd-z>oZ5gEa{x zJe1DYqk44wk$E3>{4s4O6n`99{&d|2x1FxedZ+n1s>!DQ$G^ex#wVLJe4T*ljJE;5vim>q z8L)jc#pm2Fg->wQ51+uVDxWydo8oiye}vCL_ym4c`NZ|Qe?G0YdAU%=+Z7$!#@z2V#pkH->5%2~h;>KA;}iH*WFX_d;-6!e8zlV+7zF2 z!ly%)&m-0y5sy#cSH>sekI|b4j6ZIeyr{qMqj`+hj?LLN&E{>iyUTJW{&=(*Z;|*J zY^J|d@aqpZdo3tG7(Pw6{Du)GCAbdKM=O5p8N;>|?{s#PF zxG?Fs67?nY%cf=V$3Wtb2D${lynfjc;Vj+fQ2Y`2kzYJe{E>Oj#vfZr+}+gzcHnM9 zK0rpLuuZec#2=rj6?NN5dtp09lHMDX_lu7-{%`PjlZKDu^_b(0U*LG-=Q-YZt4V`f zc>hf%Mcss>jz4m}u=8QZAA|d4d&*mxh-%%KJ(hVjn!*5@yExS@fL}n!DjkP z1;74qvttd_4Ob)u0YTuPM?m#{5`P@j3Kpvhu%Ir)c!m;xe8(y2_#^up@QdNX3@iQ^ zcjS8o;L-N2e&1{*kR!iXf3JY?Bfof{_#^Y4jX#nu*&pm6yQkH1V~1oXuut`r;fkuy zKRza=ozgVaFfm zz9;v8z`U-V)B9I}U)lX1_zc)Sn&LC~XW?@YK7n6VK5?Em#b^9o;d2l^fnQZValP)J zPpfTSE|&2&2NvI-z`7&CS&X* zuPUE0-yjJ@w9@~*9!gR*INUtUYnKF=WF~h@t5;$%D1uJ>*6o>#-|)(YnYM~1Ox#=pacQc z`x*bW%wHbtd+Dwg#r`r$neKRz`nhG2yzd_;>%O?Zjv5|le|aeL_1fk+2l&hIH=6R7 zL-ChkE-EeRlN}Mx!e0h{{rbyPkN#c(^N#s?x9{Dn@4bvp+2b$bvxnpk<=r?B9_ol= zo3p7^^t}RCw&VkV4l`+R9na7EB+t*gmgnbv+@!(Bc>hOC3VmSbs26rV z?D=}5-;w!1z`U-V(|kSPR~9b;pCQ{vQ+#&i``VVyn%6Dj6Zlo-Gvf2SDLw!ou9z3DxV?uyG`*qzgPNCOK5#QfnQZVBle$~;xiUL zEuDSzpTMswpE3KvP4PJ=d=A7X@TVf^t8?f^^0${aBhe>_CukHzB`MSfX!yTl)} znAF47u}sMd0)l`b&=Udb7R`LUha6*O7Ugw^6uWq!=Ia&3IJg;z-hW?8a~}P5#eteT*K5(L>-k{% zJqqk^z%NEy>6nN+5wE6HHZ@Ea&({ki{%D}n{|Udm#S!5w;*Y?O{9=PO2_!sJpRc#C zZ-05)_{>aa`|&F$x6e$CPtVkLnhX8qH^SJm&9AaW+hnjv{N;R`%CocLZQ?H%V^a;^ zDkdv3f`A|(2oM6+UoM-kSL`phQvPT;uEq29==m0RUQte6bSz%zT6u8#%kVdv@|WW+ z@_s#QdqsV+l|T;uGVmMJUyg3;*IzzuYW%|5J~Em?X`#RTrXl#t;j2x%#NR8jt!mo^ zziK!Y`_8V(OI{EV1O$Oz2+(NcY@2*x{PMa(dY5gHzl`x+lrK+v`^$&-uHZrGFB8T~ zmQ1%Fe#bR0qVeUN^;+Z0@Hd+Bmm~3)9V;yAlN}Mx!e0h{gZj(CEra;WBOChudJFr@ zdDntJ$lI8OqG$`9zpdz1;x8Bba7Ff(-7fxe7L$6o7MZDR7X$KgtFY9#8ejk zGVtryU#5EW^We-oo(DHan{8ip<&}EQPx|Qg-0`>5`jL4Xoox?s@-_?GF?HW&ccgOh zD~$geTxQbnQj=I6gZ$j^U&fS><ddfpM&3p=m>JUD91Pv`HD z=h-YWc{XnOw{phL>G?$9M|O_uos~mIs*QdL&$@^{4LX+vDs#vWgwr0lREN%eUw;zG$au zm&DIpyQ!ZS{OV(tz7CfgtVjp~f`A}k5TG7$(C@djO5<~Bw0qCjv(L|_OYs^Vix;|9 zJ~*ClvAWN;&3rw*Md^?AUeAK#xota+4}SxGF}pl`OEQUc^(`* z7WcbW0y+50z^`9_nd;H=^_X|e*DL>i3pB~5bRR{}sky%;ORi7m{XIRPJ=Xu2eC(kw zGV8VkY}#%yxnRopzu^v(M%zsqyqD+ay_@IfUCHzF{?w$w6}xG@y zov(MOKGSi(IorPG{!4Ct@%5j%>Dbrac+-Z7?KjWA=otO|bsYELPA&JY9pqs`{2Zfp z06(&Gd!KGfgqJ*3U3Wgm_Jz9bJwI%vUv3X6xr#^f?GJ}K;P0o72xo~~n!5-5%3@(S zS8>ia#pm4r$lL?Vmd_*Btpsx56Zlo-6W8wk`Gf}fX(X{~2N>|@r;Z3`!6)#m%4f)Z za8rDCg-?eppGT}aA|9W>uPUDr`%+Eu848~cS>Vr49TAUD;8&H;n0?}=_#72J9kP5L zvF?a?d;-6!eB$1wDLw;12=6 zGCq^Jdsmw=ihkzq=~(2*`pKOaccDg|v@jO=M|SY8PJNIyvB+(vT@p)!&GeTFe*NKQ z$Btl@k_rNXfFMwcfa?7u7Fmi?iNIpD9}7egw;4(-@^*gtO!q)7(AaM}D!vngkLaO6TrTJvtW2ydxHA4g+1x8vVcO z%A+;MusOTO=17m8vB<}eEb2~lW!o|J`0*yQRn1l0YW&}D!lco~oW6r&k8k7Hs2Qrhe5?X2rQnq=rlF&Sr{-ZtpJ#i{}a zx&poP`dkdQn0751`k81BzUUBp7Fcy$4qL6e9{r_d*k_~@ejL6@!j`k=vfbwH?=O#I zAT83v-EWTHBz{?%-8LUc_(88MK50Jk_R}``2?BzEAW)9LVXa4yQ2S}>-(lRbXRniH z&QH;Ia?LfV{8(0^x4)csd|S4q`&)Ot=sUed^*qr2^4ni|ukz<{O;7pDx*7c4+?7hE z$6{KHc@pq9^896s4IPty+0^%!A9cs8Z+`w~Z(U01aVibOUpCMs_*woemyQT$;V%Qf zB7gZQZ`{h-#;+Q>z7kIe2Zq{_+{)Q(HSzBP%AiZON)xWlN#I{MMoqt4gir zUbhuqDC5i4j`D1)+BO+qu7*=F*42zwqyzy$KoC#}sNQe3eTB+2`<+}D>tcVIq)NKu zjK7SU{c`>~jz9q`NRm#qYH@RxyKk-vP$H9Hc2`SM$LX8dKUM?dSryyICHymzmk z@8nY4rq{DB$5eRlp0OLW)~3+~#{Z39X42rLoJRa?%bWPwmN)RTEw3|a@LJygtH-C_ ze~0@*)C)VW`>e}h`f6h1C_g#uq?>8^DKC-Oxg}9wC+gWb@Jrjdsq*~GZyme#v~eA4 zyXc~4v|stSU*iFAYmp%6q-!IR-SfcYdHhfqalOulUxfkF^JfmN;vZ&9# zQxWHXV|@O%@R`LQJRr3a$R&I-ewF#;>v;csLWBG?ka?aCFyPNm9TCogPvBRT&yf4$ zrudxylANEGEuTlMTM6XAC-AGvXT*M0Q+&q4Cn!=W`14aogtOoi_*LaIX8*V;KIeo_ zhb*5*tUDqepTMswpSaIyiqA;+bjSjKe(H#Ld;-6!e1?3#+7zE%;nN|@=Mn3Uh{q@J zE8`P!$>?WC>+y&B&%JP5a%Fd7y0a~-Q2Ca^xa1$(fxPlsvJ(1UJA8@6C5!uO*im^Z zamjLwdgGimP}w2~2m*pY0RpP`lelC7HkCIoR+3my2;;Xyc?aKbd2vbhH{ch;g`s02 zZ~6(+hWeCrS{9cKC0=77OK{8UmmLw#(l~^E?uGFqzu3m|5*|vQd!c%CT#|W5T+$o{ zy0ls!9e)yW%lx|BXLX|)yMA2Kjc-1)LR|9jY_)nz^kR-np3Cvbb4(ij(!?9%`%N1B z!ldDUnKb$t@BfKOQ9ZSv-ob}@Vdr(@lK%I=GI2?H2Ol6;DeTHm9TCnFKgXzi#Q2e& zn`ehy+1W8W#~O9o*j3E7(l57VG3P+8VGbF<-%lM8&f*#d{LM})KB6Zlo-6Mb`2e2xmA4p}~rSa(D`K7n6VKH+0E#b+RVI%I)A zKXpVrK7n6VKH)1j#pir1{ikKi=Mn2x0y$i7fnQZVanI8fpRw=>ic|{z{L~TQEcgU| zRr!qh-nA({=Y&s(ET2cLJ0c#Rz^{x?#3+M%`j1ggZ_VmaV~cjbv-i=h*5%4KAK<6& z$HI*gqb$B2z>dmOiBXng)EnmkELn;Q0)oInhQMQ0d+}~Q6HUqM4tu|wua(3|s)1Mh z>?FOL@7Gl&MX?aIi;l$$T`TReeZ8Ialz!AoXP;Ud{I^(Dfd#c;ywAiamnj|0VxE=s z*L%HZ1kZliaYFbT@QcwNIwp>5`U%ozmfLSr!!+uhZD*dH9G7P&!DDfMYbB7Q`y7f< z#*82N#RhAVNboO>QNmx2?(W-Pp4ipuLalyMZAP#ww}Q9jZFB{C=d~?H>y5wMk*0}lu#VVf^)>Cmx=EYFFH5s~>;nlu=;dRE?MURr}NyqgdHMxMWHwWWT7e%aLbm;HD1MdB|T=o0+U=ensQ!ddvs zz^}+(uKaGkeSQ1OJGaeD{N|2re3pza zTi@Nasd{-CU#^E&7IV)!WmOOm1O$OX1gKlI9MzHUR!cp1+Lan!bU`Q=gJf zeSg^>Uk=4zHjpK_<@L*s2xs9h1HU4Fx$ND1$@ubZ1NqB4wq2IhvEmkOMtSGZJMuPG ztW=3T+`>TtO){wfFMwe01YGA z@nw?B>kc2t`O8NXD@%LG2jqpWmGo`#z1lzZ^>)_TZ=~X8KB=?MY#i|aVpSfC%BK8f zyklv}l4<%b-i!EKFKV1TweF2C=Z`mId>Q^mp1*9L(bD)Rb+W1NFZ<)m@dYw}*_s65 zm$z66gZPSUf~cg08OU%$V?@#S|7cJkN#Sqg`ODUwp}vHE*|f}Gj>KO!&?Wfg^~;V3XW=gczkdB?sz<+*lzA_D zC#kPNulPLKqyJ9QB}=Z?_jXiIm2V}|_ZIVh@fzd*2BAsAQ+fSA`5mM`=68_(h~Gha zuStV@c>lke6m{di5cR^&>%Nn;?0tsa@5=j_fO)ZhX(f;&e&~IMz>n-4*E`7A`s{Pc zu#cwr424e%f9^d#`T|ExWx*%#tI8+N^QQO=_RINcnab;fdh-eVs`44|^}2sPt+si& zNZzmIz*3)2;8&H;ko(=H`0NUw1Mvy`s`44J|I`$pq3}5npTMswpE3KvP4PJ@d=A7X z@TZWVz@ALOyo@;LE2Cskxt9vkD4Is$202jyEnhY4~dMTu$^a9B=#q#~Z)T@y73&G`gGjf5)V#n%b}5d%*R= z&W9a;jJ_rJf56<>XLUQ*-&14!%I^QbXTbK+7@yw|J_q8H@vF)w&hy6jykGbnh)>3^ zDxbJs_s^%*HZK>;c$))D-nAA!f+MD~bp533E%2+#XUzR>Q+&<|pAJ#=`2>Dd`3%^9 zYKqTD_#B8&;8&H;kp1AM`0NUw1Mvy`s`82ZnWp#*h0lTb1b$WdjQPH_DLzMq&w=;^ zer0?j{uqr67JnSsFnQ68qj8O_9uCYKpSdD$WA%zn{P9(0yhY+?MLt-y?Sfx5oa&4f zRX1gk6a)l;gA4)H`^~n`QjLBP#UH89Mf?S+6L&KV7Io_s4=UPcO49!-@1wTTi&Yj2 zwhlG^_ZWVzg&i@y9^okDyVdMSZd(!dV(8r1&H7Bfof{_#^Y~#~<;I9A5+2 zfxn&BX;;4+hjm-70zIo@~|#~Z)F@y0t$ z8tmi!U+4YbT(bG&%7_uKLcOr_`tiqRrw6L z-))M|`7g-%X$kdt#JZJ04*e(atIB7@{!>$Y#=<8kQYrZJQ%8ie;1l>&uPUFopJ|HENceQf0)Kw$hyC)W zC-5ud6Yyi3fEL2MpAMv|! ze;tQ>P{tom^5T!|Z@@1`TZa{Yj5o>m3SckA{jHTij>aJ<{s{cYFCHlV$h`aUM|FtA z?s05NVF&Iu_Me*KGY~!p;uH8)U6AP5Koxd>2?cwl`mJ?|aq zj_TCk@Eq)pwwI!RHm>7MNoqn@z|9k0?#2*bbj8A_5>xgg` z@kiiCesMqXNBGOZqQ3p*$?5*)>7h~DRfb(*Bc)g7ZFB{C=e55aZxeqx-=^qXt-grA zTpg=?Tzea<>=gtA0YShbVEtv<_6W7)b%*qxfz#DO-}YATDp;Dn_Ox^#sCHNUneQVM z2|vDQhuN-uWR>N9#U7jVHo6(Xymru@g_^IoWXW{<;dfl~BK|&l+gn$@EBUWjOdI_F znD+vIBhO#fj*c!!eF^=tX_>zqioa~2OYkEM{lyXCEc|8QH>kfH-C+F6KECg@b9$i1 zTg>OL^Uk5G@-}9nDB7ZJGT18qa@L-F`zl`-f4Ll^-Z&STscaVn1OY)HgMf0cX4^-r z%?H}^Ep}Wkr8D)nSZIgte<|a4@BDuoG|`xbg@a}j!A=b?0o3Yw|rOT{{i!?eZ$_Z1aia=+0#7ZS2n*0e8N5&<5S+32#Qn+{`}Mt z;cUVu<5!hWoaasP+5NekpO!73N32^3uPUDr`%g{r848~cS>Vr49TAUD;8&H;nEl|U_#72J z9kP5LvF?a?d;-6!eByqlDLw9#{G4Yq2Gft{zaHa9ezCzC_2_i$j%#)> zC(GKG-?~%He|7hp_g(4uBlGUZAC+`s_ol4*Z@G83ntaJT*jE1e2HP=q^_6V3dP{hr z@qeQWOd7w8*H1BV#rTCL4Svg{;R{R}oy7Z>m=x6$j*)5%>V=&TJN_8R``7@vN`3pr zx+B6_-2VZ;vim>q3HxY@&+yxFKX2Ire|~BukOQB7$!!hdRt&q(+jh)>{Gl~4G=P4U?k zJ_q6x_*LZ-_cKlL848~R@d^B@@)`4eX;XZT3ZDb<3H-|VMEo(j+Kfx|5r3SV8K3F2 zPI#`PZ>_A3Kk9#8vG?>EwDDwfR`obg@KVz*iJ$rRy7krtzj}CO?@4nkR5l3$f`A~9 zivabAgT7ynu32?{#qSHbbU^UF1^1*KMUq} z+s6`~z|;{_S>lJ{kHC-o;(p?f@Rx%t`t_GLY@Qn5(K-IC&iK~peqKjy-WLKJc3b&g z7@NDXdS0K4;Y-9{F19P!S9vP_aydr5ajtH-A}I(60tY(+)?a?eF{WqF>keryPx1Tp z@_mP5WPAI|^e(?1KlYVd@L3)d{_ z#b0(zu&7UVL^un78TbwAFGp|g-(TLjZO6>2sqss*T2|VkU1fXkWy`!T?*d_Wm*up- z9KBfl<=%c=k z?=N3{>6sc2jLn(xWsQp3j`!*L>-GF)_#1it^5F>q)R)jNo0g3)2jVXq=o0+$`ejFi zv+$RJ-=O|-@Y=rp<%vsnY@<&d_WRT3n|Ch$S>DF#N6|JJpDX@yecvu?gW@k|F{y`Z zb;A`&K|l~V*bz9e{AFU}(Y-05{+1WIR_eSi;dkTyI;tgKv1lJ;=$iZRJDzq*t2MH$ z)mo;(~9KTea z2e-)2D(>FY1#W5zfM227ZJ3%fUT;`^%Sf#;5w4 zxXew_{<6LIvTgnIq7%!C^vY>}IoxRcW`xYH?Xim*8kFC~SkN(m!)M)0N z=}ycetylAx{n~o3FIKy;sBG$a zzqh~g-qiQh&G@pdFaLXo`Qy#-m*H>Z`OCIu@RCja@#RO|@#>qO|JhrYQhJ<9L-Cg_ zjGm8T`(Q_ev+$RJUy;B3ls9f=J6=ZLjL*Dp6wmubclYlvPfpHs2XL4R{pI%;omg2o z^0w%9N9$#L+1ioo^VQ4C_;NkGvY6+YsB9Ai1OY)H4*}{HF}`f}=XHlPC$`96Ub19~ z@5AOD$l2E0U+&>6Qyp|HUg%ocO8jMCZ)ZKF-+=zIJ|^EzzIoLOtzufP~tWY_$}jF+P7Fd=A7X<5!hWT(6trGm!5$SUPjZ;NYt{Vk%4hAzg2QUsXOs?suEwbN+AT z{IpD=zw=WofgJb*epUI5*net@&sg{bMJn}q#JVHGS?~$`s`44LAKVn5bHb-X7Wng1 zN5tb3_*LZ-_cKlL83~^bSw4?gcSJlsfnQZVL%uI5v8f{L~Tg_ym4sd?NlB z-PU*far^kz&PX^pxwX$Zd;0b`dym{|eZUUbWgA+)#l#=iNc^$5zxM5^cwOR;#n@EC zx7=VwLJ$xH1OanBp&k+Q^-NSMuREl7<`>P^GxgNLv-fD-aVsJ)m+BsGlAGIZ$mc<_mg95=g^1pHl|_dwWe({JXOY* zd;4~I_LkiyfzeURArwaAP5KoDFjr%cwj!?qC4!As(OX`TP(DJeZs7dUDT~t z^Op~>=Ubkee!d0%MxMWH+f985{j#a=FK3W! z8zx1K)P8y%0`*lGC6G(_Wc;e~iR*P^e9C-IP^41u=ckScXA?dd zzp8x3-0wEU=cw@Mkmd7;bw|YG6Zlo-GhqLzDLw^} z5$leK$0zVB;}g%f1kW+!5`DxUcV0L%HNJT!t4qZ#h4IG^+X1_ZRi(uA7+?5mGY_%J z`DUr3>J{)qseHdBi;vy%;QIazcqRRj&r9?6+cry15D)|efnEq4(s~5#F8zMX13h1_ zht3>ROC%1;`Fij-;1|P%NyluBUtszW!ppAv@kf8YUi=byzg}Wtg?+G{uWH_3&Z_D9 zP~tE5B2E0|Ug*d^K|l~VI1xxa-x3f8*?y+g5`Ve3bu3o9v8Zh6^DX7?qxQe&VvbM# zn4ZVP{zjg^Y<-->KjV80yYBnT{(QYi{AGu5*UxhEjtFPrF9W|Kf4OYFUNXM?_`dz+ z?!@M;+dI?K{XXDQIKKRmybDAYilQyr7UNeKe_5W-aP6snUhu1rnYnL8xgs-_?Sg}Smpu8UME81t#Il!K8IU)Ug3;c~df7!N;`ULuA z(=vZK6o1)3m*7Vj`impNS@_GquU~(e>e0`)Fz^2JE$VQI-Md;??%k~>-|L%6B+={n z7TQmB|2<`Le!*qN{|zrSX|&U%!ISxUmM8M_EJyS6EJvC&cs%caoJmnN?h8>b?0neI zx6JR8`G3GXYu~VUD}fyGqrcz6_?68s0-vytrudA%A$)?Pe)t4_Rr$nu-V~paJg;Qw z%=ACy=O^&1$|tVZjqxe-IS1pD@vF*b$o+0pe0GJ;f%pV|Rr!qAe`<=)Q1~2(PvBRT z&zSw-ruZBcJ_q6x_*LZ-_cKlL83>;P@d^B@@)`1dX;Xa8-y-)bmQeV!erhFFsb1YOg2?BzEAdrgy^@y`=`Zf!GdEH^}`FgF~SP1INroF%4qMx|Q7Qz-f7B6(I zJV?La!u|&QVsJ)m4r9JvAn`}on@WrNWJiRv`cWk{rx1`ED{<7Yq`(MiW-MGK5rPV+3UyAlYhA?^f9Zx%@)f!pW zYAs8SVfUwVi`6O??9mQ~TDg7iTJ^k(YV);U9HWK4cZfV~=kFh`RC#AXEhY_)PtVtb zzmexJ+qO|(LceTUHeWCPU3nhdU=jT0!=jT0|=jT1rq|p()|6wLYrPO|U zjtlj|&WAl;Z%*EK3&>UK+c(x75zZ1nG+z(+mBmZIXT zQ+&<|pAK0*k63p^JU)S6RXzjupPJ$`5uPUD*`@v1|*%dw=vV0z~ z?udAN0>7$!;(n$nK11QtAq)KZsUza?3H++^8S{NT@yCz%8nnqa-QS|efr723T@pWo&GeTFe*NKQ?@fL4 zlyyNs5D)|k5m5c&Z2LsD`>?}IR4T7Kr1^TIYN1%!?R)nwz3Ugh(lIrpg|#O;($}@} z_+zVecv3c%q5c*N?MUJ#;YhW*Kg+$l z)#Q)PZc1&b^1hJUQzh(5IKlD8i%lALOd13nZ+r;H8xP}n;~^#u7V-X9KYsJa5wKU) zQu}rMk?Vz>4?F%if2YK&EQ@(I4x6=7luP0pj9=OPANY*eKAPfl?wi7=WvV`(z^^Kw zIM18nv-@q~a}Yj(UsXPFy>5!nK*rlFoqfcUfnQZVL+*E*;&c9Ua(-Gu>tAnyUsXOM z_Me*KGZsEAoqe32z^^KwG5f(y@i`}a4#X$$tI8+tXPV+O5Zn7w;<1KbrYM zZYjhI;NM`&(gN+kK!y8e*}Ky z7Y`JFWZwPwV?WP7>M!|aRZg~)#UDxVqC`5K2`@DMZ*+l4pUHwS)I`9#0l6rZ7tpISQmIX@Y{ zs(iwKYKqUfNjX0)q4m#C;8>_`yx_8SD@~2jLU=Rpk@+GfnY1C;g|Tvyba7@T1MycUCZH7avN^*B`UQqwMp zpB44l)wTdI8ft{MZGfhw^*nhNgT*8;IE_656bxCv0nU< z{SElVXzQ@zkAcJ=VJ<2y>XRK2&LaK@{KzjJDE`R249;-n&LD5p71#cpTMswpE%DO<8z5!nc^N;obk_7M=z0tMs`43f zzuOd_fsCIH#3%5p%4fv>Q&W6K%OqZ939aY%>-hnUUsXP1_Jf<^b58iQboOz*1%6fe z#QjWDe8$4(Kzstfs(glgU)mI(^TOvqd;-5RJ`sNmt}x>gea9bHO^sjbXj~(!Z!!BmP+Q?MCQc zCH}Yt!d@C~H2!b2-lXwaynZpq8#^3t+`{q33r!kb!24fjQdEn073zhZ4?F%CeO=-k zz`Tx6N&M*XHpZ{){ttY@KAPflPWZHR_A}mAlTV!IP4PMZk8*xmLhJQII$p*2RX#uY zdfgPC!E%Xj48kYytIB80{cclyjtZZa&OWZUz^^Kw0sBu)@fixA1Mvy`s`44KAKVn5 zk?=VXpTMswpSYiCiqARWb09u}UsXP1zAtTx&sg{zh)>{G#wX&B(VNY?ZqG2-+*5X7iL)T$4KIj&b6SZPj*B&i})k(Bfof{_#^W^jQHbY zv+Aa{REa-!Qzh(5cm~HCPd912#-zbZIo|jZjyJxT9+ecG;c7;z%XCLF?z^^KwIM18nGn9DpKzstfs(j*l z-4vhmGTt^2pTMswpCR|VP4OA5ka)5sw4R?x^8<2f+XDECQ#3%5p$|vq;n&Pu7d=A7X@T*}q2KJ-9oOvO z{Id4tx9(iZ+j(27MfJ?9jREsMjQC@I?9LpS{#S`VUTnovx$sou|3<4!8n58>^&D?J zi{p*!INo@MNu$$w{~D8`QpBrJFYG+O4GFHmH%YbAk4kgW@Si09Xkn>m=QMr_{L1eC zz$fgZDL&`+3!j7V3H++^iSxWEJ|p@5qouQt@o?Z*mCuN;*G=&m%Xr&Bd;-6!e8$}G zHpOQk@6#QKPvBRT&w%}>rudxyU5O`KLhJiOz^^KwA^X8i@fn^gd=A1V@Tk+kr{r7YGVwQ(o zI&NgfnW!A(P;NJuLw!H}*Rstd=19LjaM9O|3@;YDpMZaK)I+{s)H_1*Q27q_vv zL=#)c57Rd&jW2vB2N_qDHnbtx9N9OO{$WG;vLNY?$~e1{y$1zZmG(KX^%zkF5u?QeU` z7?npk$f4Yw&*$@x%hPq~-hcbO)cE&^Di1l7o8xk*ueJZx?YR#>v;Burq{q;4JjkKk zE-r`qsN7rLd_-GelhPA%C>L@$)b~IC{mS-_?%k%iZ=K?{4{|7X6qiGNbi93E-#GTh zHyoBa9^_DN{vKT^P*Ha$f4YBE{FQ4 z+~;py(Z2kTAC)QxIh5;iIn?*fJI`ys?ea&rKXL7~DLf&Eawl^+)OXWom$u_Cd_iAh zTs$F%asih^eb>DIsp@(?I|e?0C*)A>&Lw>QL0@$&vdS{+upYH*3T_Vowtxfxsc1DzJL9fi`%!~cDlyYJs#vx z?kFyY`u^WP{EoI2I_KSTkVCoo6Z!n(@_&2F^7eI~dTzV5|5qtoAct~$xE$*H#vSLj z)%CjlsZXAeY9HiKF5+^ikFJCIc%-EIfj`Kh+<9CM^^tv|ZEiWpq1-5!Lw$6-eP922 za_-`IkVCoqp3CPSj{DayXutk-ugjE!9LmL94)xu9(@kUd-?wY*-{$92xIhl&c5^w@ zN7r2CzhsUFIh5;iIn+nE?EU-S*5|y73*=DlWG;vLOu4@wBU^LJK@Q~tE{FQ4obo4@ zzVjWAO_hTj%H4SapMPBbyWf6kTb&DIU-aQ~OfoAct}hmqUHHKlUs8?^rhdQ^awr#YIn;;i zv?*oFK@R2a{7pXpxV-AameS&vgB;4uaXHj?-_Kv(-v2-US7Bo2AV5#Zq1-Mmhx+dM z*NOHo{_E0AImn@0$mLMqKYV4KzMuAafE>yl#pO`n$3FV(_LshRn(D{W{6P-o=8xs` zkIVn~M?V_VK9*MwawxZl%b`ByM=n*@_%VZxEpHhkeJKw-A%}A3 zaXHlY+0UFp*NL$o-Ft89yoDUfjdD5EN5`P+?gu~cfmAujq1=7X;q#BnfA8)KmeTSk z?|NLS9OO_g=5na-$3NQM{;!|yZ2#wv&HNv<4{|8Co6DiTJNKQ_{+Azg+IN5FWhq=B zhjLvmhx(Ks*d`zJ#!vrNsvP7{?qn{9`o4MRonzPj#cwJf^wd;2$e~=oI%=JSus6A${__53Wzq1+soLw)aj$2-Qp`sFW=eR|KH6c3O? zxm{ci^?iEJ$z$(*&wKPjhXxOjL%ER4p+53k{yq-J{Qd}XD0dW>Lw$;GWiNMU`#+XL zx%p@D`N!LdJG!>0`?wUIkVCmWTn@)o?bBt**4*|%4&@>)hx$Ho?Qwei?5}P(DOC<~ zD0d#0Lw$7K(LEg9Kf1?*9LkMyIn+n@9MK;OOo-aXifx%L%D#x z=kt%tC*@2gxqdv1OI7wmp?`040-H_JoHC$gf+`YF&M}nn%v-A5eld;B2j1v2y&9&eV8I|3B`86Z+&f@0c&m+lYqLOpmB3 z|3HZc|M44|XZLuES`SH934;68@^D^~9S3OU;jg-9+2gMM_UCqe^nJ_HD$;cei@OKg zX4}vH)myc1@zg&{$24%wv!%>6(5_R?-R9<7t=H^6zP&$up{|=GkNUv}Z+glF?-~2h z$sN7zjeDQbUj4!+-~8VD|5;xv(`|r$RMP#Wk74%YZ(F2vQ_B*?<@H>{64IBp(Ygx! zU$2%AlN_xpxs%lLEVVvIa<5kUlg^~4+C58cA^k~bl2@Bfq_(jBvp-$D=reEn%FdkE2zLaTMSxjG!WPpvO%?dNO7AxeafGx)K}v<$xT%yF8Zaj^fW zU-+>C0eE~!<%y@(=jfmRbGaFequclHU3$CnBOiXpH9EfOAF0>+aA~`G867L>zqr5b zqyO4@VW+jD+nMV0(!Fe-#@-WpS>8s-9R8vU>)3Ixs!-)Zq|r&{IWG6u4~G8h&`rBjj9Q~#pSGZknJ6u)I|C{gq{ZD?~;- z=l?jo^`S5Lg*$)$Gv4`Z*YjD2AA8gP_14ap{P-mNFjo6e+NUquf2(!Gn@3BtoOYT# zmfeuaPD@S$ye+#mrN;N9KbQYEkmtGTm)ie7(Pp(%dH)H0QTzWRZ6K#j#X3Nk(SJ#LaLo zH^23x|NYrm#~(}l9rXBd|IX{Xs#1Ra9fy}ro;!2q%vrxa_IIN_Pn>&Hoj`mh zSZM!0I%5}a`Mbl1&uMPi0}^(hW8mZVfA}QpoIjY)(dE4Glb`V)&PBOr&qj$S&z}8= z4~a2DwHG=c!Stn@{)dmb)A{|{l{DnI#*y|AtiPyg1 zvUKLxJtxXnd58Z9{xp==+6=*`{tIr8{=MyG*BSq`>rkF{{QWJgG1LE#R7alTe>Wa8 zzfabDYN(&AvfJf8*8JZ78L@ub`L8B?xqW#e*5~83udLrsI0lxbKWxMKhZ1kEbCtdN zS)py0Zqh#M@BZ))g>-xn-3T6MHShahO!Qe}(xxApqZ9x3jPab_zmIsq^Z&rhhJHVJ z{VjCpGpORYd3>U3e%Tj=51RV<778u(o+GSrY4bV%+a3C+(WznLA*DR~*Xy*0^iC?jksaoN)<@;6}^lizbGTY&j zUwPW$OIerlx5MSzrc907J1DdsN5X}k$Oa*}`Y`?r*7RR+DEJl(>Ro|Ty;GXr3Gb9V zO4s+wE7%VBj;CN$|K+EqZ_9TCogOeBWhtyOlu!9fSxPIm66Gmns$aqng&!*T;gd;w ztiKu_A1l*iyeo2x>c5?QC4Qc;#zKE;vqnzO5?0?!SnH*PwN6V|bfkn|`XXjr@c!Qg zo%?y-sqdHj_tF==bTZrSUvBnC&39a#4;+`6C7gZk)}!isj;mz0e$NZb|EgYdmu@<_ zlKCxX(LJ7vq?0@^m37q06^**_b)kPbF$-VNRt5((Z_>e(_y0BF`0{AZ$;1Q+!O0tt)9ret+Wb+g~D|n`o69b>CGr>X_y@>BKa~@x(Zu zw{QJZ^IhesOjptDN2~7tvvk41`)GLS-|GmgAElqAAt!D>`)e=#x)Q6ZxBTs!zV`2k zH{<=H&gNd8Oze;xndfBrPj|4#FqSe8YzObAP;aaY`qu2URP`q?fa1G>{EK)%Q#%=v&QR5uL@o-;>%X?diCa`c>U(?`qsv5 zvK(I#6Loc8mDW|&vzYa7AbNNduMZQi_w(6XeKsXrZb*F82LN8raVhKjM2=4xg$K{B zu5Wg1O|I@LwJ7mgzc20j;Ih8|i=%k`+G=>)Ka{%w{&C~=G7eYz)cTgpRQmZHNzaQ6 zp{L}78viFe6!<9hok+NO@U~U>xByQ--dISqysE!z{l2L*@&BhBg^$~|C*4Jp?FvJi z|MOD=K1x5oHQ^(MDdon`T-;H^N8-_=@KJ{K#OeVz>51%<((x|^bU{a4gqRHjBCGgRhHv6#o#v zmz>%9JNv1(6&+wnRo?jiI9*WW%JR!6@7K?N^763jm#5%PM5@Gp{!!rLLU(7nJsNLZ zZRelq55u+?Wr%OAs=N4oH3R(Me;@iuISyaRc;9vImdRp%5^_1&x)unf+mHCOx$6Vi#@fVC-br}&YzmL)0lBGNa zC)RUkegByB+`oAR{V4r;vh>^^T6NKD{y*nVygKFSugquO1$m-%C*)N$yEOlCpU?a+ zA2-WYWe^-#&z=1%`j8XZ&r;}#`+j3Z|M{K&=TUt~=&G-DHJ1EWtLm1X`>Sc>BlO&_ z%z1j*>Ut{ux$@`#UwUrU`)~RGJpL=JzyHwUe}0g(|0dJp?Qy@F=YI!)p2%@2^2~`> ztd7rvFI$you2oNct>2fvJn?#Njpej8ZcpawExow(#I!W&;5q;XU@Fh{bt_FI9%zop7)&RGVi6FvhE-Jiq(0)Wi+2|W7ygm zjIT-n&H($8rwo>h7KV=X3 z19CsY9&%sO|6%O=IniHzUUmg_#$pc<&3N+c+#j48j=I`P^ld7VcYOxk2bHQm zpq`p{*+WV{i#_D1j9SA-!b1%o_vAWCxOwp2Rrt8D?9H#m72;aIZzk(((2GwxN-t~= z!Nc@QiH7!@KIi;(^xs?I*+iRC8*A0Ku8-A@7d5I<4+xynySf2Dn{+9#{Oci&v&k%WsH zPVP)NN%(p2MUM(6S4C}FaB@}ONBiZKn|S02v%8->Hyr-$%_siX4}88;bf)z4ap_FL zLk%Bamhe&V$=$2)ao1qc-QFIpmwCF<=e2&{)c3^Gnc?uAH~)3LKl=ll&Xj&WE}cnu zsNv)GgpY)q2k%^kj|Wlot~!^bsz|K!5Q%isC7rwDwMejb63N6Ie=4>f%3CVUh;GFgR>^V@^& zZ2jsz`>*x;Clfy2^u{;5^TDSGe3X73fsY*C7XOj(P{YR};UnSZ!Re#G2i(KeNHR5i zT;=yqE_}S>otsY)_$d8s!-vk3jPY&3N5Vr5AG3syf=6bn@NvhBxXkPt{;u`=rt0KB zp0IsOC(pgg=pPk+~mrwDwMem*XIBs|pc@zn_*2{+ArMCjIQz#S^#TE8#tdE)K2QSx8^ zdC`BAnm(|e#ZRd8v)FG}d)eYY5*}*!*iQIJxLN(KnP2Vbx|$8t1wO9!`=&ilH2)DL zZ=U=7%Q|nkX~+9lsK7_*XTcxQi`@ns^2AYyG~d z>WSt*qU3i!Mes-IXMvC4Kgxc!7XC@*^w#T=gR>qpRnohgR%#2^Te-6o2l5Pxe>gq|sws-Hc!B z_oXLK4xHTat_PnYa8mkt*>I9@QQ)M^!-<5S2M<=^upcwX!GrKl(VJQwzqTzYM5AIS$U-MNuL zEc+)P^*ooduem+|LT0=XI3xZ--&+` zZ9D(_>x_KN$9&B7ANO$|clMJ$>62cq|HRLJ#7BI@_0M?5Gvp%tr2IYW zSr+wO|oqhGIU;WH|)_Tk3H#-ZBrvX{NgZTYe< z`!cuV+_`gy`hVk%H~!_dwBwUM`IE1|<(6A6z3z3dJN)Kv{^rBizV@|;U;p)AfB3au z`?ZH(^;KVWIGfE5A9&z_!}axbx8o%*c}YDU=g*&a8`O@^{oK!e`<2ei$AA3CpQOL< z{hsgnp2P3`-tRs9&hPwA|Npjc`?kXeAAHbl`MR(By2FEmgTv``dN>-54tu@c;r;jD z?>3aNxcTOr57idt?JrN9IC1iF=VY;1JoM%_zxnVjZ+Xk%5B}f}9=`F7Z#;a%8{TlJ z_NXmthsH(YvA@6XdD+?7IqdiQ^;mrQmw)-;?YG~4$Qb(n*|TRK{-}@osOulE4UF@9 zf8r;8;_xSb@+S}VeCu1^>UR9l5B*Tx4z=Oizx~?}zv-L4>9CB0U_)&XTy#2}L(Rus zcinaPrC<7`hqvB(tN$|}4}aK)eb}Rp17rC5pZmF=JN)^d|M|n8{n?*A{F$HmnZuv@ zsh>Lh@gM(jw?l1s)0^IO_5~shK);?E*)OHc=1p$D)`*o+;kfR zn`%Q@BU&fVdCqe#9XAH7U{NfA}rm@-2o3!KL7VxpNyd4y>EQm%j9+hj-t7x7UWoLjOPU6F>10>l3(o=r@1! zHxJAIU-^|^IsD~c{^i48_=R8aSiJ3RZ}WWo*pK~~+wcQF@B@ZTwLviX4d3t$^;~Fe zY;A2B9=`G`zw+?D`|djwJg9EL#C6wQ_xko2fV)1H{yzNszyJG(zxR8;clbNM^E+;b z#^Sg(2qrWRYQuMb_jel}OB=rCYrf`iZ*Om9UA*EIuQ$^O?`Aapm>b zUw`%w{@@P|-}%mW9_p!f{O<4muG{ddzxu15kGH@5?S_Y+{^_4KJe0MebRS zQ|qF@g4U*RM1cjZORb5cWAO5qzr2P;)&F^)_jzwF^)q&F|L6bwpC9V~Kl^9@%W5Y! zhsGb@KlI0c{Ktp?@?ZYT!+-HF{)OA2u}~Y1j)U5uG0?gcEdI!k{D|>_)}-)))U6y$ePWb-s|9<1g@A!`IsMmwm<7-~?8slf-B&~zv>St}a{?Z1GgXTgoA(%W4 z9yJeT473&m2O0y_FT5mr_0?bf)rLdOLATpAPSiR)I{wVzLx1*Xe|Gr3_r34%z3+YR z;h+4;pRCM-;6QEA82tLL|9TAzWemz%&=?2~L?48k%R0~;h&~Ay6@0k1wpQZ+;N{JK z{^x&wsQ+rid*1UN!@|4Y{cgizdkh4N1xIQOgqI3V(ijwcP+&mopk2SlU+eI*KI^kC zmHCH8-t({i)xSFYi@*4bLybdw3&>cPW1u-Gu&A}5{+G2V+^jKZ&w<9Ey%vR!1OvhYqKm3u zI6&*~DDEk90IzZn^Zl^qp*;s>EeIcI4uqGF!l7V5G`iq|QonGq>K8o{Exh;Md&LJl zT{f`?SU;7{W(Iye{%4!`6}zT~0D;=Rfk==s^7{n^(8-+$R&18o>A z{TEFt{V(%hXp#5<@kD|>*86)UGqvk@yzobU(2 z!oeDQ_5Jfd|MM>$U2Bh5cl-SdU--g%z^P1o%zK+R5}#OTq3Rd@6%7>bVZI-N&%2^N zx9dF`rXOeFE8fo9dauS^bqnrAg9P{V`CS`i#E*Zf^$5@9!z~4r}I5M0#A>?(<5+|BXHg1yz$|6`|)%!Cn~hA$6uetwWwcrIaU4r zYvX>fPx#!mSGp*QJ08u+rd{mXms9d%=Q;69FM6r&?-H}x`sdQlN7FxR zB=mRU53W%E+{%A^zmK-;>G;zl@bm~gJpxaUz|$k}^awmX0#A>?(MP}!`Ziyada10}^_{-P%J{t0SIRH-y=@xxm3Fv3 zU7~c2f2F=seqG;g)K}W!`fj+!%J{slFUv3WZSF;Vr5&#Cc~4w@rTkLgUoW%1Y=`T6 z{u5VUDZkWL^p~X_uI~j;Tz#edQeP>#w8QnuLG~K|Zn^v1sqLTnpz3|!`;!;{E;X%M ze;0Uh_qn@nee1_p)!KNlzo^!xv%zk)*6%L5)!J}0o0GKN<#)e2s4iCfJEJi_U1ACy zDD;|TcX9s>uc{W>q^`hxy}LaiP=`BvgVDyO3ZHPk<6u_lX69+N%a$SjpRN`M(?K;~ z_WT@fcQ>kWcV}?_^Ho-Nm+K1LoNbP1T5x#RwgQvsU>3)CEy&)PcKg@gfBIF`8l{XD zgPqQ7FdVRzaedHHQBC^xgvLeMBeRaM#qFyhE+Vo<+S+W~r4nwItt+0pR#obE96r}^ z``7BKt0{?t*b!XsY&C(-l)&$j(XKvcRn91I__q4{rRt|IE{O> zJ{fn&G#k+B^?Y=e)HLaEwe_SkUCuX4a(Bqkwvy+Zm&kbmo#j&1wA(V-9n5B<{-8tM zv+nGmTAR#98>(n+de9k-=Zh{QSFLGSPgP1Dj<_{KFyYpny8bj%qcjakr`wy~A4zM| zE`zR#=KAeHUpXpfV@jDCS*lfwoXjY=Pk)e&J$)nJ^``tETwGK@>}-7@K+PSsS533JCU({B0~~!u6sS_E`e?qG-G7F{93EX9 z1Ryda9)W62wXO|klO5Hfk2H^`t964N6|%KPU^ixlhuXNe$n`@BYq46^Cp%NkxF=&? zDK8*Q@96M+u)VF0u2+QCs~wj*S2N~=!B#b#tS{%C{wQH+2;5JV$f{%A>Tc%wU_9rF zm{~c8&+E7vFLyeI*H7LC+=war=#7; zg7M#G?v%R&KoR!HJR)_$n2mP26^Gz6oonmcqba>qcrqNaI5m4lY*p8rVdoQuz$2*s zPI?ajm{nKH9gyrqx9e!#*Cs{CtI3}|@6Yx+>yz1-bwYhYq139x1$QVaC8Pbpbm7IK zcOG$OF)^-^#@>(FN?Yt#Q{foaCkRxVdDTJY$WMF_Dkf)MO=gSDNhiA5pLO?gS~XuC z5Thrqa{!2shLq^XLG|+6I{nE|)4*z&3>k}x#i_JP|9c>o9WdX#d_Nooz}^1>Mii7a zm{c`RoUac6%i#>1J)XsrR(S%dImrR3)%wBub~V{zjcv1 z@VeUW9%xp(1(z9RRsU zaogSAVB2eYZN0m`38b_z))~*FTEnuMu@>BfIo$6&!yQE^WWIouseMg?N5?}9PM8hm zAmG`cJ6B2>I0Z#UH4h#Y1)^IDX~Y64h(tHIn#PFy$AHZjK!3ktkuml9J@Bv5rJ_** z0RyAotxvWmGZopLPxtk6P&sK%6@w0oXu(~!^H@L~FHudK>YD?_#zfo%0(u1LGm=3x z6r4vUQBlFmnSRL*30R+i)2A$7|BeS6pg~3~XmPH~HS$%<-5{;%@@(<|D}vtx|6bI` zQ(d&%n?X@K#G-u>4ZPt7Plj{Nv}c|t3%i2t=}&e7xkP`JbGw>Gv*Mw4c~wq57}eh9 zXnnIYSuP-B6%0|;tG25CVAz2osgPlJUBpQbKGTB*Hq~>lJM)uF^XXt+NjsyNvv_4k zUc8ohQ8Em6MhnF^yR*KYKzaGbT$`)w?)3DIa!YoCfS6wrbWY{yg9r2kPb`=Z7ns>Z z3=|Jkuh9DTa>woML&BA?H5zY~XC}c7Zfq)zb(Cdq%(}ave8>4D5uV8*G{4Dh^~&JW_JW8BaQm{5M9ij0aO z8SHl$&{1oGlAQT zOdiGQ0JbZLK;6$)+S>Z0C*dH+LyS6)Q`z2!Cw$t*ua8MuKo%)7h@j@=Nm;VID% z>>yC&Z+A92w^#gd$K7(=or(Svo2)O80_F||DIjs93p*yF)9LO^V5zGyRCu|FX77$W zd#5V>p7!q<|K6bAoxwhm2Uv?wcN7q0OaAZxv<9q6jFIwt2TxZJG^4+{Gp)nsTQE|< za#5s+OLPhWW-|I&b%$c=_Gg3X0M6?mpD>+3DopPH#(8F9I_|<17)_rNPF)*=RXpY3 zWhlHjB{*JTBe0Mj4ZVkfjD&qXJYR1R?E>pkrE7 zYSN(Zs6(2x-f|e#fi)CCz?&!Vxamp~(c|g3sA30{z}!YqZLLEGP4Hp{p?x%Lz8ohm zXU-TOW0lSB_5|89g<5n-7LVsvKVLJm-UaF;AawT)R&@fco{S|Al^jE|)sc0BtriHi zwC*oc@R*)(YC4fMj7h2@2yoz$`?WYeDxUX(MZxokkX#i`PYv z;Qsc`Y@^pzKLF6}I1QNJXGYv85x_I|LjlD+xhhu*{|KImJKbSv8BBqLT8(I-yh!`gA;NYKK^iWQ zAEeg(=|zT!c1RF~&7=s6TZ<54&D>OLgFcEE3AojobEq9?hb9X~!5CD_dkkWLUECI* zh8hHz-W$n>>kYKlJ0swY(CGKU(vQyMzD*+Gt(ju-Q#e|Kr) zoYfkST?8&z`(-?KEp0FTiwbUQ40>JWb62v(0*;uGM>Sz)qr^~@pv>8?pc~_Aui8YE zo}p6GU`D7n*o6;fZX|t1h&3}A2jyOqh5+3NTvZ2-n1vmv?fU!S3d~x?!ieB}XEKot z&v8H7>)q)*`2^{K;Q1GV!KXR^Mg_MbCk~>fkjUM+?yZ| zt^1*};Ke4=q4-JPKt-q2N1mtic}hY^h$N9-#|2%dH977eig)PwA02|eMA9{ketmC<=V*}Jl z&AaUh+MfCyN|pn7l*yDHv!;8yW&N$qH|hJ<9(uN@9mxmz54LkM=93Yu9PHz0jDk&h z0NYq!?MP>+_gd@JC#>87(9jU9?P&U-+iN?ne{IK&ipP?L<+w1)+79E*xa~-I;F*sd zcaRZN&(``G^9PI>sxgK#N6x`r^WLEz9XdSq@3wy#Ko`W*weZaL5pn~0x`j2PKQCB5 z=&lj5phr{|Et^-M5W6~VR2}n`(*^;GTR)AF46{O;GcJt=1a>F;tnXu%mgyVl>+V#~q; zMd%|M60HdB1X(~6S{{Py>(&&Rf6jHEQ>}sW5kRY5y7^(M(D=USjkgP!x*@6`K~_pn^R}wb90M*V>pyq$>#vcw4?MYd>c8J~0b! zZBY;1siuR>b~}lXi@LN2Q`twQU((kGJLg0Fluxivs9`l(`z*^CVn$KA+0bQZQF(&b z5J|f;^vE?M0rmnzLPp^s!I2R#A(7s1E!Z*zlR;zjgLfkkN?2oPbbzs<^8>?bFvRq! zVeZ_*1sVw&2JH8cZ&?RTbLz~1<@7+aycS%Tn!sJ@RAc3hxL@RZR*gcQNd)kqcF~aS z(M~4ANV8xNH{nsVbTb;jzDV@|3Kgb(G)5jm{h~0!C*fVMsbsCX$S7)V@OnX7gOWv~ zlCx(fHfGZX77&fln(x%q7_I7#q}??W$29~iN(Bau^})%+bT0JH2tGs*9pp}ELsUYR zA1S9N=#)=g&x%9Q-Xuv&$4hJLc%s{t@ebXt9w^5KD7m3{>LII)K|*;uPo&WC>_k_x z4-Ar8=CO+DB*?H^)&-i>5EV#i1|%vHJRMX?lo9%8W&ngt6kh#!3FesIEbE` zW*7ll-^)rCt_BiB^6BGXSBsh@L=_uo@MTX71J!73)I?m35sFwdu7%Wt90Kh^kVF(< zuNRvya>Fe(F|0E&sNgjCr3i-#CRoeq!cTH+c1JVg1qC`A@Mtn2sj^l=*AjY@0EDjQ zSjXIAbiD@ONdKVs-YU2T_1=eb;a3d4#Az1xq7!L#ta$7}wNt)$te{_jVL=<-G*niU6DCDX9l>EP_wS2fm@b=|w+4ghEwTg!gJ;4O!52+|mk8b^&R!_!PNNfr z&Y2Pg-;%V=6c((PD8;Bp2p&uWs~ETkMxRx96o1Y@om((DG3&TGk1L9j(W=)rwBneQ&4qN=mEGovxN@JD~@QLJPF|6+oIuO$j6s zB(N`RkkiyeV>rdcCBg(pPA_&rwjEks?=uzQg)OeSbx+~#@4oVX}cFn&GX2OfXW{U$3HmftoMZ>^K z!1GgH^uf=5LBKCe`aLgGmQc(PNESg9~bx20pghT~Wac>zzZ=}u5H9eYdBm0@1Tp#)V6=NA#Bx@No%HkPT6E(0T3d)0J z2ECfgG)_Wu!RX{HwXmAZ4@MvGN`Z}2yN2@*h6A|?=%ED-<%apJ@nH^B!Qyf_18f=) zt;;hYgNMfxtt zPh3u7Mkg64>IArQOHG=dk~o*97rRKDI;p^G zoUK}~SFNyy5&)#l&?*iMnqDNN%KC$6mX?SYA!c!eEW3I-a|ZPeXO%)VnXl9vt|Xbu1G^D?49fs)AXzJW*;S zvAzp7XnllYwob-QEOrl{2G;yg9E*HNF*AyQ%0A+upjA>$_8BS7wZ*9j2nRcq=HWin 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 F{{t@4qMQH# literal 0 HcmV?d00001 diff --git a/tests/dependency.json b/tests/dependency.json new file mode 100644 index 0000000..a449c26 --- /dev/null +++ b/tests/dependency.json @@ -0,0 +1,11 @@ +{ + "blender": { + "moderlab_type": ["moderlab_type.zip", "Moderlab-Production/BlenderObjectType", "prerelease"], + "moderlab_pie": ["moderlab_plugin.zip", "Moderlab-Production/BlenderPieMenu"], + "moderlab_plugin": ["moderlab_plugin.zip", "Moderlab-Production/BlenderPlugin"] + }, + "unreal": { + "unreal-pipeline": ["unreal-moderlab-pipeline.zip", "Moderlab-Production/UnrealPipeline"], + "unreal-type": ["Moderlab-Unreal-Type.zip", "Moderlab-Production/UnrealType"] + } +} \ No newline at end of file diff --git a/tests/launch_test_b3d.sh b/tests/launch_test_b3d.sh new file mode 100644 index 0000000..a9bf8a0 --- /dev/null +++ b/tests/launch_test_b3d.sh @@ -0,0 +1,3 @@ +#!/bin/bash +/opt/blender/blender --background --python-exit-code 1 --python "$FOLDER_TEST/tests/utils/blender_addon.py" > /dev/null 2>&1 || exit 1 +/opt/blender/blender --background -noaudio --disable-autoexec --python-exit-code 1 --python "$1" -- --verbose || exit 1 \ No newline at end of file diff --git a/tests/main.py b/tests/main.py new file mode 100644 index 0000000..dc6d9e9 --- /dev/null +++ b/tests/main.py @@ -0,0 +1,54 @@ +import sys +import os +import enum + +from pathlib import Path +from utils.blender import get_b3d_addon_dependency +from utils.container import VirtualMachine +from utils.misc import ordering_test_file, generate_archive +from utils.properties import ContainerObject + + +class Container(enum.Enum): + """Enumerate about the Geometry node""" + BLENDER = ContainerObject(name='Blender', image='stilobique/blender', tag='3.1.2') + + +def launch_unit_test(test: [str] = None): + """Start all Unit Test, Blender and Unreal if needed""" + # Ordering Unit test Blender/Unreal + if test is None: + test = ordering_test_file() + b3d = test['blender'] + else: + b3d = test + + vm_b3d = VirtualMachine(Container.BLENDER.value) + vm_b3d.launch_unit_test(tests=b3d) + + +if __name__ == '__main__': + # Initialize Variable and module request + archives = [] + + # Prepare Blender and Unreal dependency + get_b3d_addon_dependency(archives) + generate_archive(archives, 'blender_addon_folder') + + # Generate Unit Test, a specific call or execute all Unit Test + test_list = None + if sys.argv: + for arg in sys.argv: + if '--test=' in arg: + test_list = [] + items = arg.replace('--test=', '').split(',') + for item in items: + test_list.append(item) + + # Launch Unit Test + launch_unit_test(test=test_list) + + # Clear archive file and container + for archive in archives: + if Path(Path(os.getcwd(), archive)).exists(): + os.remove(Path(os.getcwd(), archive)) diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 0000000..36011d0 --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,2 @@ +docker +PyGithub \ No newline at end of file diff --git a/tests/unit_test/test_b3d_install_addon.py b/tests/unit_test/test_b3d_install_addon.py new file mode 100644 index 0000000..6f87ad5 --- /dev/null +++ b/tests/unit_test/test_b3d_install_addon.py @@ -0,0 +1,25 @@ +import unittest +import bpy +import glob +import os + + +class ActivateAddon(unittest.TestCase): + """Activate the Blender addon""" + + @staticmethod + def get_folder_name(): + """Return the folder name to get the addon name we want activated""" + addon = glob.glob("/addon_moderlab/*/__init__.py", recursive=True) + return os.path.basename(os.path.dirname(addon[0])) + + def test_activate_addon(self): + """Activate the blender addon 'moderlab_plugin'""" + addon = bpy.ops.preferences.addon_enable(module=self.get_folder_name()) + self.assertEqual({'FINISHED'}, addon) + + +if __name__ == '__main__': + import sys + sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []) + unittest.main() diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/utils/blender.py b/tests/utils/blender.py new file mode 100644 index 0000000..99c3bc3 --- /dev/null +++ b/tests/utils/blender.py @@ -0,0 +1,21 @@ +import json +import os + +from pathlib import Path +from .forge import get_release_file + + +def get_b3d_addon_dependency(archive: list): + """From json resources, get all blender dependency and download-it""" + dependency = Path(os.getcwd(), "tests", "dependency.json") + with open(dependency) as f: + data = json.load(f) + + b3d_dependency = data['blender'] + for key, value in b3d_dependency.items(): + if 'prerelease' in value: + prerelease = True + else: + prerelease = False + get_release_file(value[0], value[1], prerelease=prerelease) + archive.append(value[0]) diff --git a/tests/utils/blender_addon.py b/tests/utils/blender_addon.py new file mode 100644 index 0000000..1b004b0 --- /dev/null +++ b/tests/utils/blender_addon.py @@ -0,0 +1,58 @@ +import os +import bpy +import pathlib +import json +import shutil + + +def b3d_install_addon(): + """Function to install addon with the blender locally set""" + env_name = 'FOLDER_TEST' + dependency = pathlib.Path(os.environ[env_name], "tests", "dependency.json") + with open(dependency) as f: + data = json.load(f) + + b3d_dependency = data['blender'] + + try: + if not os.environ.get(env_name): + raise KeyError + env_path = pathlib.Path(os.environ[env_name]) + if not env_path.exists(): + raise FileNotFoundError + + for key, value in b3d_dependency.items(): + bpy.ops.preferences.addon_install(filepath=f'{env_path}/{value[0]}') + bpy.ops.preferences.addon_enable(module=key) + bpy.ops.wm.save_userpref() + + except KeyError: + print(f'Env. "{env_name}" doesn\'t exist') + exit(1) + except FileNotFoundError: + print('Wrong path to execute this Unit Test') + exit(1) + + +def b3d_install_preset(): + """If the folder preset exist, add all preset inside the moderlab dedicated folder""" + env_name = 'FOLDER_TEST' + + try: + if not os.environ.get(env_name): + raise KeyError + + path_preset = pathlib.Path(bpy.utils.preset_paths("")[0]) + path_locally = pathlib.Path(os.environ.get(env_name), "presets") + + if path_locally.exists(): + shutil.copytree(path_locally, path_preset.joinpath("moderlab", "props")) + + except KeyError: + print(f'Env. "{env_name}" doesn\'t exist') + exit(1) + + +if __name__ == '__main__': + b3d_install_addon() + b3d_install_preset() diff --git a/tests/utils/container.py b/tests/utils/container.py new file mode 100644 index 0000000..c6189f7 --- /dev/null +++ b/tests/utils/container.py @@ -0,0 +1,75 @@ +import docker +import os +import sys + +from pathlib import PurePosixPath +from docker.errors import DockerException +from .issue import ContainerErrorTest +from .properties import ContainerObject + + +class VirtualMachine: + def __init__(self, container: ContainerObject): + self.client = self.start_docker() + + self.container = container + self.base_command = self.container.commands + self.clear_containers() + + @staticmethod + def start_docker(): + """Generate docker client information""" + try: + client = docker.from_env() + return client + + except DockerException: + print('Docker isn\'t start or installed') + exit(1) + + def clear_containers(self): + """Look all docker containers, and remove-it if the task are used with the unit test.""" + containers = self.client.containers.list(all=True) + + for container in containers: + image_tag = container.image.tags[0] + status = container.status + if image_tag in self.container.ref and status in 'exited': + container.remove() + + @staticmethod + def workspace(): + """Define the workspace folder""" + if os.environ.get('GITHUB_WORKSPACE'): + return os.environ['GITHUB_WORKSPACE'] + else: + return os.getcwd() + + def launch_unit_test(self, tests: list[str]): + """Execute a docker container to start unit test dedicated""" + if tests is None: + unit_test = os.listdir(self.workspace()) + else: + if type(tests) is not list: + tests = [tests] + unit_test = tests + + try: + for test in unit_test: + print(f'Launch unit test "{test}"') + cmds = self.base_command + [f'{PurePosixPath(self.container.local_folder, "tests", "unit_test", test)}'] + + docker_test = self.client.containers.run(self.container.ref, command=cmds, + volumes=self.container.volumes, privileged=True, + environment=self.container.environments, detach=True, + name=test, tty=True) + exit_docker = docker_test.wait() + if exit_docker['StatusCode'] != 0: + print(f'Container error "{exit_docker["StatusCode"]}".\n\t' + f'Show log : \n\t' + f'{docker_test.logs()}') + raise ContainerErrorTest + + except ContainerErrorTest as exception: + print(f'{exception.__doc__}') + sys.exit(1) diff --git a/tests/utils/forge.py b/tests/utils/forge.py new file mode 100644 index 0000000..db29572 --- /dev/null +++ b/tests/utils/forge.py @@ -0,0 +1,51 @@ +import os +import requests + +from pathlib import Path +from github import Github + + +def read_token(): + token_file = Path(os.getcwd(), 'tests', 'token.txt') + if token_file.exists(): + with open(token_file, 'r') as f: + token = f.read() + + else: + token = os.environ.get('token') + + return token + + +def get_release_file(filename: str, repo: str, prerelease: bool = False): + """Download from Github the latest release files""" + g = Github(read_token()) + repository = g.get_repo(repo) + all_releases = repository.get_releases() + assets_release = None + + for release in all_releases: + print(f'Get "{filename}", with a prerelease value to "{prerelease}" ') + if release.prerelease is prerelease: + assets_release = release.get_assets() + break + else: + assets_release = release.get_assets() + break + + for file in assets_release: + if file.name == filename: + dl_file(file.url, file.name) + + +def dl_file(url: str, filename: str): + """From specific asset, download it""" + headers = { + 'Authorization': f'token {read_token()}', + 'Accept': 'application/octet-stream' + } + session = requests.Session() + link = session.get(url, stream=True, headers=headers) + with open(filename, 'wb') as f: + for chunk in link.iter_content(1024*1024): + f.write(chunk) diff --git a/tests/utils/issue.py b/tests/utils/issue.py new file mode 100644 index 0000000..962f897 --- /dev/null +++ b/tests/utils/issue.py @@ -0,0 +1,12 @@ +class Archive(Exception): + def __init__(self, source): + self.source = source + + +class ArchiveFolderSourceNotFound(Archive): + def __str__(self): + return f'Can\'t find the folder source "{self.source}".' + + +class ContainerErrorTest(Exception): + """ Failed to generate the test """ diff --git a/tests/utils/misc.py b/tests/utils/misc.py new file mode 100644 index 0000000..fd7ba70 --- /dev/null +++ b/tests/utils/misc.py @@ -0,0 +1,47 @@ +import os +import pathlib +import sys +import zipfile + +from .issue import ArchiveFolderSourceNotFound + + +def generate_archive(list_clean: list, name: str): + """From the plugin folder, generate an archive to test his code""" + archive_path_source = pathlib.Path(os.getcwd(), name) + archive_filename = pathlib.Path(os.getcwd(), f"{name}.zip") + archive_file_generate = zipfile.ZipFile(archive_filename, 'w') + + try: + # Check if all default folder are present. + if not archive_path_source.exists(): + raise ArchiveFolderSourceNotFound(source=name) + + for directory, subdir, files in os.walk(archive_path_source): + if '__pycache__' not in directory: + for file in files: + append_file = pathlib.Path(directory, file) + included_file = pathlib.Path(os.path.relpath(append_file)) + archive_file_generate.write(append_file, included_file) + + archive_file_generate.close() + list_clean.append(archive_filename) + + except BaseException as e: + print(f'Generate Archive error : \n\t{e}') + sys.exit(1) + + +def ordering_test_file(): + unit_test_folder = pathlib.Path(os.getcwd(), "tests", "unit_test") + unit_test = os.listdir(unit_test_folder) + unit_test_b3d = [] + unit_test_ue = [] + + for test in unit_test: + if '_ue_' in test: + unit_test_ue.append(test) + elif '_b3d_' in test: + unit_test_b3d.append(test) + + return {'blender': unit_test_b3d, 'unreal': unit_test_ue} diff --git a/tests/utils/properties.py b/tests/utils/properties.py new file mode 100644 index 0000000..3cc955c --- /dev/null +++ b/tests/utils/properties.py @@ -0,0 +1,69 @@ +import os + +from pathlib import PurePosixPath + + +class ContainerObject(object): + """All data request to launch one dedicated container""" + + def __init__(self, name: str, image: str, tag: str = None): + self.label: str = name.lower() + self.image: str = image + self.tag: str = self.set_tag(tag) + self.local_folder: str = '' + self.volumes: list[str] = self.set_volumes() + self.environments: list[str] = self.set_environments() + self.commands: list[str] = self.set_commands() + self.ref = f'{self.image}:{self.tag}' + + def set_tag(self, tag): + """Determine the tag use with the docker image call""" + if 'blender' in self.label: + if tag is not None: + return tag + else: + return 'latest' + elif 'unreal' in self.label: + if tag is not None: + return tag + else: + return 'dev-slim-4.27.2' + else: + return None + + def set_volumes(self): + """Define folder/path with mount with each docker container""" + if 'blender' in self.label: + self.local_folder = '/addon_moderlab' + elif 'unreal' in self.label: + self.local_folder = '/project' + else: + return None + return [f'{self.workspace()}:{self.local_folder}'] + + def set_environments(self): + """Add environment variable start with the docker container""" + if 'blender' in self.label: + return [f'FOLDER_TEST={self.local_folder}'] + else: + return [] + + def set_commands(self): + """Write all commands execute on the docker container start""" + cmds = ['/bin/sh'] + if 'blender' in self.label: + cmds.append(str(PurePosixPath(self.local_folder, "tests", "launch_test_b3d.sh"))) + else: + cmds.append(str(PurePosixPath(self.local_folder, "tests", "launch_test_ue.sh"))) + cmds.append(str(PurePosixPath(self.local_folder, "tests", "unreal_sample", "empty_project", + "EmptyProject.uproject"))) + + return cmds + + @staticmethod + def workspace(): + """Define the workspace folder""" + if os.environ.get('GITHUB_WORKSPACE'): + return os.environ['GITHUB_WORKSPACE'] + else: + return os.getcwd()