From 2a0c16a153d259cf4b730ed45bbaef813c5fe659 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 13 May 2021 13:42:16 +0200 Subject: [PATCH 001/106] improve docs for build --- website/docs/dev_build.md | 171 ++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 73 deletions(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index 14efeaa850..f3ee230964 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -7,14 +7,26 @@ sidebar_label: Build import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +## Introduction To build Pype you currently need (on all platforms): - **[Python 3.7](https://www.python.org/downloads/)** as we are following [vfx platform](https://vfxplatform.com). - **[git](https://git-scm.com/downloads)** -We use [CX_Freeze](https://cx-freeze.readthedocs.io/en/latest) to freeze the code and all dependencies. +We use [CX_Freeze](https://cx-freeze.readthedocs.io/en/latest) to freeze the code and all dependencies and +[Poetry](https://python-poetry.org/) for virtual environment management. +This is outline of build steps. Most of them are done automatically via scripts: +- Virtual environment is created using **Poetry** in `.venv` +- Necessary third-party tools (like [ffmpeg](https://www.ffmpeg.org/), [OpenImageIO](https://github.com/OpenImageIO/oiio) + and [usd libraries](https://developer.nvidia.com/usd)) are downloaded to `./vendor/bin` +- OpenPype code is frozen with **cx_freeze** to `./build` +- Modules are moved from `lib` to `dependencies` to solve some Python 2 / Python 3 clashes +- On Mac application bundle and dmg image will be created from built code. +- On Windows, you can create executable installer with `./tools/build_win_installer.ps1` + +## Platform specific steps +### Windows More tools might be needed for installing some dependencies (for example for **OpenTimelineIO**) - mostly development tools like [CMake](https://cmake.org/) and [Visual Studio](https://visualstudio.microsoft.com/cs/downloads/) -### Clone repository: -```sh +#### Clone repository: +```powershell git clone --recurse-submodules git@github.com:pypeclub/pype.git ``` -### Run from source +#### Run from source For development purposes it is possible to run OpenPype directly from the source. We provide a simple launcher script for this. To start OpenPype from source you need to -1) Run `.\tools\create_env.ps1` to create virtual environment in `.\venv` -2) Run `.\tools\run_tray.ps1` if you have all required dependencies on your machine you should be greeted with OpenPype igniter window and once you give it your Mongo URL, with OpenPype icon in the system tray. +1. Run `.\tools\create_env.ps1` to create virtual environment in `.venv` +2. Run `.\tools\fetch_thirdparty_libs.ps1` to get **ffmpeg**, **oiio** and other tools needed. +3. Run `.\tools\run_tray.ps1` if you have all required dependencies on your machine you should be greeted with OpenPype igniter window and once you give it your Mongo URL, with OpenPype icon in the system tray. +Step 1 and 2 needs to be run only once (or when something was changed). -### To build OpenPype: +#### To build OpenPype: +1. Run `.\tools\fetch_thirdparty_libs.ps1` to get **ffmpeg**, **oiio** and other tools needed. +2. `.\tools\build.ps1` to create virtual environment in `.venv` -1) Run `.\tools\create_env.ps1` to create virtual environment in `.\venv` -2) Run `.\tools\build.ps1` to build pype executables in `.\build\` To create distributable OpenPype versions, run `./tools/create_zip.ps1` - that will create zip file with name `pype-vx.x.x.zip` parsed from current pype repository and @@ -61,27 +76,33 @@ without the need to re-build the whole package +### Linux + #### Docker You can use Docker to build OpenPype. Just run: -```sh -sudo ./tools/docker_build.sh +```shell +$ sudo ./tools/docker_build.sh ``` and you should have built OpenPype in `build` directory. It is using **Centos 7** as a base image. You can pull the image: -```sh +```shell # replace 3.0.0 tag with version you want -docker pull pypeclub/openpype:3.0.0 +$ docker pull pypeclub/openpype:3.0.0 ``` See https://hub.docker.com/r/pypeclub/openpype/tag for more. +Beware that as Python is built against some libraries version in Centos 7 base image, +those might not be available in linux version you are using. We try to handle those we +found (libffi, libcrypto/ssl, etc.) but there might be more. + #### Manual build -To build OpenPype on Linux you wil need: + +To build OpenPype on Linux you will need: - **[curl](https://curl.se)** on systems that doesn't have one preinstalled. -- Python header files installed (**python3-dev** on Ubuntu for example). - **bzip2**, **readline**, **sqlite3** and other libraries. Because some Linux distros come with newer Python version pre-installed, you might @@ -90,69 +111,73 @@ Your best bet is probably using [pyenv](https://github.com/pyenv/pyenv). You can use your package manager to install **git** and other packages to your build environment. -Use curl for pyenv installation +#### Common steps for all Distros + +Use pyenv to prepare Python version for Pype build + +```shell +$ curl https://pyenv.run | bash + +# you can add those to ~/.bashrc +$ export PATH="$HOME/.pyenv/bin:$PATH" +$ eval "$(pyenv init -)" +$ eval "$(pyenv virtualenv-init -)" + +# reload shell +$ exec $SHELL + +# install Python 3.7.10 +# python will be downloaded and build so please make sure +# you have all necessary requirements installed (see bellow). +$ pyenv install -v 3.7.10 + +# change path to pype 3 +$ cd /path/to/pype-3 + +# set local python version +$ pyenv local 3.7.9 +``` :::note Install build requirements for **Ubuntu** -```sh +```shell sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev git ``` In case you run in error about `xcb` when running Pype, you'll need also additional libraries for Qt5: -```sh +```shell sudo apt install qt5-default ``` ::: -:::note Install build requirements for **Centos** +:::note Install build requirements for **Centos 7** -```sh -yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel git +```shell +$ sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm +$ sudo yum install centos-release-scl +$ sudo yum install bash which git devtoolset-7-gcc* \ + make cmake curl wget gcc zlib-devel bzip2 \ + bzip2-devel readline-devel sqlite sqlite-devel \ + openssl-devel tk-devel libffi-devel qt5-qtbase-devel \ + patchelf ``` - -In case you run in error about `xcb` when running Pype, -you'll need also additional libraries for Qt5: - -```sh -sudo yum install qt5-qtbase-devel -``` - ::: -For more information about setting your build environmet please refer to [pyenv suggested build environment](https://github.com/pyenv/pyenv/wiki#suggested-build-environment) +:::note Install build requirements for other distros -#### Common steps for all Distros +Build process usually needs some reasonably recent versions of libraries and tools. You +can follow what's needed for Ubuntu and change it for your package manager. Centos 7 steps +have additional magic to overcame very old versions. +::: -Use pyenv to prepare Python version for Pype build +For more information about setting your build environment please refer to [pyenv suggested build environment](https://github.com/pyenv/pyenv/wiki#suggested-build-environment). -```sh -curl https://pyenv.run | bash - -# you can add those to ~/.bashrc -export PATH="$HOME/.pyenv/bin:$PATH" -eval "$(pyenv init -)" -eval "$(pyenv virtualenv-init -)" - -# reload shell -exec $SHELL - -# install Python 3.7.9 -pyenv install -v 3.7.9 - -# change path to pype 3 -cd /path/to/pype-3 - -# set local python version -pyenv local 3.7.9 - -``` #### To build Pype: - -1. Run `.\tools\create_env.sh` to create virtual environment in `.\venv` -2. Run `.\tools\build.sh` to build pype executables in `.\build\` +1. Run `./tools/fetch_thirdparty_libs.sh` to get **ffmpeg**, **oiio** and other tools needed. +2. Run `./tools/build.sh` to build pype executables in `.\build\` @@ -164,43 +189,43 @@ To build pype on MacOS you wil need: - **XCode Command Line Tools** (or some other build system) 1) Install **Homebrew**: -```sh -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +```shell +$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` 2) Install **cmake**: -```sh -brew install cmake +```shell +$ brew install cmake ``` 3) Install [pyenv](https://github.com/pyenv/pyenv): -```sh -brew install pyenv -echo 'eval "$(pypenv init -)"' >> ~/.zshrc -pyenv init -exec "$SHELL" -PATH=$(pyenv root)/shims:$PATH +```shell +$ brew install pyenv +$ echo 'eval "$(pypenv init -)"' >> ~/.zshrc +$ pyenv init +$ exec "$SHELL" +$ PATH=$(pyenv root)/shims:$PATH ``` 4) Pull in required Python version 3.7.x -```sh +```shell # install Python build dependences -brew install openssl readline sqlite3 xz zlib +$ brew install openssl readline sqlite3 xz zlib # replace with up-to-date 3.7.x version -pyenv install 3.7.9 +$ pyenv install 3.7.9 ``` 5) Set local Python version -```sh +```shell # switch to Pype source directory -pyenv local 3.7.9 +$ pyenv local 3.7.9 ``` #### To build Pype: -1. Run `.\tools\create_env.sh` to create virtual environment in `.\venv` -2. Run `.\tools\build.sh` to build Pype executables in `.\build\` +1. Run `./tools/create_env.sh` to create virtual environment in `./venv` +2. Run `./tools/build.sh` to build Pype executables in `./build/` From 843fa6f6e08db1a6934b50d0be9739f627ccefb9 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 14 May 2021 17:51:24 +0100 Subject: [PATCH 002/106] Removed Animation Set as asset type --- .../blender/plugins/create/create_setdress.py | 25 ---- .../hosts/blender/plugins/load/load_layout.py | 27 +--- .../publish/extract_animation_collection.py | 61 --------- .../unreal/plugins/load/load_setdress.py | 127 ------------------ 4 files changed, 7 insertions(+), 233 deletions(-) delete mode 100644 openpype/hosts/blender/plugins/create/create_setdress.py delete mode 100644 openpype/hosts/blender/plugins/publish/extract_animation_collection.py delete mode 100644 openpype/hosts/unreal/plugins/load/load_setdress.py diff --git a/openpype/hosts/blender/plugins/create/create_setdress.py b/openpype/hosts/blender/plugins/create/create_setdress.py deleted file mode 100644 index 97c737c235..0000000000 --- a/openpype/hosts/blender/plugins/create/create_setdress.py +++ /dev/null @@ -1,25 +0,0 @@ -import bpy - -from avalon import api, blender -import openpype.hosts.blender.api.plugin - - -class CreateSetDress(openpype.hosts.blender.api.plugin.Creator): - """A grouped package of loaded content""" - - name = "setdressMain" - label = "Set Dress" - family = "setdress" - icon = "cubes" - defaults = ["Main", "Anim"] - - def process(self): - asset = self.data["asset"] - subset = self.data["subset"] - name = openpype.hosts.blender.api.plugin.asset_name(asset, subset) - collection = bpy.data.collections.new(name=name) - bpy.context.scene.collection.children.link(collection) - self.data['task'] = api.Session.get('AVALON_TASK') - blender.lib.imprint(collection, self.data) - - return collection diff --git a/openpype/hosts/blender/plugins/load/load_layout.py b/openpype/hosts/blender/plugins/load/load_layout.py index f1f2fdcddd..08a905fbf0 100644 --- a/openpype/hosts/blender/plugins/load/load_layout.py +++ b/openpype/hosts/blender/plugins/load/load_layout.py @@ -25,9 +25,6 @@ class BlendLayoutLoader(plugin.AssetLoader): icon = "code-fork" color = "orange" - animation_creator_name = "CreateAnimation" - setdress_creator_name = "CreateSetDress" - def _remove(self, objects, obj_container): for obj in list(objects): if obj.type == 'ARMATURE': @@ -293,7 +290,6 @@ class UnrealLayoutLoader(plugin.AssetLoader): color = "orange" animation_creator_name = "CreateAnimation" - setdress_creator_name = "CreateSetDress" def _remove_objects(self, objects): for obj in list(objects): @@ -383,7 +379,7 @@ class UnrealLayoutLoader(plugin.AssetLoader): def _process( self, libpath, layout_container, container_name, representation, - actions, parent + actions, parent_collection ): with open(libpath, "r") as fp: data = json.load(fp) @@ -392,6 +388,11 @@ class UnrealLayoutLoader(plugin.AssetLoader): layout_collection = bpy.data.collections.new(container_name) scene.collection.children.link(layout_collection) + parent = parent_collection + + if parent is None: + parent = scene.collection + all_loaders = api.discover(api.Loader) avalon_container = bpy.data.collections.get( @@ -516,23 +517,9 @@ class UnrealLayoutLoader(plugin.AssetLoader): container_metadata["libpath"] = libpath container_metadata["lib_container"] = lib_container - # Create a setdress subset to contain all the animation for all - # the rigs in the layout - creator_plugin = get_creator_by_name(self.setdress_creator_name) - if not creator_plugin: - raise ValueError("Creator plugin \"{}\" was not found.".format( - self.setdress_creator_name - )) - parent = api.create( - creator_plugin, - name="animation", - asset=api.Session["AVALON_ASSET"], - options={"useSelection": True}, - data={"dependencies": str(context["representation"]["_id"])}) - layout_collection = self._process( libpath, layout_container, container_name, - str(context["representation"]["_id"]), None, parent) + str(context["representation"]["_id"]), None, None) container_metadata["obj_container"] = layout_collection diff --git a/openpype/hosts/blender/plugins/publish/extract_animation_collection.py b/openpype/hosts/blender/plugins/publish/extract_animation_collection.py deleted file mode 100644 index 19dc59c5cd..0000000000 --- a/openpype/hosts/blender/plugins/publish/extract_animation_collection.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import json - -import openpype.api -import pyblish.api - -import bpy - - -class ExtractSetDress(openpype.api.Extractor): - """Extract setdress.""" - - label = "Extract SetDress" - hosts = ["blender"] - families = ["setdress"] - optional = True - order = pyblish.api.ExtractorOrder + 0.1 - - def process(self, instance): - stagingdir = self.staging_dir(instance) - - json_data = [] - - for i in instance.context: - collection = i.data.get("name") - container = None - for obj in bpy.data.collections[collection].objects: - if obj.type == "ARMATURE": - container_name = obj.get("avalon").get("container_name") - container = bpy.data.collections[container_name] - if container: - json_dict = { - "subset": i.data.get("subset"), - "container": container.name, - } - json_dict["instance_name"] = container.get("avalon").get( - "instance_name" - ) - json_data.append(json_dict) - - if "representations" not in instance.data: - instance.data["representations"] = [] - - json_filename = f"{instance.name}.json" - json_path = os.path.join(stagingdir, json_filename) - - with open(json_path, "w+") as file: - json.dump(json_data, fp=file, indent=2) - - json_representation = { - "name": "json", - "ext": "json", - "files": json_filename, - "stagingDir": stagingdir, - } - instance.data["representations"].append(json_representation) - - self.log.info( - "Extracted instance '{}' to: {}".format(instance.name, - json_representation) - ) diff --git a/openpype/hosts/unreal/plugins/load/load_setdress.py b/openpype/hosts/unreal/plugins/load/load_setdress.py deleted file mode 100644 index da302deb1c..0000000000 --- a/openpype/hosts/unreal/plugins/load/load_setdress.py +++ /dev/null @@ -1,127 +0,0 @@ -import json - -from avalon import api -import unreal - - -class AnimationCollectionLoader(api.Loader): - """Load Unreal SkeletalMesh from FBX""" - - families = ["setdress"] - representations = ["json"] - - label = "Load Animation Collection" - icon = "cube" - color = "orange" - - def load(self, context, name, namespace, options): - from avalon import api, pipeline - from avalon.unreal import lib - from avalon.unreal import pipeline as unreal_pipeline - import unreal - - # Create directory for asset and avalon container - root = "/Game/Avalon/Assets" - asset = context.get('asset').get('name') - suffix = "_CON" - - tools = unreal.AssetToolsHelpers().get_asset_tools() - asset_dir, container_name = tools.create_unique_asset_name( - "{}/{}".format(root, asset), suffix="") - - container_name += suffix - - unreal.EditorAssetLibrary.make_directory(asset_dir) - - libpath = self.fname - - with open(libpath, "r") as fp: - data = json.load(fp) - - all_loaders = api.discover(api.Loader) - - for element in data: - reference = element.get('_id') - - loaders = api.loaders_from_representation(all_loaders, reference) - loader = None - for l in loaders: - if l.__name__ == "AnimationFBXLoader": - loader = l - break - - if not loader: - continue - - instance_name = element.get('instance_name') - - api.load( - loader, - reference, - namespace=instance_name, - options=element - ) - - # Create Asset Container - lib.create_avalon_container( - container=container_name, path=asset_dir) - - data = { - "schema": "openpype:container-2.0", - "id": pipeline.AVALON_CONTAINER_ID, - "asset": asset, - "namespace": asset_dir, - "container_name": container_name, - "loader": str(self.__class__.__name__), - "representation": context["representation"]["_id"], - "parent": context["representation"]["parent"], - "family": context["representation"]["context"]["family"] - } - unreal_pipeline.imprint( - "{}/{}".format(asset_dir, container_name), data) - - asset_content = unreal.EditorAssetLibrary.list_assets( - asset_dir, recursive=True, include_folder=True - ) - - return asset_content - - def update(self, container, representation): - from avalon import api, io - from avalon.unreal import pipeline - - source_path = api.get_representation_path(representation) - - with open(source_path, "r") as fp: - data = json.load(fp) - - animation_containers = [ - i for i in pipeline.ls() if - i.get('asset') == container.get('asset') and - i.get('family') == 'animation'] - - for element in data: - new_version = io.find_one({"_id": io.ObjectId(element.get('_id'))}) - new_version_number = new_version.get('context').get('version') - anim_container = None - for i in animation_containers: - if i.get('container_name') == (element.get('subset') + "_CON"): - anim_container = i - break - if not anim_container: - continue - - api.update(anim_container, new_version_number) - - container_path = "{}/{}".format(container["namespace"], - container["objectName"]) - # update metadata - pipeline.imprint( - container_path, - { - "representation": str(representation["_id"]), - "parent": str(representation["parent"]) - }) - - def remove(self, container): - unreal.EditorAssetLibrary.delete_directory(container["namespace"]) From b4c826c4a93208ac85098fde0a1483ecff4c6e61 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 14 May 2021 17:52:11 +0100 Subject: [PATCH 003/106] Fixed problem with non local actions when loading rigs --- openpype/hosts/blender/plugins/load/load_rig.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/blender/plugins/load/load_rig.py b/openpype/hosts/blender/plugins/load/load_rig.py index c5690a6ab8..0c92354310 100644 --- a/openpype/hosts/blender/plugins/load/load_rig.py +++ b/openpype/hosts/blender/plugins/load/load_rig.py @@ -107,6 +107,9 @@ class BlendRigLoader(plugin.AssetLoader): if action is not None: local_obj.animation_data.action = action + elif local_obj.animation_data.action is not None: + plugin.prepare_data( + local_obj.animation_data.action, collection_name) # Set link the drivers to the local object if local_obj.data.animation_data: From 8c03e16314db5fe886f5864a8c2e593bb79d5762 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 14 May 2021 17:56:16 +0100 Subject: [PATCH 004/106] Improved extraction of animation from Blender and loading in Unreal A json file is extracted together with the animation fbx. The json file stores the instance name of the asset in Unreal. Thus, when loading the animation in Unreal, it can be associated with a skeleton and automatically applied to the right SkeletalMesh. --- .../plugins/publish/extract_fbx_animation.py | 33 ++++++++++++++++ .../unreal/plugins/load/load_animation.py | 38 +++++++++++++++---- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py index 1036800705..418dd100b2 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py @@ -1,4 +1,5 @@ import os +import json import openpype.api @@ -121,6 +122,30 @@ class ExtractAnimationFBX(openpype.api.Extractor): pair[1].user_clear() bpy.data.actions.remove(pair[1]) + json_filename = f"{instance.name}.json" + json_path = os.path.join(stagingdir, json_filename) + + json_dict = {} + + collection = instance.data.get("name") + container = None + for obj in bpy.data.collections[collection].objects: + if obj.type == "ARMATURE": + container_name = obj.get("avalon").get("container_name") + container = bpy.data.collections[container_name] + if container: + json_dict = { + # "representation": container.get("avalon").get( + # "representation" + # ), + "instance_name": container.get("avalon").get( + "instance_name" + ) + } + + with open(json_path, "w+") as file: + json.dump(json_dict, fp=file, indent=2) + if "representations" not in instance.data: instance.data["representations"] = [] @@ -130,7 +155,15 @@ class ExtractAnimationFBX(openpype.api.Extractor): 'files': fbx_filename, "stagingDir": stagingdir, } + json_representation = { + 'name': 'json', + 'ext': 'json', + 'files': json_filename, + "stagingDir": stagingdir, + } instance.data["representations"].append(fbx_representation) + instance.data["representations"].append(json_representation) + self.log.info("Extracted instance '{}' to: {}".format( instance.name, fbx_representation)) diff --git a/openpype/hosts/unreal/plugins/load/load_animation.py b/openpype/hosts/unreal/plugins/load/load_animation.py index 18910983ea..a53328847d 100644 --- a/openpype/hosts/unreal/plugins/load/load_animation.py +++ b/openpype/hosts/unreal/plugins/load/load_animation.py @@ -1,4 +1,5 @@ import os +import json from avalon import api, pipeline from avalon.unreal import lib @@ -61,10 +62,16 @@ class AnimationFBXLoader(api.Loader): task = unreal.AssetImportTask() task.options = unreal.FbxImportUI() - # If there are no options, the process cannot be automated - if options: + libpath = self.fname.replace("fbx", "json") + + with open(libpath, "r") as fp: + data = json.load(fp) + + instance_name = data.get("instance_name") + + if instance_name: automated = True - actor_name = 'PersistentLevel.' + options.get('instance_name') + actor_name = 'PersistentLevel.' + instance_name actor = unreal.EditorLevelLibrary.get_actor_reference(actor_name) skeleton = actor.skeletal_mesh_component.skeletal_mesh.skeleton task.options.set_editor_property('skeleton', skeleton) @@ -81,16 +88,31 @@ class AnimationFBXLoader(api.Loader): # set import options here task.options.set_editor_property( - 'automated_import_should_detect_type', True) + 'automated_import_should_detect_type', False) task.options.set_editor_property( - 'original_import_type', unreal.FBXImportType.FBXIT_ANIMATION) + 'original_import_type', unreal.FBXImportType.FBXIT_SKELETAL_MESH) + task.options.set_editor_property( + 'mesh_type_to_import', unreal.FBXImportType.FBXIT_ANIMATION) task.options.set_editor_property('import_mesh', False) task.options.set_editor_property('import_animations', True) + task.options.set_editor_property('override_full_name', True) - task.options.skeletal_mesh_import_data.set_editor_property( - 'import_content_type', - unreal.FBXImportContentType.FBXICT_SKINNING_WEIGHTS + task.options.anim_sequence_import_data.set_editor_property( + 'animation_length', + unreal.FBXAnimationLengthImportType.FBXALIT_EXPORTED_TIME ) + task.options.anim_sequence_import_data.set_editor_property( + 'import_meshes_in_bone_hierarchy', False) + task.options.anim_sequence_import_data.set_editor_property( + 'use_default_sample_rate', True) + task.options.anim_sequence_import_data.set_editor_property( + 'import_custom_attribute', True) + task.options.anim_sequence_import_data.set_editor_property( + 'import_bone_tracks', True) + task.options.anim_sequence_import_data.set_editor_property( + 'remove_redundant_keys', True) + task.options.anim_sequence_import_data.set_editor_property( + 'convert_scene', True) unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task]) From 963127e08e45698e03a7f79a720c4f4e44c0d56c Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 14 May 2021 18:04:07 +0100 Subject: [PATCH 005/106] Hound fix --- .../hosts/blender/plugins/publish/extract_fbx_animation.py | 7 +------ openpype/hosts/unreal/plugins/load/load_animation.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py index 418dd100b2..8312114c7b 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py @@ -135,12 +135,7 @@ class ExtractAnimationFBX(openpype.api.Extractor): container = bpy.data.collections[container_name] if container: json_dict = { - # "representation": container.get("avalon").get( - # "representation" - # ), - "instance_name": container.get("avalon").get( - "instance_name" - ) + "instance_name": container.get("avalon").get("instance_name") } with open(json_path, "w+") as file: diff --git a/openpype/hosts/unreal/plugins/load/load_animation.py b/openpype/hosts/unreal/plugins/load/load_animation.py index a53328847d..481285d603 100644 --- a/openpype/hosts/unreal/plugins/load/load_animation.py +++ b/openpype/hosts/unreal/plugins/load/load_animation.py @@ -98,7 +98,7 @@ class AnimationFBXLoader(api.Loader): task.options.set_editor_property('override_full_name', True) task.options.anim_sequence_import_data.set_editor_property( - 'animation_length', + 'animation_length', unreal.FBXAnimationLengthImportType.FBXALIT_EXPORTED_TIME ) task.options.anim_sequence_import_data.set_editor_property( From 424e9950e719a4f4a965bc9c8da4fd3bb4be9540 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 10:40:38 +0200 Subject: [PATCH 006/106] blender implementation has copy of blender `load_scripts` function --- openpype/hosts/blender/api/lib.py | 93 +++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 openpype/hosts/blender/api/lib.py diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py new file mode 100644 index 0000000000..38a745f6ca --- /dev/null +++ b/openpype/hosts/blender/api/lib.py @@ -0,0 +1,93 @@ +import os +import traceback +import importlib + +import bpy + + +def load_scripts(paths): + """Copy of `load_scripts` from Blender's implementation. + + It is possible that whis function will be changed in future and usage will + be based on Blender version. + """ + import bpy_types + + loaded_modules = set() + + previous_classes = [ + cls + for cls in bpy.types.bpy_struct.__subclasses__() + ] + + def register_module_call(mod): + register = getattr(mod, "register", None) + if register: + try: + register() + except: + traceback.print_exc() + else: + print("\nWarning! '%s' has no register function, " + "this is now a requirement for registerable scripts" % + mod.__file__) + + def unregister_module_call(mod): + unregister = getattr(mod, "unregister", None) + if unregister: + try: + unregister() + except: + traceback.print_exc() + + def test_reload(mod): + # reloading this causes internal errors + # because the classes from this module are stored internally + # possibly to refresh internal references too but for now, best not to. + if mod == bpy_types: + return mod + + try: + return importlib.reload(mod) + except: + traceback.print_exc() + + def test_register(mod): + if mod: + register_module_call(mod) + bpy.utils._global_loaded_modules.append(mod.__name__) + + from bpy_restrict_state import RestrictBlend + + with RestrictBlend(): + for base_path in paths: + for path_subdir in bpy.utils._script_module_dirs: + path = os.path.join(base_path, path_subdir) + if not os.path.isdir(path): + continue + + bpy.utils._sys_path_ensure_prepend(path) + + # Only add to 'sys.modules' unless this is 'startup'. + if path_subdir != "startup": + continue + for mod in bpy.utils.modules_from_path(path, loaded_modules): + test_register(mod) + + # load template (if set) + if any(bpy.utils.app_template_paths()): + import bl_app_template_utils + bl_app_template_utils.reset(reload_scripts=False) + del bl_app_template_utils + + for cls in bpy.types.bpy_struct.__subclasses__(): + if cls in previous_classes: + continue + if not getattr(cls, "is_registered", False): + continue + for subcls in cls.__subclasses__(): + if not subcls.is_registered: + print( + "Warning, unregistered class: %s(%s)" % + (subcls.__name__, cls.__name__) + ) From 5110374a1b0dcc40e1fb0f554300bb287c5fe926 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 10:40:58 +0200 Subject: [PATCH 007/106] implemented `append_user_scripts` using `OPENPYPE_BLENDER_USER_SCRIPTS` env to load user scripts --- openpype/hosts/blender/api/lib.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index 38a745f6ca..6aa1cb46ac 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -91,3 +91,15 @@ def load_scripts(paths): "Warning, unregistered class: %s(%s)" % (subcls.__name__, cls.__name__) ) + + +def append_user_scripts(): + user_scripts = os.environ.get("OPENPYPE_BLENDER_USER_SCRIPTS") + if not user_scripts: + return + + try: + load_scripts(user_scripts.split(os.pathsep)) + except Exception: + print("Couldn't load user scripts \"{}\"".format(user_scripts)) + traceback.print_exc() From 83590556c5b8adfb07303e9972a490d5fbdb9b3e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 10:41:10 +0200 Subject: [PATCH 008/106] run append_user_scripts on blender install --- openpype/hosts/blender/api/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/__init__.py b/openpype/hosts/blender/api/__init__.py index 66102a2ae1..ecf4fdf4da 100644 --- a/openpype/hosts/blender/api/__init__.py +++ b/openpype/hosts/blender/api/__init__.py @@ -4,6 +4,8 @@ import traceback import bpy +from .lib import append_user_scripts + from avalon import api as avalon from pyblish import api as pyblish @@ -29,7 +31,7 @@ def install(): pyblish.register_plugin_path(str(PUBLISH_PATH)) avalon.register_plugin_path(avalon.Loader, str(LOAD_PATH)) avalon.register_plugin_path(avalon.Creator, str(CREATE_PATH)) - + append_user_scripts() avalon.on("new", on_new) avalon.on("open", on_open) From 8df855aa115559e3d9542c5b667cc11a52baae90 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 10:54:12 +0200 Subject: [PATCH 009/106] modified blender's init to expect somebody will set OPENPYPE_BLENDER_USER_SCRIPTS --- openpype/hosts/blender/__init__.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/blender/__init__.py b/openpype/hosts/blender/__init__.py index 4d93233449..747394aad0 100644 --- a/openpype/hosts/blender/__init__.py +++ b/openpype/hosts/blender/__init__.py @@ -23,18 +23,32 @@ def add_implementation_envs(env, _app): env["PYTHONPATH"] = os.pathsep.join(python_path_parts) # Modify Blender user scripts path + previous_user_scripts = set() + # Implementation path is added to set for easier paths check inside loops + # - will be removed at the end + previous_user_scripts.add(implementation_user_script_path) + + openpype_blender_user_scripts = ( + env.get("OPENPYPE_BLENDER_USER_SCRIPTS") or "" + ) + for path in openpype_blender_user_scripts.split(os.pathsep): + if path and os.path.exists(path): + previous_user_scripts.add(os.path.normpath(path)) + blender_user_scripts = env.get("BLENDER_USER_SCRIPTS") or "" - previous_user_scripts = [] for path in blender_user_scripts.split(os.pathsep): if path and os.path.exists(path): - path = os.path.normpath(path) - if path != implementation_user_script_path: - previous_user_scripts.append(path) + previous_user_scripts.add(os.path.normpath(path)) + # Remove implementation path from user script paths as is set to + # `BLENDER_USER_SCRIPTS` + previous_user_scripts.remove(implementation_user_script_path) + env["BLENDER_USER_SCRIPTS"] = implementation_user_script_path + + # Set custom user scripts env env["OPENPYPE_BLENDER_USER_SCRIPTS"] = os.pathsep.join( previous_user_scripts ) - env["BLENDER_USER_SCRIPTS"] = implementation_user_script_path # Define Qt binding if not defined if not env.get("QT_PREFERRED_BINDING"): From 76e0be34c8869ecb85833c8064a6b921d6ee9bd8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 12:43:33 +0200 Subject: [PATCH 010/106] added schema for bg color in extract review --- .../schemas/schema_global_publish.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 0efe3b8fea..6989252826 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -193,6 +193,20 @@ "minimum": 0, "maximum": 100000 }, + { + "type": "label", + "label": "Background color is used only when input have transparency and Alpha is higher than 0." + }, + { + "type": "schema_template", + "name": "template_rgba_color", + "template_data": [ + { + "label": "Background color", + "name": "bg_color" + } + ] + }, { "key": "letter_box", "label": "Letter box", From 968c8028e607ff779cfad614ce4df977f6074aad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 12:44:06 +0200 Subject: [PATCH 011/106] saved default bg color --- openpype/settings/defaults/project_settings/global.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 1f54bed03c..6b079e367e 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -57,6 +57,12 @@ }, "width": 0, "height": 0, + "bg_color": [ + 0, + 0, + 0, + 0 + ], "letter_box": { "enabled": false, "ratio": 0.0, From f249499b5bc10cba85682de5311bdec5fb9ac00f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 13:15:53 +0200 Subject: [PATCH 012/106] add bg color to ffmpeg args if is set --- openpype/plugins/publish/extract_review.py | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 048d16fabb..af30e6534d 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -470,6 +470,33 @@ class ExtractReview(pyblish.api.InstancePlugin): lut_filters = self.lut_filters(new_repre, instance, ffmpeg_input_args) ffmpeg_video_filters.extend(lut_filters) + bg_alpha = 0 + bg_color = output_def.get("bg_color") + if bg_color: + bg_red, bg_green, bg_blue, bg_alpha = bg_color + + if bg_alpha > 0: + if not temp_data["input_allow_bg"]: + self.log.info(( + "Output definition has defined BG color input was" + " resolved as does not support adding BG." + )) + else: + bg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( + bg_red, bg_green, bg_blue + ) + bg_color_alpha = float(bg_alpha) / 255 + bg_color_str = "{}@{}".format(bg_color_hex, bg_color_alpha) + + self.log.info("Applying BG color {}".format(bg_color_str)) + ffmpeg_video_filters.extend([ + "split=2[bg][fg]", + "[bg]drawbox=c={}:replace=1:t=fill[bg]".format( + bg_color_str + ), + "[bg][fg]overlay=format=auto" + ]) + # Add argument to override output file ffmpeg_output_args.append("-y") From 4f0f91e9563180496f0316860f5339d9ae57e5c6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 14:05:29 +0200 Subject: [PATCH 013/106] defined if input is valid for bg color usage --- openpype/plugins/publish/extract_review.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index af30e6534d..816bcbbc51 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -48,6 +48,8 @@ class ExtractReview(pyblish.api.InstancePlugin): video_exts = ["mov", "mp4"] supported_exts = image_exts + video_exts + alpha_exts = ["exr", "png", "dpx"] + # FFmpeg tools paths ffmpeg_path = get_ffmpeg_tool_path("ffmpeg") @@ -296,6 +298,13 @@ class ExtractReview(pyblish.api.InstancePlugin): ): with_audio = False + input_is_sequence = self.input_is_sequence(repre) + input_allow_bg = False + if input_is_sequence and repre["files"]: + ext = os.path.splitext(repre["files"][0])[1].replace(".", "") + if ext in self.alpha_exts: + input_allow_bg = True + return { "fps": float(instance.data["fps"]), "frame_start": frame_start, @@ -310,7 +319,8 @@ class ExtractReview(pyblish.api.InstancePlugin): "resolution_width": instance.data.get("resolutionWidth"), "resolution_height": instance.data.get("resolutionHeight"), "origin_repre": repre, - "input_is_sequence": self.input_is_sequence(repre), + "input_is_sequence": input_is_sequence, + "input_allow_bg": input_allow_bg, "with_audio": with_audio, "without_handles": without_handles, "handles_are_set": handles_are_set From 19312827f75618975a4053891626e12855f27651 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 14:05:50 +0200 Subject: [PATCH 014/106] prepend bg color filters before all other filters --- openpype/plugins/publish/extract_review.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 816bcbbc51..0d97afe3ae 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -499,13 +499,18 @@ class ExtractReview(pyblish.api.InstancePlugin): bg_color_str = "{}@{}".format(bg_color_hex, bg_color_alpha) self.log.info("Applying BG color {}".format(bg_color_str)) - ffmpeg_video_filters.extend([ + color_args = [ "split=2[bg][fg]", "[bg]drawbox=c={}:replace=1:t=fill[bg]".format( bg_color_str ), "[bg][fg]overlay=format=auto" - ]) + ] + # Prepend bg color change before all video filters + # NOTE at the time of creation it is required as video filters + # from settings may affect color of BG (e.g. to grey) + for arg in reversed(color_args): + ffmpeg_video_filters.insert(0, arg) # Add argument to override output file ffmpeg_output_args.append("-y") From d888fcf9849b101d303f049a619f55d257fa7de6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 14:22:52 +0200 Subject: [PATCH 015/106] modified comment --- openpype/plugins/publish/extract_review.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 0d97afe3ae..7569023e0c 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -508,7 +508,8 @@ class ExtractReview(pyblish.api.InstancePlugin): ] # Prepend bg color change before all video filters # NOTE at the time of creation it is required as video filters - # from settings may affect color of BG (e.g. to grey) + # from settings may affect color of BG + # e.g. `eq` can remove alpha from input for arg in reversed(color_args): ffmpeg_video_filters.insert(0, arg) From 86f7fa9bc58c328fb838ef1205353d6aaeb87fce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 14:30:31 +0200 Subject: [PATCH 016/106] replaced `eq` filter with `apply_trc` argument in defualt settings --- openpype/settings/defaults/project_settings/global.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 6b079e367e..d3b8c55d07 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -37,11 +37,11 @@ "ftrackreview" ], "ffmpeg_args": { - "video_filters": [ - "eq=gamma=2.2" - ], + "video_filters": [], "audio_filters": [], - "input": [], + "input": [ + "-apply_trc gamma22" + ], "output": [ "-pix_fmt yuv420p", "-crf 18", From e9a38a5f53ff48912b9747f113dde56be643f91b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 17:23:13 +0200 Subject: [PATCH 017/106] created base of InvalidValueType (BaseInvalidValueType) to be able pass reason directly --- openpype/settings/entities/__init__.py | 2 ++ openpype/settings/entities/base_entity.py | 3 ++- openpype/settings/entities/exceptions.py | 16 +++++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/openpype/settings/entities/__init__.py b/openpype/settings/entities/__init__.py index 2c71b622ee..5d83a7cde4 100644 --- a/openpype/settings/entities/__init__.py +++ b/openpype/settings/entities/__init__.py @@ -57,6 +57,7 @@ from .exceptions import ( SchemaError, DefaultsNotDefined, StudioDefaultsNotDefined, + BaseInvalidValueType, InvalidValueType, InvalidKeySymbols, SchemaMissingFileInfo, @@ -115,6 +116,7 @@ from .anatomy_entities import AnatomyEntity __all__ = ( "DefaultsNotDefined", "StudioDefaultsNotDefined", + "BaseInvalidValueType", "InvalidValueType", "InvalidKeySymbols", "SchemaMissingFileInfo", diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index 3e73fa8aa6..76150950b5 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -9,6 +9,7 @@ from .lib import ( ) from .exceptions import ( + BaseInvalidValueType, InvalidValueType, SchemeGroupHierarchyBug, EntitySchemaError @@ -377,7 +378,7 @@ class BaseItemEntity(BaseEntity): try: new_value = self.convert_to_valid_type(value) - except InvalidValueType: + except BaseInvalidValueType: new_value = NOT_SET if new_value is not NOT_SET: diff --git a/openpype/settings/entities/exceptions.py b/openpype/settings/entities/exceptions.py index 3649e63ab7..f352c94f20 100644 --- a/openpype/settings/entities/exceptions.py +++ b/openpype/settings/entities/exceptions.py @@ -15,20 +15,22 @@ class StudioDefaultsNotDefined(Exception): super(StudioDefaultsNotDefined, self).__init__(msg) -class InvalidValueType(Exception): - msg_template = "{}" +class BaseInvalidValueType(Exception): + def __init__(self, reason, path): + msg = "Path \"{}\". {}".format(path, reason) + self.msg = msg + super(BaseInvalidValueType, self).__init__(msg) + +class InvalidValueType(BaseInvalidValueType): def __init__(self, valid_types, invalid_type, path): - msg = "Path \"{}\". ".format(path) - joined_types = ", ".join( [str(valid_type) for valid_type in valid_types] ) - msg += "Got invalid type \"{}\". Expected: {}".format( + msg = "Got invalid type \"{}\". Expected: {}".format( invalid_type, joined_types ) - self.msg = msg - super(InvalidValueType, self).__init__(msg) + super(InvalidValueType, self).__init__(msg, path) class RequiredKeyModified(KeyError): From b420ea6971c01410ec49b81cde5356cec9f18532 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 17:24:53 +0200 Subject: [PATCH 018/106] base implementation of ColorEntity --- openpype/settings/entities/__init__.py | 4 +- openpype/settings/entities/color_entity.py | 53 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 openpype/settings/entities/color_entity.py diff --git a/openpype/settings/entities/__init__.py b/openpype/settings/entities/__init__.py index 5d83a7cde4..33881a6097 100644 --- a/openpype/settings/entities/__init__.py +++ b/openpype/settings/entities/__init__.py @@ -97,7 +97,7 @@ from .input_entities import ( PathInput, RawJsonEntity ) - +from .color_entity import ColorEntity from .enum_entity import ( BaseEnumEntity, EnumEntity, @@ -148,6 +148,8 @@ __all__ = ( "PathInput", "RawJsonEntity", + "ColorEntity", + "BaseEnumEntity", "EnumEntity", "AppsEnumEntity", diff --git a/openpype/settings/entities/color_entity.py b/openpype/settings/entities/color_entity.py new file mode 100644 index 0000000000..7d31ba42b9 --- /dev/null +++ b/openpype/settings/entities/color_entity.py @@ -0,0 +1,53 @@ +from .lib import STRING_TYPE +from .input_entities import InputEntity +from .exceptions import ( + BaseInvalidValueType, + InvalidValueType +) + + +class ColorEntity(InputEntity): + schema_types = ["color"] + def _item_initalization(self): + self.valid_value_types = (list, ) + self.value_on_not_set = [0, 0, 0, 255] + + def convert_to_valid_type(self, value): + """Conversion to valid type. + + Complexity of entity requires to override BaseEntity implementation. + """ + # Convertion to valid value type `list` + if isinstance(value, (set, tuple)): + value = list(value) + + # Skip other validations if is not `list` + if not isinstance(value, list): + raise InvalidValueType( + self.valid_value_types, type(value), self.path + ) + + # Allow list of len 3 (last aplha is set to max) + if len(value) == 3: + value.append(255) + + if len(value) != 4: + reason = "Color entity expect 4 items in list got {}".format( + len(value) + ) + raise BaseInvalidValueType(reason, self.path) + + new_value = [] + for item in value: + if not isinstance(item, int): + if isinstance(item, (STRING_TYPE, float)): + item = int(item) + + is_valid = isinstance(item, int) and -1 < item < 256 + if not is_valid: + reason = ( + "Color entity expect 4 integers in range 0-255 got {}" + ).format(value) + raise BaseInvalidValueType(reason, self.path) + new_value.append(item) + return new_value From d3673ae627b4e115cd6574183b33f921e2b84690 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 17:25:54 +0200 Subject: [PATCH 019/106] copy pasted PyQtColorTriangle project --- openpype/widgets/color_widgets/__init__.py | 6 + .../widgets/color_widgets/color_inputs.py | 514 ++++++ .../color_widgets/color_picker_widget.py | 115 ++ .../color_widgets/color_screen_pick.py | 248 +++ .../widgets/color_widgets/color_triangle.py | 1431 +++++++++++++++++ openpype/widgets/color_widgets/color_view.py | 78 + 6 files changed, 2392 insertions(+) create mode 100644 openpype/widgets/color_widgets/__init__.py create mode 100644 openpype/widgets/color_widgets/color_inputs.py create mode 100644 openpype/widgets/color_widgets/color_picker_widget.py create mode 100644 openpype/widgets/color_widgets/color_screen_pick.py create mode 100644 openpype/widgets/color_widgets/color_triangle.py create mode 100644 openpype/widgets/color_widgets/color_view.py diff --git a/openpype/widgets/color_widgets/__init__.py b/openpype/widgets/color_widgets/__init__.py new file mode 100644 index 0000000000..3423e26cf8 --- /dev/null +++ b/openpype/widgets/color_widgets/__init__.py @@ -0,0 +1,6 @@ +from .color_picker_widget import ColorPickerWidget + + +__all__ = ( + "ColorPickerWidget", +) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py new file mode 100644 index 0000000000..ddf8aebd4e --- /dev/null +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -0,0 +1,514 @@ +import re +from Qt import QtWidgets, QtCore, QtGui + + +slide_style = """ +QSlider::groove:horizontal { + background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #000, stop: 1 #fff); + height: 8px; + border-radius: 4px; +} + +QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #ddd, stop:1 #bbb); + border: 1px solid #777; + width: 8px; + margin-top: -1px; + margin-bottom: -1px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #eee, stop:1 #ddd); + border: 1px solid #444;ff + border-radius: 4px; +}""" + + +class AlphaInputs(QtWidgets.QGroupBox): + alpha_changed = QtCore.Signal(int) + + def __init__(self, parent=None): + super(AlphaInputs, self).__init__("Alpha", parent) + + self._block_changes = False + self.alpha_value = None + + # Opacity slider + alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) + alpha_slider.setSingleStep(1) + alpha_slider.setMinimum(0) + alpha_slider.setMaximum(255) + alpha_slider.setStyleSheet(slide_style) + alpha_slider.setValue(255) + + inputs_widget = QtWidgets.QWidget(self) + inputs_layout = QtWidgets.QHBoxLayout(inputs_widget) + inputs_layout.setContentsMargins(0, 0, 0, 0) + + percent_input = QtWidgets.QDoubleSpinBox(self) + percent_input.setMinimum(0) + percent_input.setMaximum(100) + percent_input.setDecimals(2) + + int_input = QtWidgets.QSpinBox(self) + int_input.setMinimum(0) + int_input.setMaximum(255) + + inputs_layout.addWidget(int_input) + inputs_layout.addWidget(QtWidgets.QLabel("0-255")) + inputs_layout.addWidget(percent_input) + inputs_layout.addWidget(QtWidgets.QLabel("%")) + + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(alpha_slider) + layout.addWidget(inputs_widget) + + alpha_slider.valueChanged.connect(self._on_slider_change) + percent_input.valueChanged.connect(self._on_percent_change) + int_input.valueChanged.connect(self._on_int_change) + + self.alpha_slider = alpha_slider + self.percent_input = percent_input + self.int_input = int_input + + self.set_alpha(255) + + def set_alpha(self, alpha): + if alpha == self.alpha_value: + return + self.alpha_value = alpha + + self.update_alpha() + + def _on_slider_change(self): + if self._block_changes: + return + self.alpha_value = self.alpha_slider.value() + self.alpha_changed.emit(self.alpha_value) + self.update_alpha() + + def _on_percent_change(self): + if self._block_changes: + return + self.alpha_value = int(self.percent_input.value() * 255 / 100) + self.alpha_changed.emit(self.alpha_value) + self.update_alpha() + + def _on_int_change(self): + if self._block_changes: + return + + self.alpha_value = self.int_input.value() + self.alpha_changed.emit(self.alpha_value) + self.update_alpha() + + def update_alpha(self): + self._block_changes = True + + if self.alpha_slider.value() != self.alpha_value: + self.alpha_slider.setValue(self.alpha_value) + + if self.int_input.value() != self.alpha_value: + self.int_input.setValue(self.alpha_value) + + percent = round(100 * self.alpha_value / 255, 2) + if self.percent_input.value() != percent: + self.percent_input.setValue(percent) + + self._block_changes = False + + +class RGBInputs(QtWidgets.QGroupBox): + value_changed = QtCore.Signal() + + def __init__(self, color, parent=None): + super(RGBInputs, self).__init__("RGB", parent) + + self._block_changes = False + + self.color = color + + input_red = QtWidgets.QSpinBox(self) + input_green = QtWidgets.QSpinBox(self) + input_blue = QtWidgets.QSpinBox(self) + + input_red.setMinimum(0) + input_green.setMinimum(0) + input_blue.setMinimum(0) + + input_red.setMaximum(255) + input_green.setMaximum(255) + input_blue.setMaximum(255) + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(input_red) + layout.addWidget(input_green) + layout.addWidget(input_blue) + + input_red.valueChanged.connect(self._on_red_change) + input_green.valueChanged.connect(self._on_green_change) + input_blue.valueChanged.connect(self._on_blue_change) + + self.input_red = input_red + self.input_green = input_green + self.input_blue = input_blue + + def _on_red_change(self, value): + if self._block_changes: + return + self.color.setRed(value) + self._on_change() + + def _on_green_change(self, value): + if self._block_changes: + return + self.color.setGreen(value) + self._on_change() + + def _on_blue_change(self, value): + if self._block_changes: + return + self.color.setBlue(value) + self._on_change() + + def _on_change(self): + self.value_changed.emit() + + def color_changed(self): + if ( + self.input_red.value() == self.color.red() + and self.input_green.value() == self.color.green() + and self.input_blue.value() == self.color.blue() + ): + return + + self._block_changes = True + + self.input_red.setValue(self.color.red()) + self.input_green.setValue(self.color.green()) + self.input_blue.setValue(self.color.blue()) + + self._block_changes = False + + +class CMYKInputs(QtWidgets.QGroupBox): + value_changed = QtCore.Signal() + + def __init__(self, color, parent=None): + super(CMYKInputs, self).__init__("CMYK", parent) + + self.color = color + + self._block_changes = False + + input_cyan = QtWidgets.QSpinBox(self) + input_magenta = QtWidgets.QSpinBox(self) + input_yellow = QtWidgets.QSpinBox(self) + input_black = QtWidgets.QSpinBox(self) + + input_cyan.setMinimum(0) + input_magenta.setMinimum(0) + input_yellow.setMinimum(0) + input_black.setMinimum(0) + + input_cyan.setMaximum(255) + input_magenta.setMaximum(255) + input_yellow.setMaximum(255) + input_black.setMaximum(255) + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(input_cyan) + layout.addWidget(input_magenta) + layout.addWidget(input_yellow) + layout.addWidget(input_black) + + input_cyan.valueChanged.connect(self._on_change) + input_magenta.valueChanged.connect(self._on_change) + input_yellow.valueChanged.connect(self._on_change) + input_black.valueChanged.connect(self._on_change) + + self.input_cyan = input_cyan + self.input_magenta = input_magenta + self.input_yellow = input_yellow + self.input_black = input_black + + def _on_change(self): + if self._block_changes: + return + self.color.setCmyk( + self.input_cyan.value(), + self.input_magenta.value(), + self.input_yellow.value(), + self.input_black.value() + ) + self.value_changed.emit() + + def color_changed(self): + if self._block_changes: + return + _cur_color = QtGui.QColor() + _cur_color.setCmyk( + self.input_cyan.value(), + self.input_magenta.value(), + self.input_yellow.value(), + self.input_black.value() + ) + if ( + _cur_color.red() == self.color.red() + and _cur_color.green() == self.color.green() + and _cur_color.blue() == self.color.blue() + ): + return + + c, m, y, k, _ = self.color.getCmyk() + self._block_changes = True + + self.input_cyan.setValue(c) + self.input_magenta.setValue(m) + self.input_yellow.setValue(y) + self.input_black.setValue(k) + + self._block_changes = False + + +class HEXInputs(QtWidgets.QGroupBox): + hex_regex = re.compile("^#(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$") + value_changed = QtCore.Signal() + + def __init__(self, color, parent=None): + super(HEXInputs, self).__init__("HEX", parent) + self.color = color + + input_field = QtWidgets.QLineEdit() + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(input_field) + + input_field.textChanged.connect(self._on_change) + + self.input_field = input_field + + def _on_change(self): + if self._block_changes: + return + input_value = self.input_field.text() + # TODO what if does not match? + if self.hex_regex.match(input_value): + self.color.setNamedColor(input_value) + self.value_changed.emit() + + def color_changed(self): + input_value = self.input_field.text() + if self.hex_regex.match(input_value): + _cur_color = QtGui.QColor() + _cur_color.setNamedColor(input_value) + if ( + _cur_color.red() == self.color.red() + and _cur_color.green() == self.color.green() + and _cur_color.blue() == self.color.blue() + ): + return + self._block_changes = True + + self.input_field.setText(self.color.name()) + + self._block_changes = False + + +class HSVInputs(QtWidgets.QGroupBox): + value_changed = QtCore.Signal() + + def __init__(self, color, parent=None): + super(HSVInputs, self).__init__("HSV", parent) + + self._block_changes = False + + self.color = color + + input_hue = QtWidgets.QSpinBox(self) + input_sat = QtWidgets.QSpinBox(self) + input_val = QtWidgets.QSpinBox(self) + + input_hue.setMinimum(0) + input_sat.setMinimum(0) + input_val.setMinimum(0) + + input_hue.setMaximum(359) + input_sat.setMaximum(255) + input_val.setMaximum(255) + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(input_hue) + layout.addWidget(input_sat) + layout.addWidget(input_val) + + input_hue.valueChanged.connect(self._on_change) + input_sat.valueChanged.connect(self._on_change) + input_val.valueChanged.connect(self._on_change) + + self.input_hue = input_hue + self.input_sat = input_sat + self.input_val = input_val + + def _on_change(self): + if self._block_changes: + return + self.color.setHsv( + self.input_hue.value(), + self.input_sat.value(), + self.input_val.value() + ) + self.value_changed.emit() + + def color_changed(self): + _cur_color = QtGui.QColor() + _cur_color.setHsv( + self.input_hue.value(), + self.input_sat.value(), + self.input_val.value() + ) + if ( + _cur_color.red() == self.color.red() + and _cur_color.green() == self.color.green() + and _cur_color.blue() == self.color.blue() + ): + return + + self._block_changes = True + h, s, v, _ = self.color.getHsv() + + self.input_hue.setValue(h) + self.input_sat.setValue(s) + self.input_val.setValue(v) + + self._block_changes = False + + +class HSLInputs(QtWidgets.QGroupBox): + value_changed = QtCore.Signal() + + def __init__(self, color, parent=None): + super(HSLInputs, self).__init__("HSL", parent) + + self._block_changes = False + + self.color = color + + input_hue = QtWidgets.QSpinBox(self) + input_sat = QtWidgets.QSpinBox(self) + input_light = QtWidgets.QSpinBox(self) + + input_hue.setMinimum(0) + input_sat.setMinimum(0) + input_light.setMinimum(0) + + input_hue.setMaximum(359) + input_sat.setMaximum(255) + input_light.setMaximum(255) + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(input_hue) + layout.addWidget(input_sat) + layout.addWidget(input_light) + + input_hue.valueChanged.connect(self._on_change) + input_sat.valueChanged.connect(self._on_change) + input_light.valueChanged.connect(self._on_change) + + self.input_hue = input_hue + self.input_sat = input_sat + self.input_light = input_light + + def _on_change(self): + if self._block_changes: + return + self.color.setHsl( + self.input_hue.value(), + self.input_sat.value(), + self.input_light.value() + ) + self.value_changed.emit() + + def color_changed(self): + _cur_color = QtGui.QColor() + _cur_color.setHsl( + self.input_hue.value(), + self.input_sat.value(), + self.input_light.value() + ) + if ( + _cur_color.red() == self.color.red() + and _cur_color.green() == self.color.green() + and _cur_color.blue() == self.color.blue() + ): + return + + self._block_changes = True + h, s, l, _ = self.color.getHsl() + + self.input_hue.setValue(h) + self.input_sat.setValue(s) + self.input_light.setValue(l) + + self._block_changes = False + + +class ColorInputsWidget(QtWidgets.QWidget): + color_changed = QtCore.Signal(QtGui.QColor) + + def __init__(self, parent=None, **kwargs): + super(ColorInputsWidget, self).__init__(parent) + + color = QtGui.QColor() + + input_fields = [] + + if kwargs.get("use_hex", True): + input_fields.append(HEXInputs(color, self)) + + if kwargs.get("use_rgb", True): + input_fields.append(RGBInputs(color, self)) + + if kwargs.get("use_hsl", True): + input_fields.append(HSLInputs(color, self)) + + if kwargs.get("use_hsv", True): + input_fields.append(HSVInputs(color, self)) + + if kwargs.get("use_cmyk", True): + input_fields.append(CMYKInputs(color, self)) + + inputs_widget = QtWidgets.QWidget(self) + inputs_layout = QtWidgets.QVBoxLayout(inputs_widget) + + for input_field in input_fields: + inputs_layout.addWidget(input_field) + input_field.value_changed.connect(self._on_value_change) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(inputs_widget, 0) + spacer = QtWidgets.QWidget(self) + layout.addWidget(spacer, 1) + + self.input_fields = input_fields + + self.color = color + + def set_color(self, color): + if ( + color.red() == self.color.red() + and color.green() == self.color.green() + and color.blue() == self.color.blue() + ): + return + self.color.setRed(color.red()) + self.color.setGreen(color.green()) + self.color.setBlue(color.blue()) + self._on_value_change() + + def _on_value_change(self): + for input_field in self.input_fields: + input_field.color_changed() + self.color_changed.emit(self.color) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py new file mode 100644 index 0000000000..d06af73cbf --- /dev/null +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -0,0 +1,115 @@ +from Qt import QtWidgets, QtCore, QtGui + +from .color_triangle import QtColorTriangle +from .color_view import ColorViewer +from .color_screen_pick import PickScreenColorWidget +from .color_inputs import ( + ColorInputsWidget, + AlphaInputs +) + + +class ColorPickerWidget(QtWidgets.QWidget): + color_changed = QtCore.Signal(QtGui.QColor) + + def __init__(self, color=None, parent=None): + super(ColorPickerWidget, self).__init__(parent) + + # Eye picked widget + pick_widget = PickScreenColorWidget() + + # Color utils + utils_widget = QtWidgets.QWidget(self) + utils_layout = QtWidgets.QVBoxLayout(utils_widget) + + bottom_utils_widget = QtWidgets.QWidget(utils_widget) + + # Color triangle + color_triangle = QtColorTriangle(utils_widget) + + # Color preview + color_view = ColorViewer(bottom_utils_widget) + color_view.setMaximumHeight(50) + + # Color pick button + btn_pick_color = QtWidgets.QPushButton( + "Pick a color", bottom_utils_widget + ) + + # Color inputs widget + color_inputs = ColorInputsWidget(self) + + # Alpha inputs + alpha_input_wrapper_widget = QtWidgets.QWidget(self) + alpha_input_wrapper_layout = QtWidgets.QVBoxLayout( + alpha_input_wrapper_widget + ) + + alpha_inputs = AlphaInputs(alpha_input_wrapper_widget) + alpha_input_wrapper_layout.addWidget(alpha_inputs) + alpha_input_wrapper_layout.addWidget(QtWidgets.QWidget(), 1) + + bottom_utils_layout = QtWidgets.QHBoxLayout(bottom_utils_widget) + bottom_utils_layout.setContentsMargins(0, 0, 0, 0) + bottom_utils_layout.addWidget(color_view, 1) + bottom_utils_layout.addWidget(btn_pick_color, 0) + + utils_layout.addWidget(bottom_utils_widget, 0) + utils_layout.addWidget(color_triangle, 1) + + layout = QtWidgets.QHBoxLayout(self) + layout.addWidget(utils_widget, 1) + layout.addWidget(color_inputs, 0) + layout.addWidget(alpha_input_wrapper_widget, 0) + + color_view.set_color(color_triangle.cur_color) + color_inputs.set_color(color_triangle.cur_color) + + color_triangle.color_changed.connect(self.triangle_color_changed) + pick_widget.color_selected.connect(self.on_color_change) + color_inputs.color_changed.connect(self.on_color_change) + alpha_inputs.alpha_changed.connect(self.alpha_changed) + btn_pick_color.released.connect(self.pick_color) + + self.pick_widget = pick_widget + self.utils_widget = utils_widget + self.bottom_utils_widget = bottom_utils_widget + + self.color_triangle = color_triangle + self.color_view = color_view + self.btn_pick_color = btn_pick_color + self.color_inputs = color_inputs + self.alpha_inputs = alpha_inputs + + if color: + self.set_color(color) + self.alpha_changed(color.alpha()) + + def showEvent(self, event): + super(ColorPickerWidget, self).showEvent(event) + triangle_width = int(( + self.utils_widget.height() - self.bottom_utils_widget.height() + ) / 5 * 4) + self.color_triangle.setMinimumWidth(triangle_width) + + def color(self): + return self.color_view.color() + + def set_color(self, color): + self.alpha_inputs.set_alpha(color.alpha()) + self.on_color_change(color) + + def pick_color(self): + self.pick_widget.pick_color() + + def triangle_color_changed(self, color): + self.color_view.set_color(color) + self.color_inputs.set_color(color) + + def on_color_change(self, color): + self.color_view.set_color(color) + self.color_triangle.set_color(color) + self.color_inputs.set_color(color) + + def alpha_changed(self, alpha): + self.color_view.set_alpha(alpha) diff --git a/openpype/widgets/color_widgets/color_screen_pick.py b/openpype/widgets/color_widgets/color_screen_pick.py new file mode 100644 index 0000000000..87f50745eb --- /dev/null +++ b/openpype/widgets/color_widgets/color_screen_pick.py @@ -0,0 +1,248 @@ +import Qt +from Qt import QtWidgets, QtCore, QtGui + + +class PickScreenColorWidget(QtWidgets.QWidget): + color_selected = QtCore.Signal(QtGui.QColor) + + def __init__(self, parent=None): + super(PickScreenColorWidget, self).__init__(parent) + self.labels = [] + self.magnification = 2 + + self._min_magnification = 1 + self._max_magnification = 10 + + def add_magnification_delta(self, delta): + _delta = abs(delta / 1000) + if delta > 0: + self.magnification += _delta + else: + self.magnification -= _delta + + if self.magnification > self._max_magnification: + self.magnification = self._max_magnification + elif self.magnification < self._min_magnification: + self.magnification = self._min_magnification + + def pick_color(self): + if self.labels: + if self.labels[0].isVisible(): + return + self.labels = [] + + for screen in QtWidgets.QApplication.screens(): + label = PickLabel(self) + label.pick_color(screen) + label.color_selected.connect(self.on_color_select) + label.close_session.connect(self.end_pick_session) + self.labels.append(label) + + def end_pick_session(self): + for label in self.labels: + label.close() + self.labels = [] + + def on_color_select(self, color): + self.color_selected.emit(color) + self.end_pick_session() + + +class PickLabel(QtWidgets.QLabel): + color_selected = QtCore.Signal(QtGui.QColor) + close_session = QtCore.Signal() + + def __init__(self, pick_widget): + super(PickLabel, self).__init__() + self.setMouseTracking(True) + + self.pick_widget = pick_widget + + self.radius_pen = QtGui.QPen(QtGui.QColor(27, 27, 27), 2) + self.text_pen = QtGui.QPen(QtGui.QColor(127, 127, 127), 4) + self.text_bg = QtGui.QBrush(QtGui.QColor(27, 27, 27)) + self._mouse_over = False + + self.radius = 100 + self.radius_ratio = 11 + + @property + def magnification(self): + return self.pick_widget.magnification + + def pick_color(self, screen_obj): + self.show() + self.windowHandle().setScreen(screen_obj) + geo = screen_obj.geometry() + args = ( + QtWidgets.QApplication.desktop().winId(), + geo.x(), geo.y(), geo.width(), geo.height() + ) + if Qt.__binding__ in ("PyQt4", "PySide"): + pix = QtGui.QPixmap.grabWindow(*args) + else: + pix = screen_obj.grabWindow(*args) + + if pix.width() > pix.height(): + size = pix.height() + else: + size = pix.width() + + self.radius = int(size / self.radius_ratio) + + self.setPixmap(pix) + self.showFullScreen() + + def wheelEvent(self, event): + y_delta = event.angleDelta().y() + self.pick_widget.add_magnification_delta(y_delta) + self.update() + + def enterEvent(self, event): + self._mouse_over = True + super().enterEvent(event) + + def leaveEvent(self, event): + self._mouse_over = False + super().leaveEvent(event) + self.update() + + def mouseMoveEvent(self, event): + self.update() + + def paintEvent(self, event): + super().paintEvent(event) + if not self._mouse_over: + return + + mouse_pos_to_widet = self.mapFromGlobal(QtGui.QCursor.pos()) + + magnified_half_size = self.radius / self.magnification + magnified_size = magnified_half_size * 2 + + zoom_x_1 = mouse_pos_to_widet.x() - magnified_half_size + zoom_x_2 = mouse_pos_to_widet.x() + magnified_half_size + zoom_y_1 = mouse_pos_to_widet.y() - magnified_half_size + zoom_y_2 = mouse_pos_to_widet.y() + magnified_half_size + pix_width = magnified_size + pix_height = magnified_size + draw_pos_x = 0 + draw_pos_y = 0 + if zoom_x_1 < 0: + draw_pos_x = abs(zoom_x_1) + pix_width -= draw_pos_x + zoom_x_1 = 1 + elif zoom_x_2 > self.pixmap().width(): + pix_width -= zoom_x_2 - self.pixmap().width() + + if zoom_y_1 < 0: + draw_pos_y = abs(zoom_y_1) + pix_height -= draw_pos_y + zoom_y_1 = 1 + elif zoom_y_2 > self.pixmap().height(): + pix_height -= zoom_y_2 - self.pixmap().height() + + new_pix = QtGui.QPixmap(magnified_size, magnified_size) + new_pix.fill(QtCore.Qt.transparent) + new_pix_painter = QtGui.QPainter(new_pix) + new_pix_painter.drawPixmap( + QtCore.QRect(draw_pos_x, draw_pos_y, pix_width, pix_height), + self.pixmap().copy(zoom_x_1, zoom_y_1, pix_width, pix_height) + ) + new_pix_painter.end() + + painter = QtGui.QPainter(self) + + ellipse_rect = QtCore.QRect( + mouse_pos_to_widet.x() - self.radius, + mouse_pos_to_widet.y() - self.radius, + self.radius * 2, + self.radius * 2 + ) + ellipse_rect_f = QtCore.QRectF(ellipse_rect) + path = QtGui.QPainterPath() + path.addEllipse(ellipse_rect_f) + painter.setClipPath(path) + + new_pix_rect = QtCore.QRect( + mouse_pos_to_widet.x() - self.radius + 1, + mouse_pos_to_widet.y() - self.radius + 1, + new_pix.width() * self.magnification, + new_pix.height() * self.magnification + ) + + painter.drawPixmap(new_pix_rect, new_pix) + + painter.setClipping(False) + + painter.setRenderHint(QtGui.QPainter.Antialiasing) + + painter.setPen(self.radius_pen) + painter.drawEllipse(ellipse_rect_f) + + image = self.pixmap().toImage() + if image.valid(mouse_pos_to_widet): + color = QtGui.QColor(image.pixel(mouse_pos_to_widet)) + else: + color = QtGui.QColor() + + color_text = "Red: {} - Green: {} - Blue: {}".format( + color.red(), color.green(), color.blue() + ) + font = painter.font() + font.setPointSize(self.radius / 10) + painter.setFont(font) + + text_rect_height = int(painter.fontMetrics().height() + 10) + text_rect = QtCore.QRect( + ellipse_rect.x(), + ellipse_rect.bottom(), + ellipse_rect.width(), + text_rect_height + ) + if text_rect.bottom() > self.pixmap().height(): + text_rect.moveBottomLeft(ellipse_rect.topLeft()) + + rect_radius = text_rect_height / 2 + path = QtGui.QPainterPath() + path.addRoundedRect( + QtCore.QRectF(text_rect), + rect_radius, + rect_radius + ) + painter.fillPath(path, self.text_bg) + + painter.setPen(self.text_pen) + painter.drawText( + text_rect, + QtCore.Qt.AlignLeft | QtCore.Qt.AlignCenter, + color_text + ) + + color_rect_x = ellipse_rect.x() - text_rect_height + if color_rect_x < 0: + color_rect_x += (text_rect_height + ellipse_rect.width()) + + color_rect = QtCore.QRect( + color_rect_x, + ellipse_rect.y(), + text_rect_height, + ellipse_rect.height() + ) + path = QtGui.QPainterPath() + path.addRoundedRect( + QtCore.QRectF(color_rect), + rect_radius, + rect_radius + ) + painter.fillPath(path, color) + painter.drawRoundedRect(color_rect, rect_radius, rect_radius) + painter.end() + + def mouseReleaseEvent(self, event): + color = QtGui.QColor(self.pixmap().toImage().pixel(event.pos())) + self.color_selected.emit(color) + + def keyPressEvent(self, event): + if event.key() == QtCore.Qt.Key_Escape: + self.close_session.emit() diff --git a/openpype/widgets/color_widgets/color_triangle.py b/openpype/widgets/color_widgets/color_triangle.py new file mode 100644 index 0000000000..d4db175d84 --- /dev/null +++ b/openpype/widgets/color_widgets/color_triangle.py @@ -0,0 +1,1431 @@ +from enum import Enum +from math import floor, sqrt, sin, cos, acos, pi as PI +from Qt import QtWidgets, QtCore, QtGui + +TWOPI = PI * 2 + + +class TriangleState(Enum): + IdleState = object() + SelectingHueState = object() + SelectingSatValueState = object() + + +class DoubleColor: + def __init__(self, r, g=None, b=None): + if g is None: + g = r.g + b = r.b + r = r.r + self.r = float(r) + self.g = float(g) + self.b = float(b) + + +class Vertex: + def __init__(self, color, point): + # Convert GlobalColor to QColor as globals don't have red, green, blue + if isinstance(color, QtCore.Qt.GlobalColor): + color = QtGui.QColor(color) + + # Convert QColor to DoubleColor + if isinstance(color, QtGui.QColor): + color = DoubleColor(color.red(), color.green(), color.blue()) + + self.color = color + self.point = point + + +class QtColorTriangle(QtWidgets.QWidget): + """The QtColorTriangle class provides a triangular color selection widget. + + This widget uses the HSV color model, and is therefore useful for + selecting colors by eye. + + The triangle in the center of the widget is used for selecting + saturation and value, and the surrounding circle is used for + selecting hue. + + Use set_color() and color() to set and get the current color. + """ + color_changed = QtCore.Signal(QtGui.QColor) + + # Thick of color wheel ratio where 1 is fully filled circle + inner_radius_ratio = 5.0 + # Ratio where hue selector on wheel is relative to `inner_radius_ratio` + # - middle of the wheel is twice `inner_radius_ratio` + selector_radius_ratio = inner_radius_ratio * 2 + # Size ratio of selectors on wheel and in triangle + ellipse_size_ratio = 10.0 + # Ration of selectors thickness + ellipse_thick_ratio = 50.0 + # Hue offset on color wheel (0 - 359) + # - red on top if set to "0" + hue_offset = 90 + + def __init__(self, parent=None): + super(QtColorTriangle, self).__init__(parent) + self.setSizePolicy( + QtWidgets.QSizePolicy.Minimum, + QtWidgets.QSizePolicy.Minimum + ) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + self.angle_a = float() + self.angle_b = float() + self.angle_c = float() + + self.bg_image = QtGui.QImage( + self.sizeHint(), QtGui.QImage.Format_RGB32 + ) + self.cur_color = QtGui.QColor() + self.point_a = QtCore.QPointF() + self.point_b = QtCore.QPointF() + self.point_c = QtCore.QPointF() + self.point_d = QtCore.QPointF() + + self.cur_hue = int() + + self.pen_width = int() + self.ellipse_size = int() + self.outer_radius = int() + self.selector_pos = QtCore.QPointF() + + self.sel_mode = TriangleState.IdleState + + self._triangle_outline_pen = QtGui.QPen( + QtGui.QColor(40, 40, 40, 128), + 2 + ) + # Prepare hue numbers for color circle + _hue_circle_range = [] + for idx in range(11): + # Some Qt versions may require: + # hue = int(idx * 360.0) + percent_idx = idx * 0.1 + hue = int(360.0 - (percent_idx * 360.0)) + _hue_circle_range.append((percent_idx, hue)) + self._hue_circle_range = tuple(_hue_circle_range) + + color = QtGui.QColor() + color.setHsv(0, 255, 255) + self.set_color(color) + + def set_color(self, col): + if ( + col.red() == self.cur_color.red() + and col.green() == self.cur_color.green() + and col.blue() == self.cur_color.blue() + ): + return + + self.cur_color = col + + hue, *_ = self.cur_color.getHsv() + + # Never use an invalid hue to display colors + if hue != -1: + self.cur_hue = hue + + angle_with_offset = (360 - self.cur_hue - self.hue_offset) % 360 + self.angle_a = (angle_with_offset * TWOPI) / 360.0 + self.angle_a += PI / 2.0 + if self.angle_a > TWOPI: + self.angle_a -= TWOPI + + self.angle_b = self.angle_a + TWOPI / 3 + self.angle_c = self.angle_b + TWOPI / 3 + + if self.angle_b > TWOPI: + self.angle_b -= TWOPI + if self.angle_c > TWOPI: + self.angle_c -= TWOPI + + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + inner_radius = ( + self.outer_radius + - (self.outer_radius / self.inner_radius_ratio) + ) + selector_radius = ( + self.outer_radius + - (self.outer_radius / self.selector_radius_ratio) + ) + self.point_a = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + self.point_b = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + self.point_c = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + self.point_d = QtCore.QPointF( + cx + (cos(self.angle_a) * selector_radius), + cy - (sin(self.angle_a) * selector_radius) + ) + + self.selector_pos = self._point_from_color(self.cur_color) + self.update() + + self.color_changed.emit(self.cur_color) + + def heightForWidth(self, width): + return width + + def polish(self): + size_w = self.contentsRect().width() + size_h = self.contentsRect().height() + if size_w < size_h: + size = size_w + else: + size = size_h + + self.outer_radius = (size - 1) / 2 + + self.pen_width = int( + floor(self.outer_radius / self.ellipse_thick_ratio) + ) + self.ellipse_size = int( + floor(self.outer_radius / self.ellipse_size_ratio) + ) + + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + + inner_radius = ( + self.outer_radius + - (self.outer_radius / self.inner_radius_ratio) + ) + selector_radius = ( + self.outer_radius + - (self.outer_radius / self.selector_radius_ratio) + ) + self.point_a = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + self.point_b = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + self.point_c = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + self.point_d = QtCore.QPointF( + cx + (cos(self.angle_a) * selector_radius), + cy - (sin(self.angle_a) * selector_radius) + ) + + self.selector_pos = self._point_from_color(self.cur_color) + + self.update() + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + if event.rect().intersects(self.contentsRect()): + event_region = event.region() + if hasattr(event_region, "intersect"): + clip_region = event_region.intersect(self.contentsRect()) + else: + clip_region = event_region.intersected( + self.contentsRect() + ) + painter.setClipRegion(clip_region) + + self.paint_bg() + + # Blit the static generated background with the hue gradient onto + # the double buffer. + buf = QtGui.QImage(self.bg_image.copy()) + + # Draw the trigon + # Find the color with only the hue, and max value and saturation + hue_color = QtGui.QColor() + hue_color.setHsv(self.cur_hue, 255, 255) + + # Draw the triangle + self.drawTrigon( + buf, self.point_a, self.point_b, self.point_c, hue_color + ) + + # Slow step: convert the image to a pixmap + pix = QtGui.QPixmap.fromImage(buf) + pix_painter = QtGui.QPainter(pix) + pix_painter.setRenderHint(QtGui.QPainter.Antialiasing) + + # Draw an outline of the triangle + pix_painter.setPen(self._triangle_outline_pen) + pix_painter.drawLine(self.point_a, self.point_b) + pix_painter.drawLine(self.point_b, self.point_c) + pix_painter.drawLine(self.point_c, self.point_a) + + # Draw the color wheel selector + pix_painter.setPen(QtGui.QPen(QtCore.Qt.white, self.pen_width)) + pix_painter.drawEllipse( + int(self.point_d.x() - self.ellipse_size / 2.0), + int(self.point_d.y() - self.ellipse_size / 2.0), + self.ellipse_size, self.ellipse_size + ) + + # Draw the triangle selector + pix_painter.setBrush(self.cur_color) + pix_painter.drawEllipse( + QtCore.QRectF( + self.selector_pos.x() - self.ellipse_size / 2.0, + self.selector_pos.y() - self.ellipse_size / 2.0, + self.ellipse_size + 0.5, + self.ellipse_size + 0.5 + ) + ) + + pix_painter.end() + # Blit + painter.drawPixmap(self.contentsRect().topLeft(), pix) + painter.end() + + def mouseMoveEvent(self, event): + if (event.buttons() & QtCore.Qt.LeftButton) == 0: + return + + depos = QtCore.QPointF( + event.pos().x(), + event.pos().y() + ) + new_color = False + + if self.sel_mode is TriangleState.SelectingHueState: + self.angle_a = self._angle_at(depos, self.contentsRect()) + self.angle_b = self.angle_a + (TWOPI / 3.0) + self.angle_c = self.angle_b + (TWOPI / 3.0) + if self.angle_b > TWOPI: + self.angle_b -= TWOPI + if self.angle_c > TWOPI: + self.angle_c -= TWOPI + + am = self.angle_a - (PI / 2) + if am < 0: + am += TWOPI + self.cur_hue = ( + 360 - int((am * 360.0) / TWOPI) - self.hue_offset + ) % 360 + hue, sat, val, _ = self.cur_color.getHsv() + + if self.cur_hue != hue: + new_color = True + self.cur_color.setHsv(self.cur_hue, sat, val) + + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + inner_radius = ( + self.outer_radius + - (self.outer_radius / self.inner_radius_ratio) + ) + selector_radius = ( + self.outer_radius + - (self.outer_radius / self.selector_radius_ratio) + ) + self.point_a = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + self.point_b = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + self.point_c = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + self.point_d = QtCore.QPointF( + cx + (cos(self.angle_a) * selector_radius), + cy - (sin(self.angle_a) * selector_radius) + ) + + self.selector_pos = self._point_from_color(self.cur_color) + else: + aa = Vertex(QtCore.Qt.transparent, self.point_a) + bb = Vertex(QtCore.Qt.transparent, self.point_b) + cc = Vertex(QtCore.Qt.transparent, self.point_c) + + self.selector_pos = self._move_point_to_triangle( + depos.x(), depos.y(), aa, bb, cc + ) + col = self._color_from_point(self.selector_pos) + if col != self.cur_color: + # Ensure that hue does not change when selecting + # saturation and value. + _, sat, val, _ = col.getHsv() + self.cur_color.setHsv(self.cur_hue, sat, val) + new_color = True + + if new_color: + self.color_changed.emit(self.cur_color) + + self.update() + + def mousePressEvent(self, event): + # Only respond to the left mouse button. + if event.button() != QtCore.Qt.LeftButton: + return + + depos = QtCore.QPointF( + event.pos().x(), + event.pos().y() + ) + rad = self._radius_at(depos, self.contentsRect()) + new_color = False + + # As in mouseMoveEvent, either find the a, b, c angles or the + # radian position of the selector, then order an update. + inner_radius = ( + self.outer_radius - (self.outer_radius / self.inner_radius_ratio) + ) + if rad > inner_radius: + self.sel_mode = TriangleState.SelectingHueState + + self.angle_a = self._angle_at(depos, self.contentsRect()) + self.angle_b = self.angle_a + TWOPI / 3.0 + self.angle_c = self.angle_b + TWOPI / 3.0 + if self.angle_b > TWOPI: + self.angle_b -= TWOPI + if self.angle_c > TWOPI: + self.angle_c -= TWOPI + + am = self.angle_a - PI / 2 + if am < 0: + am += TWOPI + + self.cur_hue = ( + 360 - int((am * 360.0) / TWOPI) - self.hue_offset + ) % 360 + hue, sat, val, _ = self.cur_color.getHsv() + + if hue != self.cur_hue: + new_color = True + self.cur_color.setHsv(self.cur_hue, sat, val) + + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + + self.point_a = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + self.point_b = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + self.point_c = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + + selector_radius = ( + self.outer_radius + - (self.outer_radius / self.selector_radius_ratio) + ) + self.point_d = QtCore.QPointF( + cx + (cos(self.angle_a) * selector_radius), + cy - (sin(self.angle_a) * selector_radius) + ) + + self.selector_pos = self._point_from_color(self.cur_color) + self.color_changed.emit(self.cur_color) + else: + self.sel_mode = TriangleState.SelectingSatValueState + + aa = Vertex(QtCore.Qt.transparent, self.point_a) + bb = Vertex(QtCore.Qt.transparent, self.point_b) + cc = Vertex(QtCore.Qt.transparent, self.point_c) + + self.selector_pos = self._move_point_to_triangle( + depos.x(), depos.y(), aa, bb, cc + ) + col = self._color_from_point(self.selector_pos) + if col != self.cur_color: + self.cur_color = col + new_color = True + + if new_color: + self.color_changed.emit(self.cur_color) + + self.update() + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + self.sel_mode = TriangleState.IdleState + + def keyPressEvent(self, event): + key = event.key() + if key == QtCore.Qt.Key_Left: + self.cur_hue -= 1 + if self.cur_hue < 0: + self.cur_hue += 360 + _, sat, val, _ = self.cur_color.getHsv() + + tmp = QtGui.QColor() + tmp.setHsv(self.cur_hue, sat, val) + self.set_color(tmp) + + elif key == QtCore.Qt.Key_Right: + self.cur_hue += 1 + if (self.cur_hue > 359): + self.cur_hue -= 360 + _, sat, val, _ = self.cur_color.getHsv() + tmp = QtGui.QColor() + tmp.setHsv(self.cur_hue, sat, val) + self.set_color(tmp) + + elif key == QtCore.Qt.Key_Up: + _, sat, val, _ = self.cur_color.getHsv() + if event.modifiers() & QtCore.Qt.ShiftModifier: + if sat > 5: + sat -= 5 + else: + sat = 0 + else: + if val > 5: + val -= 5 + else: + val = 0 + + tmp = QtGui.QColor() + tmp.setHsv(self.cur_hue, sat, val) + self.set_color(tmp) + + elif key == QtCore.Qt.Key_Down: + _, sat, val, _ = self.cur_color.getHsv() + if event.modifiers() & QtCore.Qt.ShiftModifier: + if sat < 250: + sat += 5 + else: + sat = 255 + else: + if val < 250: + val += 5 + else: + val = 255 + + tmp = QtGui.QColor() + tmp.setHsv(self.cur_hue, sat, val) + self.set_color(tmp) + + def resizeEvent(self, _event): + size_w = self.contentsRect().width() + size_h = self.contentsRect().height() + if size_w < size_h: + size = size_w + else: + size = size_h + + self.outer_radius = (size - 1) / 2 + + self.pen_width = int( + floor(self.outer_radius / self.ellipse_thick_ratio) + ) + self.ellipse_size = int( + floor(self.outer_radius / self.ellipse_size_ratio) + ) + + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + inner_radius = ( + self.outer_radius + - (self.outer_radius / self.inner_radius_ratio) + ) + selector_radius = ( + self.outer_radius + - (self.outer_radius / self.selector_radius_ratio) + ) + self.point_a = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + self.point_b = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + self.point_c = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + self.point_d = QtCore.QPointF( + cx + (cos(self.angle_a) * selector_radius), + cy - (sin(self.angle_a) * selector_radius) + ) + + # Find the current position of the selector + self.selector_pos = self._point_from_color(self.cur_color) + + self.update() + + def drawTrigon(self, buf, pa, pb, pc, color): + # Create three Vertex objects. A Vertex contains a double-point + # coordinate and a color. + # pa is the tip of the arrow + # pb is the black corner + # pc is the white corner + p1 = Vertex(color, pa) + p2 = Vertex(QtCore.Qt.black, pb) + p3 = Vertex(QtCore.Qt.white, pc) + + # Sort. Make p1 above p2, which is above p3 (using y coordinate). + # Bubble sorting is fastest here. + if p1.point.y() > p2.point.y(): + p1, p2 = p2, p1 + if p1.point.y() > p3.point.y(): + p1, p3 = p3, p1 + if p2.point.y() > p3.point.y(): + p2, p3 = p3, p2 + + # All the three y deltas are >= 0 + p1p2ydist = float(p2.point.y() - p1.point.y()) + p1p3ydist = float(p3.point.y() - p1.point.y()) + p2p3ydist = float(p3.point.y() - p2.point.y()) + p1p2xdist = float(p2.point.x() - p1.point.x()) + p1p3xdist = float(p3.point.x() - p1.point.x()) + p2p3xdist = float(p3.point.x() - p2.point.x()) + + # The first x delta decides wether we have a lefty or a righty + # trigon. + lefty = p1p2xdist < 0 + + # Left and right colors and X values. The key in this map is the + # y values. Our goal is to fill these structures with all the + # information needed to do a single pass top-to-bottom, + # left-to-right drawing of the trigon. + leftColors = {} + rightColors = {} + leftX = {} + rightX = {} + + # Scan longy - find all left and right colors and X-values for + # the tallest edge (p1-p3). + # Initialize with known values + x = p1.point.x() + source = p1.color + dest = p3.color + r = source.r + g = source.g + b = source.b + y1 = int(floor(p1.point.y())) + y2 = int(floor(p3.point.y())) + + # Find slopes (notice that if the y dists are 0, we don't care + # about the slopes) + xdelta = 0.0 + rdelta = 0.0 + gdelta = 0.0 + bdelta = 0.0 + if p1p3ydist != 0.0: + xdelta = p1p3xdist / p1p3ydist + rdelta = (dest.r - r) / p1p3ydist + gdelta = (dest.g - g) / p1p3ydist + bdelta = (dest.b - b) / p1p3ydist + + # Calculate gradients using linear approximation + for y in range(y1, y2): + if lefty: + rightColors[y] = DoubleColor(r, g, b) + rightX[y] = x + else: + leftColors[y] = DoubleColor(r, g, b) + leftX[y] = x + + r += rdelta + g += gdelta + b += bdelta + x += xdelta + + # Scan top shorty - find all left and right colors and x-values + # for the topmost of the two not-tallest short edges. + x = p1.point.x() + source = p1.color + dest = p2.color + r = source.r + g = source.g + b = source.b + y1 = int(floor(p1.point.y())) + y2 = int(floor(p2.point.y())) + + # Find slopes (notice that if the y dists are 0, we don't care + # about the slopes) + xdelta = 0.0 + rdelta = 0.0 + gdelta = 0.0 + bdelta = 0.0 + if p1p2ydist != 0.0: + xdelta = p1p2xdist / p1p2ydist + rdelta = (dest.r - r) / p1p2ydist + gdelta = (dest.g - g) / p1p2ydist + bdelta = (dest.b - b) / p1p2ydist + + # Calculate gradients using linear approximation + for y in range(y1, y2): + if lefty: + leftColors[y] = DoubleColor(r, g, b) + leftX[y] = x + else: + rightColors[y] = DoubleColor(r, g, b) + rightX[y] = x + + r += rdelta + g += gdelta + b += bdelta + x += xdelta + + # Scan bottom shorty - find all left and right colors and + # x-values for the bottommost of the two not-tallest short edges. + x = p2.point.x() + source = p2.color + dest = p3.color + r = source.r + g = source.g + b = source.b + y1 = int(floor(p2.point.y())) + y2 = int(floor(p3.point.y())) + + # Find slopes (notice that if the y dists are 0, we don't care + # about the slopes) + xdelta = 0.0 + rdelta = 0.0 + gdelta = 0.0 + bdelta = 0.0 + if p2p3ydist != 0.0: + xdelta = p2p3xdist / p2p3ydist + rdelta = (dest.r - r) / p2p3ydist + gdelta = (dest.g - g) / p2p3ydist + bdelta = (dest.b - b) / p2p3ydist + + # Calculate gradients using linear approximation + for y in range(y1, y2): + if lefty: + leftColors[y] = DoubleColor(r, g, b) + leftX[y] = x + else: + rightColors[y] = DoubleColor(r, g, b) + rightX[y] = x + + r += rdelta + g += gdelta + b += bdelta + x += xdelta + + # Inner loop. For each y in the left map of x-values, draw one + # line from left to right. + p3yfloor = int(floor(p3.point.y())) + p1yfloor = int(floor(p1.point.y())) + for y in range(p1yfloor, p3yfloor): + lx = leftX[y] + rx = rightX[y] + + lxi = int(floor(lx)) + rxi = int(floor(rx)) + rc = rightColors[y] + lc = leftColors[y] + + # if the xdist is 0, don't draw anything. + xdist = rx - lx + if xdist != 0.0: + r = lc.r + g = lc.g + b = lc.b + rdelta = (rc.r - r) / xdist + gdelta = (rc.g - g) / xdist + bdelta = (rc.b - b) / xdist + + # Inner loop 2. Draws the line from left to right. + for x in range(lxi, rxi + 1): + buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) + r += rdelta + g += gdelta + b += bdelta + + def _radius_at(self, pos, rect): + mousexdist = pos.x() - float(rect.center().x()) + mouseydist = pos.y() - float(rect.center().y()) + return sqrt(mousexdist ** 2 + mouseydist ** 2) + + def _angle_at(self, pos, rect): + mousexdist = pos.x() - float(rect.center().x()) + mouseydist = pos.y() - float(rect.center().y()) + mouserad = sqrt(mousexdist ** 2 + mouseydist ** 2) + if mouserad == 0.0: + return 0.0 + + angle = acos(mousexdist / mouserad) + if mouseydist >= 0: + angle = TWOPI - angle + + return angle + + def _point_from_color(self, col): + # Simplifications for the corner cases. + if col == QtCore.Qt.black: + return self.point_b + elif col == QtCore.Qt.white: + return self.point_c + + # Find the x and y slopes + ab_deltax = self.point_b.x() - self.point_a.x() + ab_deltay = self.point_b.y() - self.point_a.y() + bc_deltax = self.point_c.x() - self.point_b.x() + bc_deltay = self.point_c.y() - self.point_b.y() + ac_deltax = self.point_c.x() - self.point_a.x() + ac_deltay = self.point_c.y() - self.point_a.y() + + # Extract the h,s,v values of col. + _, sat, val, _ = col.getHsv() + + # Find the line that passes through the triangle where the value + # is equal to our color's value. + p1 = self.point_a.x() + (ab_deltax * float(255 - val)) / 255.0 + q1 = self.point_a.y() + (ab_deltay * float(255 - val)) / 255.0 + p2 = self.point_b.x() + (bc_deltax * float(val)) / 255.0 + q2 = self.point_b.y() + (bc_deltay * float(val)) / 255.0 + + # Find the line that passes through the triangle where the + # saturation is equal to our color's value. + p3 = self.point_a.x() + (ac_deltax * float(255 - sat)) / 255.0 + q3 = self.point_a.y() + (ac_deltay * float(255 - sat)) / 255.0 + p4 = self.point_b.x() + q4 = self.point_b.y() + + # Find the intersection between these lines. + if p1 != p2: + a = (q2 - q1) / (p2 - p1) + c = (q4 - q3) / (p4 - p3) + b = q1 - a * p1 + d = q3 - c * p3 + + x = (d - b) / (a - c) + y = a * x + b + else: + x = p1 + p4_p3 = p4 - p3 + if p4_p3 == 0: + y = 0 + else: + y = q3 + (x - p3) * (q4 - q3) / p4_p3 + + return QtCore.QPointF(x, y) + + def _color_from_point(self, p): + # Find the outer radius of the hue gradient. + size_w = self.contentsRect().width() + size_h = self.contentsRect().height() + if size_w < size_h: + size = size_w + else: + size = size_h + outer_radius = (size - 1) / 2 + + # Find the center coordinates + cx = float(self.contentsRect().center().x()) + cy = float(self.contentsRect().center().y()) + + # Find the a, b and c from their angles, the center of the rect + # and the radius of the hue gradient donut. + inner_radius = outer_radius - (outer_radius / self.inner_radius_ratio) + pa = QtCore.QPointF( + cx + (cos(self.angle_a) * inner_radius), + cy - (sin(self.angle_a) * inner_radius) + ) + pb = QtCore.QPointF( + cx + (cos(self.angle_b) * inner_radius), + cy - (sin(self.angle_b) * inner_radius) + ) + pc = QtCore.QPointF( + cx + (cos(self.angle_c) * inner_radius), + cy - (sin(self.angle_c) * inner_radius) + ) + + # Find the hue value from the angle of the 'a' point. + angle = self.angle_a - PI / 2.0 + if angle < 0: + angle += TWOPI + hue = ( + 360 + - int(floor((360.0 * angle) / TWOPI)) + - self.hue_offset + ) % 360 + + # Create the color of the 'a' corner point. We know that b is + # black and c is white. + color = QtGui.QColor() + color.setHsv(hue, 255, 255) + + # See also drawTrigon(), which basically does exactly the same to + # determine all colors in the trigon. + p1 = Vertex(color, pa) + p2 = Vertex(QtCore.Qt.black, pb) + p3 = Vertex(QtCore.Qt.white, pc) + + # Make sure p1 is above p2, which is above p3. + if p1.point.y() > p2.point.y(): + p1, p2 = p2, p1 + if p1.point.y() > p3.point.y(): + p1, p3 = p3, p1 + if p2.point.y() > p3.point.y(): + p2, p3 = p3, p2 + + # Find the slopes of all edges in the trigon. All the three y + # deltas here are positive because of the above sorting. + p1p2ydist = p2.point.y() - p1.point.y() + p1p3ydist = p3.point.y() - p1.point.y() + p2p3ydist = p3.point.y() - p2.point.y() + p1p2xdist = p2.point.x() - p1.point.x() + p1p3xdist = p3.point.x() - p1.point.x() + p2p3xdist = p3.point.x() - p2.point.x() + + # The first x delta decides wether we have a lefty or a righty + # trigon. A lefty trigon has its tallest edge on the right hand + # side of the trigon. The righty trigon has it on its left side. + # This property determines wether the left or the right set of x + # coordinates will be continuous. + lefty = p1p2xdist < 0 + + # Find whether the selector's y is in the first or second shorty, + # counting from the top and downwards. This is used to find the + # color at the selector point. + firstshorty = (p.y() >= p1.point.y() and p.y() < p2.point.y()) + + # From the y value of the selector's position, find the left and + # right x values. + if lefty: + if firstshorty: + if (floor(p1p2ydist) != 0.0): + leftx = ( + p1.point.x() + + ((p1p2xdist * (p.y() - p1.point.y())) / p1p2ydist) + ) + else: + leftx = min(p1.point.x(), p2.point.x()) + + else: + if (floor(p2p3ydist) != 0.0): + leftx = ( + p2.point.x() + + (p2p3xdist * (p.y() - p2.point.y())) / p2p3ydist + ) + else: + leftx = min(p2.point.x(), p3.point.x()) + + rightx = ( + p1.point.x() + + ((p1p3xdist * (p.y() - p1.point.y())) / p1p3ydist) + ) + else: + leftx = ( + p1.point.x() + + ((p1p3xdist * (p.y() - p1.point.y())) / p1p3ydist) + ) + if firstshorty: + if floor(p1p2ydist) != 0.0: + rightx = ( + p1.point.x() + + ((p1p2xdist * (p.y() - p1.point.y())) / p1p2ydist) + ) + else: + rightx = max(p1.point.x(), p2.point.x()) + + else: + if floor(p2p3ydist) != 0.0: + rightx = ( + p2.point.x() + + ((p2p3xdist * (p.y() - p2.point.y())) / p2p3ydist) + ) + else: + rightx = max(p2.point.x(), p3.point.x()) + + # Find the r,g,b values of the points on the trigon's edges that + # are to the left and right of the selector. + if firstshorty: + if floor(p1p2ydist) != 0.0: + p_p1_ratio = (p.y() - p1.point.y()) / p1p2ydist + p2_p_ratio = (p2.point.y() - p.y()) / p1p2ydist + rshort = (p2.color.r * p_p1_ratio) + (p1.color.r * p2_p_ratio) + gshort = (p2.color.g * p_p1_ratio) + (p1.color.g * p2_p_ratio) + bshort = (p2.color.b * p_p1_ratio) + (p1.color.b * p2_p_ratio) + elif lefty: + if p1.point.x() <= p2.point.x(): + rshort = p1.color.r + gshort = p1.color.g + bshort = p1.color.b + else: + rshort = p2.color.r + gshort = p2.color.g + bshort = p2.color.b + + else: + if p1.point.x() > p2.point.x(): + rshort = p1.color.r + gshort = p1.color.g + bshort = p1.color.b + else: + rshort = p2.color.r + gshort = p2.color.g + bshort = p2.color.b + + else: + if floor(p2p3ydist) != 0.0: + p_p2_ratio = (p.y() - p2.point.y()) / p2p3ydist + p3_p_ratio = (p3.point.y() - p.y()) / p2p3ydist + rshort = (p3.color.r * p_p2_ratio) + (p2.color.r * p3_p_ratio) + gshort = (p3.color.g * p_p2_ratio) + (p2.color.g * p3_p_ratio) + bshort = (p3.color.b * p_p2_ratio) + (p2.color.b * p3_p_ratio) + elif lefty: + if p2.point.x() <= p3.point.x(): + rshort = p2.color.r + gshort = p2.color.g + bshort = p2.color.b + else: + rshort = p3.color.r + gshort = p3.color.g + bshort = p3.color.b + + else: + if p2.point.x() > p3.point.x(): + rshort = p2.color.r + gshort = p2.color.g + bshort = p2.color.b + else: + rshort = p3.color.r + gshort = p3.color.g + bshort = p3.color.b + + # p1p3ydist is never 0 + p_p1_ratio = (p.y() - p1.point.y()) / p1p3ydist + p3_p_ratio = (p3.point.y() - p.y()) / p1p3ydist + rlong = (p3.color.r * p_p1_ratio) + (p1.color.r * p3_p_ratio) + glong = (p3.color.g * p_p1_ratio) + (p1.color.g * p3_p_ratio) + blong = (p3.color.b * p_p1_ratio) + (p1.color.b * p3_p_ratio) + + # rshort,gshort,bshort is the color on one of the shortys. + # rlong,glong,blong is the color on the longy. So depending on + # wether we have a lefty trigon or not, we can determine which + # colors are on the left and right edge. + if lefty: + rl = rshort + gl = gshort + bl = bshort + rr = rlong + gr = glong + br = blong + else: + rl = rlong + gl = glong + bl = blong + rr = rshort + gr = gshort + br = bshort + + # Find the distance from the left x to the right x (xdist). Then + # find the distances from the selector to each of these (saxdist + # and saxdist2). These distances are used to find the color at + # the selector. + xdist = rightx - leftx + saxdist = p.x() - leftx + saxdist2 = xdist - saxdist + + # Now determine the r,g,b values of the selector using a linear + # approximation. + if xdist != 0.0: + r = (saxdist2 * rl / xdist) + (saxdist * rr / xdist) + g = (saxdist2 * gl / xdist) + (saxdist * gr / xdist) + b = (saxdist2 * bl / xdist) + (saxdist * br / xdist) + else: + # In theory, the left and right color will be equal here. But + # because of the loss of precision, we get an error on both + # colors. The best approximation we can get is from adding + # the two errors, which in theory will eliminate the error + # but in practise will only minimize it. + r = (rl + rr) / 2 + g = (gl + gr) / 2 + b = (bl + br) / 2 + + # Now floor the color components and fit them into proper + # boundaries. This again is to compensate for the error caused by + # loss of precision. + ri = int(floor(r)) + gi = int(floor(g)) + bi = int(floor(b)) + if ri < 0: + ri = 0 + elif ri > 255: + ri = 255 + + if gi < 0: + gi = 0 + elif gi > 255: + gi = 255 + + if bi < 0: + bi = 0 + elif bi > 255: + bi = 255 + + # Voila, we have the color at the point of the selector. + return QtGui.QColor(ri, gi, bi) + + def paint_bg(self): + bg_image = QtGui.QPixmap(self.contentsRect().size()) + bg_image.fill(QtCore.Qt.transparent) + self.bg_image = bg_image + + painter = QtGui.QPainter(self.bg_image) + + painter.setRenderHint(QtGui.QPainter.Antialiasing) + + hue_gradient = QtGui.QConicalGradient( + bg_image.rect().center(), 90 - self.hue_offset + ) + sat_val_gradient = QtGui.QConicalGradient( + bg_image.rect().center(), 90 - self.hue_offset + ) + + hue_color = QtGui.QColor() + sat_val_color = QtGui.QColor() + _, sat, val, _ = self.cur_color.getHsv() + + for idx, hue in self._hue_circle_range: + hue_color.setHsv(hue, 255, 255) + sat_val_color.setHsv(hue, sat, val) + + hue_gradient.setColorAt(idx, hue_color) + sat_val_gradient.setColorAt(idx, sat_val_color) + + inner_radius = self.outer_radius - ( + self.outer_radius / self.inner_radius_ratio + ) + half_radius = self.outer_radius - ( + (self.outer_radius - inner_radius) / 2 + ) + + hue_inner_radius_rect = QtCore.QRectF( + bg_image.rect().center().x() - inner_radius, + bg_image.rect().center().y() - inner_radius, + inner_radius * 2 + 1, + inner_radius * 2 + 1 + ) + hue_outer_radius_rect = QtCore.QRectF( + bg_image.rect().center().x() - half_radius - 1, + bg_image.rect().center().y() - half_radius - 1, + half_radius * 2 + 3, + half_radius * 2 + 3 + ) + sat_val_inner_radius_rect = QtCore.QRectF( + bg_image.rect().center().x() - half_radius, + bg_image.rect().center().y() - half_radius, + half_radius * 2 + 1, + half_radius * 2 + 1 + ) + sat_val_outer_radius_rect = QtCore.QRectF( + bg_image.rect().center().x() - self.outer_radius, + bg_image.rect().center().y() - self.outer_radius, + self.outer_radius * 2 + 1, + self.outer_radius * 2 + 1 + ) + hue_path = QtGui.QPainterPath() + hue_path.addEllipse(hue_inner_radius_rect) + hue_path.addEllipse(hue_outer_radius_rect) + + sat_val_path = QtGui.QPainterPath() + sat_val_path.addEllipse(sat_val_inner_radius_rect) + sat_val_path.addEllipse(sat_val_outer_radius_rect) + + painter.save() + painter.setClipPath(hue_path) + painter.fillRect(self.bg_image.rect(), hue_gradient) + painter.restore() + + painter.save() + painter.setClipPath(sat_val_path) + painter.fillRect(self.bg_image.rect(), sat_val_gradient) + painter.restore() + + painter.end() + + @staticmethod + def vlen(x, y): + return sqrt((x ** 2) + (y ** 2)) + + @staticmethod + def vprod(x1, y1, x2, y2): + return x1 * x2 + y1 * y2 + + @staticmethod + def _angle_between_angles(p, a1, a2): + if a1 > a2: + a2 += TWOPI + if p < PI: + p += TWOPI + + return p >= a1 and p < a2 + + @staticmethod + def _point_above_point(x, y, px, py, ax, ay, bx, by): + floored_ax = floor(ax) + floored_bx = floor(bx) + floored_ay = floor(ay) + floored_by = floor(by) + + if floored_ax == floored_bx: + # line is vertical + if floored_ay < floored_by: + return x < ax + elif floored_ay > floored_by: + return x > ax + return not (x == ax and y == ay) + + if floored_ax > floored_bx: + if floored_ay < floored_by: + # line is draw upright-to-downleft + return (floor(x) < floor(px) or floor(y) < floor(py)) + elif floored_ay > floored_by: + # line is draw downright-to-upleft + return (floor(x) > floor(px) or floor(y) < floor(py)) + # line is flat horizontal + return y < ay + + if floored_ay < floored_by: + # line is draw upleft-to-downright + return (floor(x) < floor(px) or floor(y) > floor(py)) + elif floored_ay > floored_by: + # line is draw downleft-to-upright + return (floor(x) > floor(px) or floor(y) > floor(py)) + # line is flat horizontal + return y > ay + + @staticmethod + def _point_in_line(x, y, ax, ay, bx, by): + if ax > bx: + if ay < by: + # line is draw upright-to-downleft + + # if (x,y) is in on or above the upper right point, + # return -1. + if y <= ay and x >= ax: + return -1 + + # if (x,y) is in on or below the lower left point, + # return 1. + if y >= by and x <= bx: + return 1 + else: + # line is draw downright-to-upleft + + # If the line is flat, only use the x coordinate. + if floor(ay) == floor(by): + # if (x is to the right of the rightmost point, + # return -1. otherwise if x is to the left of the + # leftmost point, return 1. + if x >= ax: + return -1 + elif x <= bx: + return 1 + else: + # if (x,y) is on or below the lower right point, + # return -1. + if y >= ay and x >= ax: + return -1 + + # if (x,y) is on or above the upper left point, return 1. + if y <= by and x <= bx: + return 1 + else: + if ay < by: + # line is draw upleft-to-downright + + # If (x,y) is on or above the upper left point, return -1. + if y <= ay and x <= ax: + return -1 + + # If (x,y) is on or below the lower right point, return 1. + if y >= by and x >= bx: + return 1 + else: + # line is draw downleft-to-upright + + # If the line is flat, only use the x coordinate. + if floor(ay) == floor(by): + if x <= ax: + return -1 + elif x >= bx: + return 1 + else: + # If (x,y) is on or below the lower left point, return -1. + if y >= ay and x <= ax: + return -1 + + # If (x,y) is on or above the upper right point, return 1. + if y <= by and x >= bx: + return 1 + + # No tests proved that (x,y) was outside [(ax,ay),(bx,by)], so we + # assume it's inside the line's bounds. + return 0 + + def _move_point_to_triangle(self, x, y, a, b, c): + # Let v1A be the vector from (x,y) to a. + # Let v2A be the vector from a to b. + # Find the angle alphaA between v1A and v2A. + v1xA = x - a.point.x() + v1yA = y - a.point.y() + v2xA = b.point.x() - a.point.x() + v2yA = b.point.y() - a.point.y() + vpA = self.vprod(v1xA, v1yA, v2xA, v2yA) + cosA = vpA / (self.vlen(v1xA, v1yA) * self.vlen(v2xA, v2yA)) + alphaA = acos(cosA) + + # Let v1B be the vector from x to b. + # Let v2B be the vector from b to c. + v1xB = x - b.point.x() + v1yB = y - b.point.y() + v2xB = c.point.x() - b.point.x() + v2yB = c.point.y() - b.point.y() + vpB = self.vprod(v1xB, v1yB, v2xB, v2yB) + cosB = vpB / (self.vlen(v1xB, v1yB) * self.vlen(v2xB, v2yB)) + alphaB = acos(cosB) + + # Let v1C be the vector from x to c. + # Let v2C be the vector from c back to a. + v1xC = x - c.point.x() + v1yC = y - c.point.y() + v2xC = a.point.x() - c.point.x() + v2yC = a.point.y() - c.point.y() + vpC = self.vprod(v1xC, v1yC, v2xC, v2yC) + cosC = vpC / (self.vlen(v1xC, v1yC) * self.vlen(v2xC, v2yC)) + alphaC = acos(cosC) + + # Find the radian angles between the (1,0) vector and the points + # A, B, C and (x,y). Use this information to determine which of + # the edges we should project (x,y) onto. + angleA = self._angle_at(a.point, self.contentsRect()) + angleB = self._angle_at(b.point, self.contentsRect()) + angleC = self._angle_at(c.point, self.contentsRect()) + angleP = self._angle_at(QtCore.QPointF(x, y), self.contentsRect()) + + # If (x,y) is in the a-b area, project onto the a-b vector. + if self._angle_between_angles(angleP, angleA, angleB): + # Find the distance from (x,y) to a. Then use the slope of + # the a-b vector with this distance and the angle between a-b + # and a-(x,y) to determine the point of intersection of the + # perpendicular projection from (x,y) onto a-b. + pdist = sqrt( + ((x - a.point.x()) ** 2) + ((y - a.point.y()) ** 2) + ) + + # the length of all edges is always > 0 + p0x = ( + a.point.x() + + ((b.point.x() - a.point.x()) / self.vlen(v2xB, v2yB)) + * cos(alphaA) * pdist + ) + p0y = ( + a.point.y() + + ((b.point.y() - a.point.y()) / self.vlen(v2xB, v2yB)) + * cos(alphaA) * pdist + ) + + # If (x,y) is above the a-b line, which basically means it's + # outside the triangle, then return its projection onto a-b. + if self._point_above_point( + x, y, + p0x, p0y, + a.point.x(), a.point.y(), + b.point.x(), b.point.y() + ): + # If the projection is "outside" a, return a. If it is + # outside b, return b. Otherwise return the projection. + n = self._point_in_line( + p0x, p0y, + a.point.x(), a.point.y(), + b.point.x(), b.point.y() + ) + if n < 0: + return a.point + elif n > 0: + return b.point + + return QtCore.QPointF(p0x, p0y) + + elif self._angle_between_angles(angleP, angleB, angleC): + # If (x,y) is in the b-c area, project onto the b-c vector. + pdist = sqrt( + ((x - b.point.x()) ** 2) + ((y - b.point.y()) ** 2) + ) + + # the length of all edges is always > 0 + p0x = ( + b.point.x() + + ((c.point.x() - b.point.x()) / self.vlen(v2xC, v2yC)) + * cos(alphaB) * pdist + ) + p0y = ( + b.point.y() + + ((c.point.y() - b.point.y()) / self.vlen(v2xC, v2yC)) + * cos(alphaB) + * pdist + ) + + if self._point_above_point( + x, y, + p0x, p0y, + b.point.x(), b.point.y(), + c.point.x(), c.point.y() + ): + n = self._point_in_line( + p0x, p0y, + b.point.x(), b.point.y(), + c.point.x(), c.point.y() + ) + if n < 0: + return b.point + elif n > 0: + return c.point + return QtCore.QPointF(p0x, p0y) + + elif self._angle_between_angles(angleP, angleC, angleA): + # If (x,y) is in the c-a area, project onto the c-a vector. + pdist = sqrt( + ((x - c.point.x()) ** 2) + ((y - c.point.y()) ** 2) + ) + + # the length of all edges is always > 0 + p0x = ( + c.point.x() + + ((a.point.x() - c.point.x()) / self.vlen(v2xA, v2yA)) + * cos(alphaC) + * pdist + ) + p0y = ( + c.point.y() + + ((a.point.y() - c.point.y()) / self.vlen(v2xA, v2yA)) + * cos(alphaC) * pdist + ) + + if self._point_above_point( + x, y, + p0x, p0y, + c.point.x(), c.point.y(), + a.point.x(), a.point.y() + ): + n = self._point_in_line( + p0x, p0y, + c.point.x(), c.point.y(), + a.point.x(), a.point.y() + ) + if n < 0: + return c.point + elif n > 0: + return a.point + return QtCore.QPointF(p0x, p0y) + + # (x,y) is inside the triangle (inside a-b, b-c and a-c). + return QtCore.QPointF(x, y) diff --git a/openpype/widgets/color_widgets/color_view.py b/openpype/widgets/color_widgets/color_view.py new file mode 100644 index 0000000000..a4393a6625 --- /dev/null +++ b/openpype/widgets/color_widgets/color_view.py @@ -0,0 +1,78 @@ +from Qt import QtWidgets, QtCore, QtGui + + +class ColorViewer(QtWidgets.QWidget): + def __init__(self, parent=None): + super(ColorViewer, self).__init__(parent) + + self.setMinimumSize(10, 10) + + self.alpha = 255 + self.actual_pen = QtGui.QPen() + self.actual_color = QtGui.QColor() + self._checkerboard = None + + def checkerboard(self): + if not self._checkerboard: + checkboard_piece_size = 10 + color_1 = QtGui.QColor(188, 188, 188) + color_2 = QtGui.QColor(90, 90, 90) + + pix = QtGui.QPixmap( + checkboard_piece_size * 2, + checkboard_piece_size * 2 + ) + pix_painter = QtGui.QPainter(pix) + + rect = QtCore.QRect( + 0, 0, checkboard_piece_size, checkboard_piece_size + ) + pix_painter.fillRect(rect, color_1) + rect.moveTo(checkboard_piece_size, checkboard_piece_size) + pix_painter.fillRect(rect, color_1) + rect.moveTo(checkboard_piece_size, 0) + pix_painter.fillRect(rect, color_2) + rect.moveTo(0, checkboard_piece_size) + pix_painter.fillRect(rect, color_2) + pix_painter.end() + self._checkerboard = pix + + return self._checkerboard + + def color(self): + return self.actual_color + + def set_color(self, color): + if color == self.actual_color: + return + + # Create copy of entered color + self.actual_color = QtGui.QColor(color) + # Set alpha by current alpha value + self.actual_color.setAlpha(self.alpha) + # Repaint + self.update() + + def set_alpha(self, alpha): + if alpha == self.alpha: + return + # Change alpha of current color + self.actual_color.setAlpha(alpha) + # Store the value + self.alpha = alpha + # Repaint + self.update() + + def paintEvent(self, event): + rect = event.rect() + + # Paint everything to pixmap as it has transparency + pix = QtGui.QPixmap(rect.width(), rect.height()) + pix_painter = QtGui.QPainter(pix) + pix_painter.drawTiledPixmap(rect, self.checkerboard()) + pix_painter.fillRect(rect, self.actual_color) + pix_painter.end() + + painter = QtGui.QPainter(self) + painter.drawPixmap(rect, pix) + painter.end() From ac3fbcb7ce1c2ab34ef30f80f44a61acfb922b2f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 17:26:19 +0200 Subject: [PATCH 020/106] base implementation of ColorEntity view --- .../tools/settings/settings/categories.py | 6 +- .../tools/settings/settings/color_widget.py | 174 ++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 openpype/tools/settings/settings/color_widget.py diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index 4762aa4b6b..01d4babd0f 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -21,6 +21,7 @@ from openpype.settings.entities import ( TextEntity, PathInput, RawJsonEntity, + ColorEntity, DefaultsNotDefined, StudioDefaultsNotDefined, @@ -44,7 +45,7 @@ from .item_widgets import ( PathWidget, PathInputWidget ) - +from .color_widget import ColorWidget from avalon.vendor import qtawesome @@ -113,6 +114,9 @@ class SettingsCategoryWidget(QtWidgets.QWidget): elif isinstance(entity, RawJsonEntity): return RawJsonWidget(*args) + elif isinstance(entity, ColorEntity): + return ColorWidget(*args) + elif isinstance(entity, BaseEnumEntity): return EnumeratorWidget(*args) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py new file mode 100644 index 0000000000..54545d7450 --- /dev/null +++ b/openpype/tools/settings/settings/color_widget.py @@ -0,0 +1,174 @@ +from Qt import QtWidgets, QtCore, QtGui + +from .item_widgets import InputWidget + +from openpype.widgets.color_widgets import ColorPickerWidget + + +class ColorWidget(InputWidget): + def _add_inputs_to_layout(self): + self.input_field = ColorViewer(self.content_widget) + + self.setFocusProxy(self.input_field) + + self.content_layout.addWidget(self.input_field, 1) + + self.input_field.clicked.connect(self._on_click) + + self._dialog = None + + def _on_click(self): + if self._dialog: + self._dialog.open() + return + + dialog = ColorDialog(self.input_field.color(), self) + self._dialog = dialog + + dialog.open() + dialog.finished.connect(self._on_dialog_finish) + + def _on_dialog_finish(self, *_args): + if not self._dialog: + return + + color = self._dialog.result() + if color is not None: + self.input_field.set_color(color) + self._on_value_change() + + self._dialog.deleteLater() + self._dialog = None + + def _on_entity_change(self): + if self.entity.value != self.input_value(): + self.set_entity_value() + + def set_entity_value(self): + self.input_field.set_color(*self.entity.value) + + def input_value(self): + color = self.input_field.color() + return [color.red(), color.green(), color.blue(), color.alpha()] + + def _on_value_change(self): + if self.ignore_input_changes: + return + + self.entity.set(self.input_value()) + + +class ColorViewer(QtWidgets.QWidget): + clicked = QtCore.Signal() + + def __init__(self, parent=None): + super(ColorViewer, self).__init__(parent) + + self.setMinimumSize(10, 10) + + self.actual_pen = QtGui.QPen() + self.actual_color = QtGui.QColor() + self._checkerboard = None + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + self.clicked.emit() + super(ColorViewer, self).mouseReleaseEvent(event) + + def checkerboard(self): + if not self._checkerboard: + checkboard_piece_size = 10 + color_1 = QtGui.QColor(188, 188, 188) + color_2 = QtGui.QColor(90, 90, 90) + + pix = QtGui.QPixmap( + checkboard_piece_size * 2, + checkboard_piece_size * 2 + ) + pix_painter = QtGui.QPainter(pix) + + rect = QtCore.QRect( + 0, 0, checkboard_piece_size, checkboard_piece_size + ) + pix_painter.fillRect(rect, color_1) + rect.moveTo(checkboard_piece_size, checkboard_piece_size) + pix_painter.fillRect(rect, color_1) + rect.moveTo(checkboard_piece_size, 0) + pix_painter.fillRect(rect, color_2) + rect.moveTo(0, checkboard_piece_size) + pix_painter.fillRect(rect, color_2) + pix_painter.end() + self._checkerboard = pix + + return self._checkerboard + + def color(self): + return self.actual_color + + def set_color(self, *args): + # Create copy of entered color + self.actual_color = QtGui.QColor(*args) + # Repaint + self.update() + + def set_alpha(self, alpha): + # Change alpha of current color + self.actual_color.setAlpha(alpha) + # Repaint + self.update() + + def paintEvent(self, event): + rect = event.rect() + + # Paint everything to pixmap as it has transparency + pix = QtGui.QPixmap(rect.width(), rect.height()) + pix_painter = QtGui.QPainter(pix) + pix_painter.drawTiledPixmap(rect, self.checkerboard()) + pix_painter.fillRect(rect, self.actual_color) + pix_painter.end() + + painter = QtGui.QPainter(self) + painter.drawPixmap(rect, pix) + painter.end() + + +class ColorDialog(QtWidgets.QDialog): + def __init__(self, color=None, parent=None): + super(ColorDialog, self).__init__(parent) + + self.setWindowTitle("Color picker dialog") + + picker_widget = ColorPickerWidget(color, self) + + footer_widget = QtWidgets.QWidget(self) + footer_layout = QtWidgets.QHBoxLayout(footer_widget) + + ok_btn = QtWidgets.QPushButton("Ok", footer_widget) + cancel_btn = QtWidgets.QPushButton("Cancel", footer_widget) + + footer_layout.addWidget(ok_btn) + footer_layout.addWidget(cancel_btn) + footer_layout.addWidget(QtWidgets.QWidget(self), 1) + + layout = QtWidgets.QVBoxLayout(self) + + layout.addWidget(picker_widget, 1) + layout.addWidget(footer_widget, 0) + + ok_btn.clicked.connect(self.on_ok_clicked) + cancel_btn.clicked.connect(self.on_cancel_clicked) + + self.picker_widget = picker_widget + + self._result = None + + def on_ok_clicked(self): + self._result = self.picker_widget.color() + self.close() + + def on_cancel_clicked(self): + self._result = None + self.close() + + def result(self): + return self._result From 589dcfd6d0e1e311e240d631e2753532ce2ef10a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 17:56:00 +0200 Subject: [PATCH 021/106] Converted inputs to widgets --- .../widgets/color_widgets/color_inputs.py | 79 ++++++++++++------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index ddf8aebd4e..a4409988b2 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -25,11 +25,11 @@ QSlider::handle:horizontal:hover { }""" -class AlphaInputs(QtWidgets.QGroupBox): +class AlphaInputs(QtWidgets.QWidget): alpha_changed = QtCore.Signal(int) def __init__(self, parent=None): - super(AlphaInputs, self).__init__("Alpha", parent) + super(AlphaInputs, self).__init__(parent) self._block_changes = False self.alpha_value = None @@ -47,11 +47,13 @@ class AlphaInputs(QtWidgets.QGroupBox): inputs_layout.setContentsMargins(0, 0, 0, 0) percent_input = QtWidgets.QDoubleSpinBox(self) + percent_input.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) percent_input.setMinimum(0) percent_input.setMaximum(100) percent_input.setDecimals(2) int_input = QtWidgets.QSpinBox(self) + int_input.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) int_input.setMinimum(0) int_input.setMaximum(255) @@ -61,6 +63,7 @@ class AlphaInputs(QtWidgets.QGroupBox): inputs_layout.addWidget(QtWidgets.QLabel("%")) layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(QtWidgets.QLabel("Alpha", self)) layout.addWidget(alpha_slider) layout.addWidget(inputs_widget) @@ -119,11 +122,11 @@ class AlphaInputs(QtWidgets.QGroupBox): self._block_changes = False -class RGBInputs(QtWidgets.QGroupBox): +class RGBInputs(QtWidgets.QWidget): value_changed = QtCore.Signal() def __init__(self, color, parent=None): - super(RGBInputs, self).__init__("RGB", parent) + super(RGBInputs, self).__init__(parent) self._block_changes = False @@ -133,6 +136,10 @@ class RGBInputs(QtWidgets.QGroupBox): input_green = QtWidgets.QSpinBox(self) input_blue = QtWidgets.QSpinBox(self) + input_red.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_green.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_blue.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_red.setMinimum(0) input_green.setMinimum(0) input_blue.setMinimum(0) @@ -142,9 +149,10 @@ class RGBInputs(QtWidgets.QGroupBox): input_blue.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(input_red) - layout.addWidget(input_green) - layout.addWidget(input_blue) + layout.addWidget(QtWidgets.QLabel("RGB", self), 0) + layout.addWidget(input_red, 1) + layout.addWidget(input_green, 1) + layout.addWidget(input_blue, 1) input_red.valueChanged.connect(self._on_red_change) input_green.valueChanged.connect(self._on_green_change) @@ -192,11 +200,11 @@ class RGBInputs(QtWidgets.QGroupBox): self._block_changes = False -class CMYKInputs(QtWidgets.QGroupBox): +class CMYKInputs(QtWidgets.QWidget): value_changed = QtCore.Signal() def __init__(self, color, parent=None): - super(CMYKInputs, self).__init__("CMYK", parent) + super(CMYKInputs, self).__init__(parent) self.color = color @@ -207,6 +215,11 @@ class CMYKInputs(QtWidgets.QGroupBox): input_yellow = QtWidgets.QSpinBox(self) input_black = QtWidgets.QSpinBox(self) + input_cyan.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_magenta.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_yellow.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_black.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_cyan.setMinimum(0) input_magenta.setMinimum(0) input_yellow.setMinimum(0) @@ -218,10 +231,11 @@ class CMYKInputs(QtWidgets.QGroupBox): input_black.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(input_cyan) - layout.addWidget(input_magenta) - layout.addWidget(input_yellow) - layout.addWidget(input_black) + layout.addWidget(QtWidgets.QLabel("CMYK", self)) + layout.addWidget(input_cyan, 1) + layout.addWidget(input_magenta, 1) + layout.addWidget(input_yellow, 1) + layout.addWidget(input_black, 1) input_cyan.valueChanged.connect(self._on_change) input_magenta.valueChanged.connect(self._on_change) @@ -272,18 +286,19 @@ class CMYKInputs(QtWidgets.QGroupBox): self._block_changes = False -class HEXInputs(QtWidgets.QGroupBox): +class HEXInputs(QtWidgets.QWidget): hex_regex = re.compile("^#(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$") value_changed = QtCore.Signal() def __init__(self, color, parent=None): - super(HEXInputs, self).__init__("HEX", parent) + super(HEXInputs, self).__init__(parent) self.color = color - input_field = QtWidgets.QLineEdit() + input_field = QtWidgets.QLineEdit(self) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(input_field) + layout.addWidget(QtWidgets.QLabel("HEX", self), 0) + layout.addWidget(input_field, 1) input_field.textChanged.connect(self._on_change) @@ -316,11 +331,11 @@ class HEXInputs(QtWidgets.QGroupBox): self._block_changes = False -class HSVInputs(QtWidgets.QGroupBox): +class HSVInputs(QtWidgets.QWidget): value_changed = QtCore.Signal() def __init__(self, color, parent=None): - super(HSVInputs, self).__init__("HSV", parent) + super(HSVInputs, self).__init__(parent) self._block_changes = False @@ -330,6 +345,10 @@ class HSVInputs(QtWidgets.QGroupBox): input_sat = QtWidgets.QSpinBox(self) input_val = QtWidgets.QSpinBox(self) + input_hue.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_sat.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_val.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_hue.setMinimum(0) input_sat.setMinimum(0) input_val.setMinimum(0) @@ -339,9 +358,10 @@ class HSVInputs(QtWidgets.QGroupBox): input_val.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(input_hue) - layout.addWidget(input_sat) - layout.addWidget(input_val) + layout.addWidget(QtWidgets.QLabel("HSV", self), 0) + layout.addWidget(input_hue, 1) + layout.addWidget(input_sat, 1) + layout.addWidget(input_val, 1) input_hue.valueChanged.connect(self._on_change) input_sat.valueChanged.connect(self._on_change) @@ -385,11 +405,11 @@ class HSVInputs(QtWidgets.QGroupBox): self._block_changes = False -class HSLInputs(QtWidgets.QGroupBox): +class HSLInputs(QtWidgets.QWidget): value_changed = QtCore.Signal() def __init__(self, color, parent=None): - super(HSLInputs, self).__init__("HSL", parent) + super(HSLInputs, self).__init__(parent) self._block_changes = False @@ -399,6 +419,10 @@ class HSLInputs(QtWidgets.QGroupBox): input_sat = QtWidgets.QSpinBox(self) input_light = QtWidgets.QSpinBox(self) + input_hue.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_sat.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_light.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) + input_hue.setMinimum(0) input_sat.setMinimum(0) input_light.setMinimum(0) @@ -408,9 +432,10 @@ class HSLInputs(QtWidgets.QGroupBox): input_light.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(input_hue) - layout.addWidget(input_sat) - layout.addWidget(input_light) + layout.addWidget(QtWidgets.QLabel("HSL", self), 0) + layout.addWidget(input_hue, 1) + layout.addWidget(input_sat, 1) + layout.addWidget(input_light, 1) input_hue.valueChanged.connect(self._on_change) input_sat.valueChanged.connect(self._on_change) From ed6848d9d02e76d3bd05d6f5817eb6c8bce5939a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:02:12 +0200 Subject: [PATCH 022/106] used color type at 2 places --- .../schemas/schema_global_publish.json | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 0efe3b8fea..426da4b71e 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -228,14 +228,9 @@ ] }, { - "type": "schema_template", - "name": "template_rgba_color", - "template_data": [ - { - "label": "Fill Color", - "name": "fill_color" - } - ] + "type": "color", + "label": "Fill Color", + "key": "fill_color" }, { "key": "line_thickness", @@ -245,14 +240,9 @@ "maximum": 1000 }, { - "type": "schema_template", - "name": "template_rgba_color", - "template_data": [ - { - "label": "Line Color", - "name": "line_color" - } - ] + "type": "color", + "label": "Line Color", + "key": "line_color" } ] } From 3e1286531f27ab78441ba2f517e5f50da865bcea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:11:31 +0200 Subject: [PATCH 023/106] add empty line --- openpype/settings/entities/color_entity.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/settings/entities/color_entity.py b/openpype/settings/entities/color_entity.py index 7d31ba42b9..7a1b1d9848 100644 --- a/openpype/settings/entities/color_entity.py +++ b/openpype/settings/entities/color_entity.py @@ -8,6 +8,7 @@ from .exceptions import ( class ColorEntity(InputEntity): schema_types = ["color"] + def _item_initalization(self): self.valid_value_types = (list, ) self.value_on_not_set = [0, 0, 0, 255] From 2861078620d62cca8fc6d24d72a3c60a05e66ec5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:24:13 +0200 Subject: [PATCH 024/106] added small info about color entity --- openpype/settings/entities/schemas/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openpype/settings/entities/schemas/README.md b/openpype/settings/entities/schemas/README.md index 18312a8364..6c31b61f59 100644 --- a/openpype/settings/entities/schemas/README.md +++ b/openpype/settings/entities/schemas/README.md @@ -420,6 +420,18 @@ } ``` +### color +- preimplemented entity to store and load color values +- entity store and expect list of 4 integers in range 0-255 + - integers represents rgba [Red, Green, Blue, Alpha] + +``` +{ + "type": "color", + "key": "bg_color", + "label": "Background Color" +} +``` ## Noninteractive widgets - have nothing to do with data From ac2e759afc45e1347bc85994a10f2e33670447e7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:24:34 +0200 Subject: [PATCH 025/106] added color entity to examples --- .../entities/schemas/system_schema/example_schema.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/settings/entities/schemas/system_schema/example_schema.json b/openpype/settings/entities/schemas/system_schema/example_schema.json index 48a21cc0c6..a4ed56df32 100644 --- a/openpype/settings/entities/schemas/system_schema/example_schema.json +++ b/openpype/settings/entities/schemas/system_schema/example_schema.json @@ -4,6 +4,11 @@ "type": "dict", "is_file": true, "children": [ + { + "key": "color", + "label": "Color input", + "type": "color" + }, { "type": "dict", "key": "schema_template_exaples", From f8936f5e4038f2516363c645fd04182ec309c9d8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:34:29 +0200 Subject: [PATCH 026/106] replaced pick color text with an icon --- .../widgets/color_widgets/color_picker_widget.py | 9 +++++++-- openpype/widgets/color_widgets/eyedropper.png | Bin 0 -> 3178 bytes 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 openpype/widgets/color_widgets/eyedropper.png diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index d06af73cbf..5786c529ed 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -1,3 +1,4 @@ +import os from Qt import QtWidgets, QtCore, QtGui from .color_triangle import QtColorTriangle @@ -32,9 +33,13 @@ class ColorPickerWidget(QtWidgets.QWidget): color_view.setMaximumHeight(50) # Color pick button - btn_pick_color = QtWidgets.QPushButton( - "Pick a color", bottom_utils_widget + btn_pick_color = QtWidgets.QPushButton(bottom_utils_widget) + icon_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "eyedropper.png" ) + btn_pick_color.setIcon(QtGui.QIcon(icon_path)) + btn_pick_color.setToolTip("Pick a color") # Color inputs widget color_inputs = ColorInputsWidget(self) diff --git a/openpype/widgets/color_widgets/eyedropper.png b/openpype/widgets/color_widgets/eyedropper.png new file mode 100644 index 0000000000000000000000000000000000000000..baf6209e0be3d0f32cf76aebbfc0ba5edef7dc3a GIT binary patch literal 3178 zcmai1d0bQ1621W>8d;?5P$W%Q3YdjJKw`pT023sXeRF{jZXiGwk^m8u5L}8?i^L5m zA{G#os8rPAPsO}yL6Ln^Dn;s2K#PJP0(E&eV6m<3dw<*{=X^8YnfYes++TJF2CUOY zm>~cF(5BP8gQ0Iv)w5I+`aH!+9RvW4bDYpfaU{c^#Nu1X)6Y2)Lk_ ziIi|tcp{R7f|}f zg2e>>a>OG1ks~DEKf6enf`2k*F#fkWm;0AAL}H(GNQn2M{w1bA4iJTI5rDX0P{dCY zvOu47kS9jZE1}Yb6v&Z)DUseBF31x>>QYcH&VK`={spA+Q~1IVsHs2-%5mODr5uUQ zWhQ_ToOp5KBG-p~e~_2(cR&?cN}8&)VLT3$3*iG-f-3;;({Sy7ZQPrMuL1f>@D6*F=R!+ z6C5#kBF51z)NwV*$%#Z*?SLnc@C)(GTSK!D&lEHNpS`N1kz~k&!64B%A~9dMWqxa+ z%|pP{h1J3`g)`sZNaTE#NlcbXBnnC(Ab<1Nq-{4`9T%tOyS(4Dcat1)2Zur z>hp60PQMs_dtt63$v!a1fm}VZ%bILM{w{7*hris_p-2)u6Iy?J|8m5AQsxhjjlb;1 zO5IX!d`lhT7))15Qy&;Rm{Ro*AJOkPciV5my>0!KBpy3D?y|(eCdhX;4cBPO&cjo* zZhmS*!~J~jTmS44Tj^I<9@!I~D&lIri?xh4eT!Y678d6x4)Z-6R`pK$d(w%y%%7hO zE)DhQpWXoPN%3NKU-Z!BUKVH^$`=$kJRa69d$(z-Rc>?_exFpb>G1g*IwgG1+uK*V zKJW;xthYUsdq+R9aQlhm>J5Ud@PXl(m2t^0!Xj!f!;cCFzn{^TbSFHc)>qP@7sfIH zElLCc%k@5!L6fwYz58S(`%R?*gCYN_N7=QalRylj z+Ar5YABQJd>6soc)2p63PP_H_Z(hD$MSg=Z@<>xw@Yf<8&!$tW$S2FpQ({61= zmz+fHMQ+0bmwtWMT}sTNv}Y@>zRI1Pk(T>}n6H4hD2RBY`sE{PVhs|oPWCG2u{^uI z>E3VZv20z~Wa`((Yb|Px3Q-*Ccs|=4aJsA&iSXa6oYog?5ICRTd#~0xmVI5u-~B7u zlOG$jzeC}h<9cTpR`>byhuZt63_%3lklm*jsZOTPrr#fPE%pIg6vnltCMyrzEXXc@ z0G&e3!6+{{el_-+t33%|r+Wl4ltYCbef-cApd|%6Zq#7|o5*_OTcfe#$P%Yy^(&hG z0fDUn*Mfpz__{VFV(9RWFw84+Lw&&MDO{nEX{|^y9{=uL`7O0r_Rlh=^0abASqvg6 zSq8W2o!!v`9f*rIdBN~Z<3rVnhBKDuDj z2^97t2ln{O+tjBHPOZ1wyPF{+w^=qGRZC`thrwS*+lx?;K(ct<-_c47dFl1a8}Ayc zdB-Z|f{R$XIm54`3AftyhSKR9U{zL#hM)ZI(Z7n^kZFyUYee z(-S5=;l2QQxP~+G`ta5_*1bTvj0IM|(Ux4$dMkl+b}e}GI3HGS#l<$-jylB}R8}_I z=1jFQo^AWmFWZWXnlo404Olnb(VI0ZQ;?M{bLz()1Z*8DxfasZ zxRiix0#lj%J<~%vYqnH{hi(kCFE4rt>pNh_n1!2Ibk3eB-TPGS(U$rLU#=IFH(OR_ z3G!|9t;g(ppKUxSc1U4U1Tm*;){%Cvk@EA94-v5z{m)_D)>lnNM4xrQS6gv#%aAV& z#?M^zfM;e_M91b<^yB))S57G|#3Kx!$WF=!^N|njOD5m`9&^-|6%}ckiVlU^n{vi|cn+8iqVsoz z#j_(Gmgs(6Y9}AmaX>F~HiH^zxk6KO$;~<|j84ss4bFGeDdaBB0Q&Le;~2(LAN|kH zMlzQ?d)e3YDSZ#3_R)b(-Mh5L+32ALKfy{fOW0Wet#-|rR%{+#f5bYx;N*nck^%JS zby~PhUhciJh<#D|NX#K;j3U;_9HCJADXZc@y%sObZkNr@xDez_Wrn)b4+vsiP(AMX z8mX2^2&auY0cbd#x3xOD6y4Ec1G9t~XH{I270CMzvE$C&GzV}|qXx)r#=eC`j2{g> z&rj3fIm}dxjdIW9dMh^0JXzM$YnWTqdSg?-3|v8}uX!>CMit`CG?ZDb+wh)0S)UxS zK2g*P+l;KMex|vLHs@%wMxWZi71;C>$zK@9xzvR#)$*H~bOuW98}He<44rK5T-Ts< zRr;(v>D!f8;=U=zT$U_YL%pxOAM=2>UB`x<+H%tZhAT*Yt0g<#?y#|R{V!`9wUu{+ zORI`MNr1+ib#wFU%}35(uj!5PFKcwyJtfFcJASd*?}vW7SoXaf*hvl(k!Y$>)6rje4D1yJp+~51Ub!=tr6;&ba4KuKs@9lEOdVi`KTRRQ*Mu M`viEOSsR=CU*aw9$^ZZW literal 0 HcmV?d00001 From 101134bbdfdfe847e647f515296089d43c2e0b09 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 19 May 2021 18:37:20 +0200 Subject: [PATCH 027/106] moved with buttons --- openpype/tools/settings/settings/color_widget.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index 54545d7450..7b534b749c 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -141,14 +141,15 @@ class ColorDialog(QtWidgets.QDialog): picker_widget = ColorPickerWidget(color, self) footer_widget = QtWidgets.QWidget(self) - footer_layout = QtWidgets.QHBoxLayout(footer_widget) ok_btn = QtWidgets.QPushButton("Ok", footer_widget) cancel_btn = QtWidgets.QPushButton("Cancel", footer_widget) + footer_layout = QtWidgets.QHBoxLayout(footer_widget) + footer_layout.setContentsMargins(0, 0, 0, 0) + footer_layout.addStretch(1) footer_layout.addWidget(ok_btn) footer_layout.addWidget(cancel_btn) - footer_layout.addWidget(QtWidgets.QWidget(self), 1) layout = QtWidgets.QVBoxLayout(self) From e68a16c73562acf2b3440b195b333f120505f453 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 19 May 2021 19:08:44 +0200 Subject: [PATCH 028/106] script documentation, upgrade docusaurus to beta.0 --- website/docs/dev_build.md | 79 +- website/package.json | 5 +- website/yarn.lock | 3185 +++++++++++-------------------------- 3 files changed, 996 insertions(+), 2273 deletions(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index f3ee230964..2ee0d9a052 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -182,9 +182,10 @@ For more information about setting your build environment please refer to [pyenv +### MacOS To build pype on MacOS you wil need: -- **[Homebrew](https://brew.sh)**, Easy way of installing everything necessary is to use. +- **[Homebrew](https://brew.sh)** - easy way of installing everything necessary. - **[CMake](https://cmake.org/)** to build some external OpenPype dependencies. - **XCode Command Line Tools** (or some other build system) @@ -229,3 +230,79 @@ $ pyenv local 3.7.9 + +## Script tools + +(replace extension with the one for your system - `ps1` for windows, `sh` for linux/macos) + +### build + +This will build OpenPype to `build` directory. If virtual environment is not created yet, it will +install [Poetry](https://python-poetry.org/) and using it download and install necessary +packages needed for build. It is recommended that you run [fetch_thirdparty_libs](#fetch-thirdparty-libs) +to download FFMpeg, OpenImageIO and others that are needed by OpenPype and are copied during the build. + +#### Arguments +`--no-submodule-update` - to disable updating submodules. This allows to make custom-builds for testing +feature changes in submodules. + +### build_win_installer + +This will take already existing build in `build` directory and create executable installer using +[Inno Setup](https://jrsoftware.org/isinfo.php) and definitions in `./inno_setup.iss`. You need OpenPype +build using [build script](#build), Inno Setup installed and in PATH before running this script. + +:::note +Windows only +::: + +### create_env + +Script to create virtual environment for build and running OpenPype from sources. It is using +[Poetry](https://python-poetry.org/). All dependencies are defined in `pyproject.toml`, resolved by +Poetry into `poetry.lock` file and then installed. Running this script without Poetry will download +it, install it to `.poetry` and then install virtual environment from `poetry.lock` file. If you want +to update packages version, just run `poetry update` or delete lock file. + +#### Arguments +`--verbose` - to increase verbosity of Poetry. This can be useful for debugging package conflicts. + +### create_zip + +Script to create packaged OpenPype version from current sources. This will strip developer stuff and +package it into zip that can be used for [auto-updates for studio wide distributions](admin_distribute#automatic-updates), etc. + +### docker_build.sh + +Script to build OpenPype on [Docker](https://www.docker.com/) enabled systems - usually Linux and Windows +with [Docker Desktop](https://docs.docker.com/docker-for-windows/install/) +and [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) (WSL) installed. + +It must be run with administrative privileges - `sudo ./docker_build.sh`. + +It will use Centos 7 base image to build OpenPype. You'll see your build in `./build` folder. + +### fetch_thirdparty_libs + +This script will download necessary tools for OpenPype defined in `pyproject.toml` like FFMpeg, +OpenImageIO and USD libraries and put them to `./vendor/bin`. Those are then included in build. +Running it will overwrite everything on their respective paths. + +### make_docs + +Script will run [sphinx](https://www.sphinx-doc.org/) to build api documentation in html. You +should see it then under `./docs/build/html`. + +### run_documentation + +This will start up [Docusaurus](https://docusaurus.io/) to display OpenPype user documentation. +Useful for offline browsing or editing documentation itself. You will need [Node.js](https://nodejs.org/) +and [Yarn](https://yarnpkg.com/) to run this script. After executing it, you'll see new +browser window with current OpenPype documentation. + +### run_mongo + +Helper script to run local mongoDB server for development and testing. You will need +[mongoDB server](https://www.mongodb.com/try/download/community) installed in standard location +or in PATH (standard location works only on Windows). It will start by default on port `2707` and +it will put its db files to `../mongo_db_data` relative to OpenPype sources. \ No newline at end of file diff --git a/website/package.json b/website/package.json index 7bd8b4e77b..604eb69591 100644 --- a/website/package.json +++ b/website/package.json @@ -1,5 +1,6 @@ { "name": "pype-documentation", + "license": "MIT", "scripts": { "examples": "docusaurus-examples", "start": "docusaurus start", @@ -13,8 +14,8 @@ "docusaurus": "docusaurus" }, "dependencies": { - "@docusaurus/core": "2.0.0-alpha.72", - "@docusaurus/preset-classic": "2.0.0-alpha.72", + "@docusaurus/core": "2.0.0-beta.0", + "@docusaurus/preset-classic": "2.0.0-beta.0", "classnames": "^2.2.6", "clsx": "^1.1.1", "react": "^16.10.2", diff --git a/website/yarn.lock b/website/yarn.lock index d29fe48fce..7d3a5284c4 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -472,7 +472,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.13", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== @@ -516,7 +516,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.12.16", "@babel/plugin-proposal-optional-chaining@^7.13.12": +"@babel/plugin-proposal-optional-chaining@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== @@ -1109,18 +1109,6 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@choojs/findup@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3" - integrity sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw== - dependencies: - commander "^2.15.1" - -"@csstools/convert-colors@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" - integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== - "@docsearch/css@3.0.0-alpha.34": version "3.0.0-alpha.34" resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.0.0-alpha.34.tgz#5d5c39955956e237884a9997eb29e28c8adc99fa" @@ -1136,15 +1124,13 @@ "@docsearch/css" "3.0.0-alpha.34" algoliasearch "^4.0.0" -"@docusaurus/core@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-alpha.72.tgz#f1acff2d84b3cbca9c35906186c49ba16d019ce3" - integrity sha512-PV0rlvVRvVEdqs1I4PktwZBJkhFg4O4bVeqseaTYuA1u/poQSiiZ+rhrZRJ+/OcTHZ8VlYZw7tCHaRH4RLbP2g== +"@docusaurus/core@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-beta.0.tgz#05506ee02e7d40e9f4c8d7b4f918d26d3b191159" + integrity sha512-xWwpuEwFRKJmZvNGOpr/dyRDnx/psckLPsozQTg2hu3u81Wqu9gigWgYK/C2fPlEjxMcVw0/2WH+zwpbyWmF2Q== dependencies: "@babel/core" "^7.12.16" "@babel/generator" "^7.12.15" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.13" - "@babel/plugin-proposal-optional-chaining" "^7.12.16" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-transform-runtime" "^7.12.15" "@babel/preset-env" "^7.12.16" @@ -1153,25 +1139,26 @@ "@babel/runtime" "^7.12.5" "@babel/runtime-corejs3" "^7.12.13" "@babel/traverse" "^7.12.13" - "@docusaurus/cssnano-preset" "2.0.0-alpha.72" + "@docusaurus/cssnano-preset" "2.0.0-beta.0" "@docusaurus/react-loadable" "5.5.0" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" - "@docusaurus/utils-validation" "2.0.0-alpha.72" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" "@endiliey/static-site-generator-webpack-plugin" "^4.0.0" "@svgr/webpack" "^5.5.0" autoprefixer "^10.2.5" babel-loader "^8.2.2" babel-plugin-dynamic-import-node "2.3.0" boxen "^5.0.0" - cache-loader "^4.1.0" chalk "^4.1.0" chokidar "^3.5.1" clean-css "^5.1.1" commander "^5.1.0" - copy-webpack-plugin "^6.4.1" + copy-webpack-plugin "^8.1.0" core-js "^3.9.1" css-loader "^5.1.1" + css-minimizer-webpack-plugin "^2.0.0" + cssnano "^5.0.1" del "^6.0.0" detect-port "^1.3.0" eta "^1.12.1" @@ -1182,62 +1169,61 @@ globby "^11.0.2" html-minifier-terser "^5.1.1" html-tags "^3.1.0" - html-webpack-plugin "^4.5.0" + html-webpack-plugin "^5.2.0" import-fresh "^3.3.0" is-root "^2.1.0" - joi "^17.4.0" leven "^3.1.0" lodash "^4.17.20" - mini-css-extract-plugin "^0.8.0" + mini-css-extract-plugin "^1.4.0" module-alias "^2.2.2" nprogress "^0.2.0" - null-loader "^4.0.0" - optimize-css-assets-webpack-plugin "^5.0.4" - pnp-webpack-plugin "^1.6.4" - postcss "^8.2.7" - postcss-loader "^4.1.0" - postcss-preset-env "^6.7.0" + postcss "^8.2.10" + postcss-loader "^5.2.0" prompts "^2.4.0" react-dev-utils "^11.0.1" + react-error-overlay "^6.0.9" react-helmet "^6.1.0" react-loadable "^5.5.0" - react-loadable-ssr-addon "^0.3.0" + react-loadable-ssr-addon-v5-slorber "^1.0.1" react-router "^5.2.0" react-router-config "^5.1.1" react-router-dom "^5.2.0" resolve-pathname "^3.0.0" + rtl-detect "^1.0.2" semver "^7.3.4" serve-handler "^6.1.3" shelljs "^0.8.4" std-env "^2.2.1" - terser-webpack-plugin "^4.1.0" + strip-ansi "^6.0.0" + terser-webpack-plugin "^5.1.1" + tslib "^2.1.0" update-notifier "^5.1.0" url-loader "^4.1.1" wait-on "^5.2.1" - webpack "^4.44.1" + webpack "^5.28.0" webpack-bundle-analyzer "^4.4.0" webpack-dev-server "^3.11.2" - webpack-merge "^4.2.2" + webpack-merge "^5.7.3" webpackbar "^5.0.0-3" -"@docusaurus/cssnano-preset@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.0.0-alpha.72.tgz#03433315207b5f43f5ba280a75b8c00f2e02b461" - integrity sha512-7W/dlemTaipVd/zrd9Fjq/xp6IX/qn2z/GDaPbJ2SPklHbts5nWuRAt++wkG8Ue+Qxc9Q5uOBjW0ihVb4478+A== +"@docusaurus/cssnano-preset@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.0.0-beta.0.tgz#a79223479666059565d60a505bed2bbcac770384" + integrity sha512-gqQHeQCDHZDd5NaiKZwDiyg75sBCqDyAsvmFukkDAty8xE7u9IhzbOQKvCAtwseuvzu2BNN41gnJ8bz7vZzQiw== dependencies: - cssnano-preset-advanced "^4.0.7" - postcss "^7.0.2" - postcss-sort-media-queries "^1.7.26" + cssnano-preset-advanced "^5.0.0" + postcss "^8.2.10" + postcss-sort-media-queries "^3.8.9" -"@docusaurus/mdx-loader@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-alpha.72.tgz#03369c9fc156318a4696ece15b65b78f8ba727d0" - integrity sha512-tG8EZc3w4xt7IKJIniPFChfVY1/adpn6w6vsXVxE96Y/1PmqKjIp6mtVKdzTShaf6MCnKrAOtEUSQR0eCRHOjQ== +"@docusaurus/mdx-loader@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-beta.0.tgz#7a58933994b2face62e34698db2f9c88c53c6d61" + integrity sha512-oQLS2ZeUnqw79CV37glglZpaYgFfA5Az5lT83m5tJfMUZjoK4ehG1XWBeUzWy8QQNI452yAID8jz8jihEQeCcw== dependencies: "@babel/parser" "^7.12.16" "@babel/traverse" "^7.12.13" - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" "@mdx-js/mdx" "^1.6.21" "@mdx-js/react" "^1.6.21" escape-html "^1.0.3" @@ -1245,128 +1231,130 @@ fs-extra "^9.1.0" github-slugger "^1.3.0" gray-matter "^4.0.2" - loader-utils "^2.0.0" mdast-util-to-string "^2.0.0" remark-emoji "^2.1.0" stringify-object "^3.3.0" unist-util-visit "^2.0.2" url-loader "^4.1.1" - webpack "^4.44.1" + webpack "^5.28.0" -"@docusaurus/plugin-content-blog@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-alpha.72.tgz#478fe3c1011b8cfdb3ba7d782f8e192206954aee" - integrity sha512-q1noOyULAQ5CkSNciUZDf1v0ly234jX3Ts6ckAy/XK5B3F340Ou8UuEFNbVap2fkRC1hOXe7RnEmFwW1PxmqmA== +"@docusaurus/plugin-content-blog@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.0.tgz#ea7d3679ab252e8f0e58aaf80f1fc6001c72c755" + integrity sha512-lz63i5k/23RJ3Rk/2fIsYAoD8Wua3b5b0AbH2JoOhQu1iAIQiV8m91Z3XALBSzA3nBtAOIweNI7yzWL+JFSTvw== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/mdx-loader" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" - "@docusaurus/utils-validation" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/mdx-loader" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" chalk "^4.1.0" feed "^4.2.2" fs-extra "^9.1.0" globby "^11.0.2" - joi "^17.4.0" - loader-utils "^1.2.3" + loader-utils "^2.0.0" lodash "^4.17.20" reading-time "^1.3.0" remark-admonitions "^1.2.1" - webpack "^4.44.1" + tslib "^2.1.0" + webpack "^5.28.0" -"@docusaurus/plugin-content-docs@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-alpha.72.tgz#65255a0fa4fabbc5f3469b04c07f263ec93c67ac" - integrity sha512-EpMt0z/Z7SsOuQFIZlo31XsndxJ0blp7n0bVNcIlcFiNHYoBVVPbYb4VKP2W+1Sfw5K1XouUxoXRM30FyDrjhw== +"@docusaurus/plugin-content-docs@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-beta.0.tgz#a5a1e0e95e499eefee53e4f61aeb99ac4a669648" + integrity sha512-WdDQUh2rRCbfJswVc0vY9EaAspxgziqpVEZja8+BmQR/TZh7HuLplT6GJbiFbE4RvwM3+PwG/jHMPglYDK60kw== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/mdx-loader" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" - "@docusaurus/utils-validation" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/mdx-loader" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" chalk "^4.1.0" + combine-promises "^1.1.0" execa "^5.0.0" fs-extra "^9.1.0" globby "^11.0.2" import-fresh "^3.2.2" - joi "^17.4.0" + js-yaml "^4.0.0" loader-utils "^1.2.3" lodash "^4.17.20" remark-admonitions "^1.2.1" shelljs "^0.8.4" + tslib "^2.1.0" utility-types "^3.10.0" - webpack "^4.44.1" + webpack "^5.28.0" -"@docusaurus/plugin-content-pages@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-alpha.72.tgz#5b1ddf48f5270b8295f9b20d18f76cd230147c2b" - integrity sha512-ETBx+3+U+1sj0C/E8C3huQj5lGcSlmj0ZHBrBb3qP3zHS8+gWHAyUiXst3bvFs5mJX7JHkxfaHZc2hLxXLpaJg== +"@docusaurus/plugin-content-pages@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-beta.0.tgz#1cab3ebe0a08be74576f10c95675291bf84f848e" + integrity sha512-mk5LVVSvn+HJPKBaAs/Pceq/hTGxF2LVBvJEquuQz0NMAW3QdBWaYRRpOrL9CO8v+ygn5RuLslXsyZBsDNuhww== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/mdx-loader" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" - "@docusaurus/utils-validation" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/mdx-loader" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" globby "^11.0.2" - joi "^17.4.0" - loader-utils "^1.2.3" lodash "^4.17.20" minimatch "^3.0.4" remark-admonitions "^1.2.1" slash "^3.0.0" - webpack "^4.44.1" + tslib "^2.1.0" + webpack "^5.28.0" -"@docusaurus/plugin-debug@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-alpha.72.tgz#79f31decce97094117924875dfe267ae7572f48c" - integrity sha512-j2xR7i0Hw8v4SBtNvf8H5zoeKFZHScLdfJ93aUHe4ERf3AfACZuG8/tjnsarrfQK59HjbwWqbRC1mUgc2nFfwA== +"@docusaurus/plugin-debug@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-beta.0.tgz#bee672b8858d88bdb229d4301785ff4692ebd17f" + integrity sha512-m75sZdF8Yccxfih3qfdQg9DucMTrYBnmeTA8GNmdVaK701Ip8t50d1pDJchtu0FSEh6vzVB9C6D2YD5YgVFp8A== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" react-json-view "^1.21.1" + tslib "^2.1.0" -"@docusaurus/plugin-google-analytics@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-alpha.72.tgz#57b66682e6aad5cd5a70c9bf9ab8ef7177832aae" - integrity sha512-A73FA1hRHxbCZ7WVUthrEty5jRAdWlWAg9pijwSFFg5YG2kb0thNqGqMU/P5dqcV/ytE4907WvXMpKYmLtFVOg== +"@docusaurus/plugin-google-analytics@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-beta.0.tgz#ee287fb991202d8e9b792129dcc5542ef3ccd6c9" + integrity sha512-7lHrg1L+adc8VbiaLexa15i4fdq4MRPUTLMxRPAWz+QskhisW89Ryi2/gDmfMNqLblX84Qg2RASa+2gqO4wepw== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" -"@docusaurus/plugin-google-gtag@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-alpha.72.tgz#c7cbc4daa1be148b607ac3d1df3d396eede344f6" - integrity sha512-161+C6XZAziT/MRF9HZFCzg0ybzzkW/NHIuIKPmiQjeBB+DXYopvEmldKcPlZbs8YCSD9nMxkTx39pr1AWjffw== +"@docusaurus/plugin-google-gtag@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-beta.0.tgz#4836770130cf54ff2cd83affbff9644ee7293e9e" + integrity sha512-V7zaYbhAMv0jexm5H/5sAnoM1GHibcn9QQk5UWC++x1kE0KRuLDZHV+9OyvW5wr0wWFajod/b88SpUpSMF5u+g== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" -"@docusaurus/plugin-sitemap@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-alpha.72.tgz#6ad55c894c19315c91847d17f0c9dcfb145132f8" - integrity sha512-ZaMeJFDdey+PDMxg7qI2u9Wm7ylZb30FBR14wPSH5da+yMnNtl8wAlWEW8RkEgKYo04mE7DMvdEZ1YdsPF7cQg== +"@docusaurus/plugin-sitemap@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-beta.0.tgz#985d4cc3af86499f616ced024ba1fab8329e601d" + integrity sha512-dvmk8Sr+6pBkiKDb7Rjdp0GeFDWPUlayoJWK3fN3g0Fno6uxFfYhNZyXJ+ObyCA7HoW5rzeBMiO+uAja19JXTg== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" fs-extra "^9.1.0" - joi "^17.4.0" sitemap "^6.3.6" + tslib "^2.1.0" -"@docusaurus/preset-classic@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-alpha.72.tgz#8f20437207d53718387676cddccdb8d6f2eaf055" - integrity sha512-Z5XKcgyrZWyUvqQZ7cAJ+E3rHkXZPRo8/23vOV5f/5sM7HeW871e+FU37RXIEFu8E8fhpCgQQ6FPEVMyiVS7Uw== +"@docusaurus/preset-classic@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-beta.0.tgz#79eb4366e6b5eb7061370019127e40172432d770" + integrity sha512-cFpR0UaAeUt5qVx1bpidhlar6tiRNITIQlxP4bOVsjbxVTZhZ/cNuIz7C+2zFPCuKIflGXdTIQOrucPmd7z51Q== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/plugin-content-blog" "2.0.0-alpha.72" - "@docusaurus/plugin-content-docs" "2.0.0-alpha.72" - "@docusaurus/plugin-content-pages" "2.0.0-alpha.72" - "@docusaurus/plugin-debug" "2.0.0-alpha.72" - "@docusaurus/plugin-google-analytics" "2.0.0-alpha.72" - "@docusaurus/plugin-google-gtag" "2.0.0-alpha.72" - "@docusaurus/plugin-sitemap" "2.0.0-alpha.72" - "@docusaurus/theme-classic" "2.0.0-alpha.72" - "@docusaurus/theme-search-algolia" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/plugin-content-blog" "2.0.0-beta.0" + "@docusaurus/plugin-content-docs" "2.0.0-beta.0" + "@docusaurus/plugin-content-pages" "2.0.0-beta.0" + "@docusaurus/plugin-debug" "2.0.0-beta.0" + "@docusaurus/plugin-google-analytics" "2.0.0-beta.0" + "@docusaurus/plugin-google-gtag" "2.0.0-beta.0" + "@docusaurus/plugin-sitemap" "2.0.0-beta.0" + "@docusaurus/theme-classic" "2.0.0-beta.0" + "@docusaurus/theme-search-algolia" "2.0.0-beta.0" "@docusaurus/react-loadable@5.5.0": version "5.5.0" @@ -1375,92 +1363,91 @@ dependencies: prop-types "^15.6.2" -"@docusaurus/theme-classic@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-alpha.72.tgz#355ed24e4252ad6e24b774496e4a52598013116a" - integrity sha512-X5kDmMG6xCw+PpkOysnulcq9OuSsljR7Z/JiAkOeAFfd6LNeMk983q+Eu72xWxpmhmBBBkE56rhdxuBXKQJCsw== +"@docusaurus/theme-classic@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-beta.0.tgz#0ad74264dc592590bd7d8a6f6327cb83bbabc665" + integrity sha512-cBNtwAyg3be7Gk41FazMtgyibAcfuYaGHhGHIDRsXfc/qp3RhbiGiei7tyh200QT0NgKZxiVQy/r4d0mtjC++Q== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/plugin-content-blog" "2.0.0-alpha.72" - "@docusaurus/plugin-content-docs" "2.0.0-alpha.72" - "@docusaurus/plugin-content-pages" "2.0.0-alpha.72" - "@docusaurus/theme-common" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" - "@docusaurus/utils-validation" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/plugin-content-blog" "2.0.0-beta.0" + "@docusaurus/plugin-content-docs" "2.0.0-beta.0" + "@docusaurus/plugin-content-pages" "2.0.0-beta.0" + "@docusaurus/theme-common" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" "@mdx-js/mdx" "^1.6.21" "@mdx-js/react" "^1.6.21" - "@types/react-toggle" "^4.0.2" chalk "^4.1.0" clsx "^1.1.1" copy-text-to-clipboard "^3.0.0" fs-extra "^9.1.0" globby "^11.0.2" - infima "0.2.0-alpha.21" - joi "^17.4.0" + infima "0.2.0-alpha.23" lodash "^4.17.20" parse-numeric-range "^1.2.0" - postcss "^7.0.2" + postcss "^8.2.10" prism-react-renderer "^1.1.1" prismjs "^1.23.0" prop-types "^15.7.2" react-router-dom "^5.2.0" - react-toggle "^4.1.2" - rtlcss "^2.6.2" + rtlcss "^3.1.2" -"@docusaurus/theme-common@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.0.0-alpha.72.tgz#509426c81986676038e8300d457d1dc1bdda6c65" - integrity sha512-4NI3VCIBVJvOUk1YhBs2V4QwH1CR65sQQt2MFhHbeAmkKh1V0dYDFF8bVxrTSl7NhTICVk2Azn+tItRNkAXbdg== +"@docusaurus/theme-common@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.0.0-beta.0.tgz#3674ef6482cc39efa034fd8d8b1c831588896329" + integrity sha512-2rcVmQpvbdAgnzTWuM7Bfpu+2TQm928bhlvxn226jQy7IYz8ySRlIode63HhCtpx03hpdMCkrK6HxhfEcvHjQg== dependencies: - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/plugin-content-blog" "2.0.0-alpha.72" - "@docusaurus/plugin-content-docs" "2.0.0-alpha.72" - "@docusaurus/plugin-content-pages" "2.0.0-alpha.72" - "@docusaurus/types" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/plugin-content-blog" "2.0.0-beta.0" + "@docusaurus/plugin-content-docs" "2.0.0-beta.0" + "@docusaurus/plugin-content-pages" "2.0.0-beta.0" + "@docusaurus/types" "2.0.0-beta.0" + tslib "^2.1.0" -"@docusaurus/theme-search-algolia@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-alpha.72.tgz#3b9e074f6dd38b4fe0b51ac42eec64a4735b37ec" - integrity sha512-K+7WvYx0vkclaCN6nvcX4rFD/M+0b0YpjAbg+aFLzeAo77vIJESgByOc6RuK3XNALX4H2U8k7j0+wWIPsJtM1Q== +"@docusaurus/theme-search-algolia@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-beta.0.tgz#bfdee3981d8da72377b9045459950686d28a01fd" + integrity sha512-/GhgAm4yuwqTXWTsWnqpFYxpjTv+t45Wk8q/LmTVINa+A7b6jkMkch2lygagIt69/ufDm2Uw6eYhgrmF4DJqfQ== dependencies: "@docsearch/react" "^3.0.0-alpha.33" - "@docusaurus/core" "2.0.0-alpha.72" - "@docusaurus/theme-common" "2.0.0-alpha.72" - "@docusaurus/utils" "2.0.0-alpha.72" + "@docusaurus/core" "2.0.0-beta.0" + "@docusaurus/theme-common" "2.0.0-beta.0" + "@docusaurus/utils" "2.0.0-beta.0" + "@docusaurus/utils-validation" "2.0.0-beta.0" algoliasearch "^4.8.4" algoliasearch-helper "^3.3.4" clsx "^1.1.1" eta "^1.12.1" - joi "^17.4.0" lodash "^4.17.20" -"@docusaurus/types@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-alpha.72.tgz#5805b0536d584b67b914b937b0f08b17a47b8c18" - integrity sha512-/AfFD2Kdfm2rvG5j1v0w0L5gVuTPIE2vGOgLZh6EGzJT/Xx6CDdso9aAbhHiGfQkQS3bu1BPpLWqKlX9Ovi/aw== +"@docusaurus/types@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-beta.0.tgz#f473f417bdf690cfd52611ddf6d89ff939d1f2a4" + integrity sha512-z9PI+GbtYwqTXnkX4/a/A6psDX2p8N2uWlN2f4ifrm8WY4WhR9yiTOh0uo0pIqqaUQQvkEq3o5hOXuXLECEs+w== dependencies: - "@types/webpack" "^4.41.0" commander "^5.1.0" joi "^17.4.0" querystring "0.2.0" - webpack-merge "^4.2.2" + webpack "^5.28.0" + webpack-merge "^5.7.3" -"@docusaurus/utils-validation@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.0.0-alpha.72.tgz#38f2fa7907a57e3c5a1427b6ba0a514df1ea1d48" - integrity sha512-qhpyCVCCCTy0ui62GxXz6vLazcRCGal/jBGcgnxSgQ4AyXrU2NpPQH2hunOLknL6D3BivTb+w+IAFHE9JAMX0Q== +"@docusaurus/utils-validation@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.0.0-beta.0.tgz#3e6491c269a397fed29717a1cb69109df9483461" + integrity sha512-ELl/FVJ6xBz35TisZ1NmJhjbiVXDeU++K531PEFPCPmwnQPh7S6hZXdPnR71/Kc3BmuN9X2ZkwGOqNKVfys2Bg== dependencies: - "@docusaurus/utils" "2.0.0-alpha.72" + "@docusaurus/utils" "2.0.0-beta.0" chalk "^4.1.0" joi "^17.4.0" + tslib "^2.1.0" -"@docusaurus/utils@2.0.0-alpha.72": - version "2.0.0-alpha.72" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-alpha.72.tgz#04469cd9fee615d76b74b01680368af41129e916" - integrity sha512-seWNBdX9LI1jREiogh0azXZaf2HStzb3MECsjAVrtEikQFbfG7K7S27C9WXDlUeQw6LVL/q0JEjHFOJD+cTSLA== +"@docusaurus/utils@2.0.0-beta.0": + version "2.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-beta.0.tgz#6f2690fd6fcd942f0d690db1dffb96742762deb3" + integrity sha512-bvrT1EQu0maavr0Hb/lke9jmpzgVL/9tn5VQtbyahf472eJFY0bQDExllDrHK+l784SUvucqX0iaQeg0q6ySUw== dependencies: - "@docusaurus/types" "2.0.0-alpha.72" + "@docusaurus/types" "2.0.0-beta.0" "@types/github-slugger" "^1.3.0" chalk "^4.1.0" escape-string-regexp "^4.0.0" @@ -1468,6 +1455,7 @@ gray-matter "^4.0.2" lodash "^4.17.20" resolve-pathname "^3.0.0" + tslib "^2.1.0" "@endiliey/static-site-generator-webpack-plugin@^4.0.0": version "4.0.0" @@ -1548,14 +1536,6 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - "@polka/url@^1.0.0-next.9": version "1.0.0-next.11" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" @@ -1693,10 +1673,31 @@ dependencies: defer-to-connect "^1.0.1" -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== +"@trysound/sax@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" + integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== + +"@types/eslint-scope@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" + integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "7.2.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.10.tgz#4b7a9368d46c0f8cd5408c23288a59aa2394d917" + integrity sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.47": + version "0.0.47" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" + integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== "@types/github-slugger@^1.3.0": version "1.3.0" @@ -1723,7 +1724,7 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== -"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== @@ -1755,32 +1756,11 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== - "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== -"@types/react-toggle@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/react-toggle/-/react-toggle-4.0.2.tgz#46ffa5af1a55de5f25d0aa78ef0b557b5c8bf276" - integrity sha512-sHqfoKFnL0YU2+OC4meNEC8Ptx9FE8/+nFeFvNcdBa6ANA8KpAzj3R9JN8GtrvlLgjKDoYgI7iILgXYcTPo2IA== - dependencies: - "@types/react" "*" - -"@types/react@*": - version "17.0.3" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79" - integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/sax@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.1.tgz#e0248be936ece791a82db1a57f3fb5f7c87e8172" @@ -1788,197 +1768,130 @@ dependencies: "@types/node" "*" -"@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== - -"@types/source-list-map@*": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" - integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== - -"@types/tapable@*", "@types/tapable@^1.0.5": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" - integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== - -"@types/uglify-js@*": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124" - integrity sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q== - dependencies: - source-map "^0.6.1" - "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== -"@types/webpack-sources@*": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10" - integrity sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg== +"@webassemblyjs/ast@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f" + integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg== dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.7.3" + "@webassemblyjs/helper-numbers" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" -"@types/webpack@^4.41.0", "@types/webpack@^4.41.8": - version "4.41.26" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.26.tgz#27a30d7d531e16489f9c7607c747be6bc1a459ef" - integrity sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA== +"@webassemblyjs/floating-point-hex-parser@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c" + integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA== + +"@webassemblyjs/helper-api-error@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4" + integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w== + +"@webassemblyjs/helper-buffer@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642" + integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA== + +"@webassemblyjs/helper-numbers@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9" + integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ== dependencies: - "@types/anymatch" "*" - "@types/node" "*" - "@types/tapable" "*" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - source-map "^0.6.0" + "@webassemblyjs/floating-point-hex-parser" "1.11.0" + "@webassemblyjs/helper-api-error" "1.11.0" + "@xtuc/long" "4.2.2" -"@webassemblyjs/ast@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" - integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== +"@webassemblyjs/helper-wasm-bytecode@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1" + integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA== + +"@webassemblyjs/helper-wasm-section@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b" + integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew== dependencies: - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" -"@webassemblyjs/floating-point-hex-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" - integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== - -"@webassemblyjs/helper-api-error@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" - integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== - -"@webassemblyjs/helper-buffer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" - integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== - -"@webassemblyjs/helper-code-frame@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" - integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== - dependencies: - "@webassemblyjs/wast-printer" "1.9.0" - -"@webassemblyjs/helper-fsm@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" - integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== - -"@webassemblyjs/helper-module-context@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" - integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== - dependencies: - "@webassemblyjs/ast" "1.9.0" - -"@webassemblyjs/helper-wasm-bytecode@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" - integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== - -"@webassemblyjs/helper-wasm-section@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" - integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - -"@webassemblyjs/ieee754@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" - integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== +"@webassemblyjs/ieee754@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf" + integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" - integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== +"@webassemblyjs/leb128@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b" + integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" - integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== +"@webassemblyjs/utf8@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf" + integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw== -"@webassemblyjs/wasm-edit@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" - integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== +"@webassemblyjs/wasm-edit@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78" + integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/helper-wasm-section" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-opt" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - "@webassemblyjs/wast-printer" "1.9.0" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/helper-wasm-section" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" + "@webassemblyjs/wasm-opt" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" + "@webassemblyjs/wast-printer" "1.11.0" -"@webassemblyjs/wasm-gen@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" - integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== +"@webassemblyjs/wasm-gen@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe" + integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/ieee754" "1.11.0" + "@webassemblyjs/leb128" "1.11.0" + "@webassemblyjs/utf8" "1.11.0" -"@webassemblyjs/wasm-opt@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" - integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== +"@webassemblyjs/wasm-opt@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978" + integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" -"@webassemblyjs/wasm-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" - integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== +"@webassemblyjs/wasm-parser@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754" + integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-api-error" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/ieee754" "1.11.0" + "@webassemblyjs/leb128" "1.11.0" + "@webassemblyjs/utf8" "1.11.0" -"@webassemblyjs/wast-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" - integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== +"@webassemblyjs/wast-printer@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e" + integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/floating-point-hex-parser" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-code-frame" "1.9.0" - "@webassemblyjs/helper-fsm" "1.9.0" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" - integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" + "@webassemblyjs/ast" "1.11.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -2004,16 +1917,16 @@ acorn-walk@^8.0.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== -acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - acorn@^8.0.4: version "8.1.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== +acorn@^8.2.1: + version "8.2.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" + integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== + address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -2032,12 +1945,12 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.1.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2074,7 +1987,7 @@ algoliasearch@^4.0.0, algoliasearch@^4.8.4: "@algolia/requester-node-http" "4.8.6" "@algolia/transporter" "4.8.6" -alphanum-sort@^1.0.0: +alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= @@ -2148,11 +2061,6 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - arg@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.0.tgz#a20e2bb5710e82950a516b3f933fee5ed478be90" @@ -2165,6 +2073,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2217,24 +2130,6 @@ asap@~2.0.3: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" - integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -2267,7 +2162,7 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^10.2.5: +autoprefixer@^10.0.2, autoprefixer@^10.2.5: version "10.2.5" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.5.tgz#096a0337dbc96c0873526d7fef5de4428d05382d" integrity sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA== @@ -2279,19 +2174,6 @@ autoprefixer@^10.2.5: normalize-range "^0.1.2" postcss-value-parser "^4.1.0" -autoprefixer@^9.4.7, autoprefixer@^9.6.1: - version "9.8.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" - integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== - dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - colorette "^1.2.1" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" - axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -2377,11 +2259,6 @@ base16@^1.0.0: resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= -base64-js@^1.0.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -2422,21 +2299,11 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bluebird@^3.5.5, bluebird@^3.7.1: +bluebird@^3.7.1: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.0.0, bn.js@^5.1.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -2515,72 +2382,6 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" - integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== - dependencies: - bn.js "^5.0.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== - dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.3" - inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - browserslist@4.14.2: version "4.14.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" @@ -2591,7 +2392,7 @@ browserslist@4.14.2: escalade "^3.0.2" node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.6.4: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.3: version "4.16.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== @@ -2602,6 +2403,17 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4 escalade "^3.1.1" node-releases "^1.1.70" +browserslist@^4.16.0: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -2612,30 +2424,6 @@ buffer-indexof@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== -buffer-json@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" - integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2646,50 +2434,6 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cacache@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^15.0.5: - version "15.0.6" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" - integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== - dependencies: - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2705,18 +2449,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cache-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" - integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== - dependencies: - buffer-json "^2.0.0" - find-cache-dir "^3.0.0" - loader-utils "^1.2.3" - mkdirp "^0.5.1" - neo-async "^2.6.1" - schema-utils "^2.0.0" - cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -2738,25 +2470,6 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2795,17 +2508,22 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196: version "1.0.30001204" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz#256c85709a348ec4d175e847a3b515c66e79f2aa" integrity sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== +caniuse-lite@^1.0.30001219: + version "1.0.30001228" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== + ccount@^1.0.0, ccount@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== -chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2878,7 +2596,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.4.1, chokidar@^3.5.1: +chokidar@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -2893,16 +2611,6 @@ chokidar@^3.4.1, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -2920,14 +2628,6 @@ ci-info@^3.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.1.1.tgz#9a32fcefdf7bcdb6f0a7e1c0f8098ec57897b80a" integrity sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ== -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2938,7 +2638,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.5, classnames@^2.2.6: +classnames@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== @@ -2985,6 +2685,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -3051,7 +2760,7 @@ color-string@^1.5.4: color-name "^1.0.0" simple-swizzle "^0.2.2" -color@^3.0.0: +color@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== @@ -3064,12 +2773,17 @@ colorette@^1.2.1, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== +combine-promises@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.1.0.tgz#72db90743c0ca7aab7d0d8d2052fd7b0f674de71" + integrity sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg== + comma-separated-tokens@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -commander@^2.15.1, commander@^2.20.0: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3089,6 +2803,11 @@ commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -3124,16 +2843,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -3156,16 +2865,6 @@ consola@^2.15.0: resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" @@ -3200,18 +2899,6 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" @@ -3222,22 +2909,18 @@ copy-text-to-clipboard@^3.0.0: resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c" integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q== -copy-webpack-plugin@^6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz#138cd9b436dbca0a6d071720d5414848992ec47e" - integrity sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA== +copy-webpack-plugin@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-8.1.1.tgz#3f697e162764925c2f0d235f380676125508fd26" + integrity sha512-rYM2uzRxrLRpcyPqGceRBDpxxUV8vcDqIKxAUKfcnFpcrPxT5+XvhTxv7XLjo5AvEJFPdAE3zCogG2JVahqgSQ== dependencies: - cacache "^15.0.5" - fast-glob "^3.2.4" - find-cache-dir "^3.3.1" + fast-glob "^3.2.5" glob-parent "^5.1.1" - globby "^11.0.1" - loader-utils "^2.0.0" + globby "^11.0.3" normalize-path "^3.0.0" - p-limit "^3.0.2" + p-limit "^3.1.0" schema-utils "^3.0.0" serialize-javascript "^5.0.1" - webpack-sources "^1.4.3" core-js-compat@^3.8.1, core-js-compat@^3.9.0: version "3.9.1" @@ -3262,16 +2945,6 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - cosmiconfig@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" @@ -3283,37 +2956,6 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - cross-fetch@^3.0.4: version "3.1.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.2.tgz#ee0c2f18844c4fde36150c2a4ddc068d20c1bc41" @@ -3341,55 +2983,27 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-blank-pseudo@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" - integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== - dependencies: - postcss "^7.0.5" - -css-color-names@0.0.4, css-color-names@^0.0.4: +css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== - dependencies: - postcss "^7.0.1" - timsort "^0.3.0" +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== -css-has-pseudo@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" - integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== +css-declaration-sorter@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.0.tgz#eb21f75860078627e9e3cc6f5535ccfcea445817" + integrity sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg== dependencies: - postcss "^7.0.6" - postcss-selector-parser "^5.0.0-rc.4" + timsort "^0.3.0" css-loader@^5.1.1: version "5.1.4" @@ -3409,12 +3023,18 @@ css-loader@^5.1.1: schema-utils "^3.0.0" semver "^7.3.4" -css-prefers-color-scheme@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" - integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== +css-minimizer-webpack-plugin@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz#3c42f6624ed4cf4780dd963e23ee649e5a25c1a8" + integrity sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw== dependencies: - postcss "^7.0.5" + cssnano "^5.0.0" + jest-worker "^26.3.0" + p-limit "^3.0.2" + postcss "^8.2.9" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" css-select-base-adapter@^0.1.1: version "0.1.1" @@ -3431,6 +3051,17 @@ css-select@^2.0.0, css-select@^2.0.2: domutils "^1.7.0" nth-check "^1.0.2" +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== + dependencies: + boolbase "^1.0.0" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" + css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" @@ -3467,118 +3098,84 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== -cssdb@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" - integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-advanced@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-4.0.7.tgz#d981527b77712e2f3f3f09c73313e9b71b278b88" - integrity sha512-j1O5/DQnaAqEyFFQfC+Z/vRlLXL3LxJHN+lvsfYqr7KgPH74t69+Rsy2yXkovWNaJjZYBpdz2Fj8ab2nH7pZXw== +cssnano-preset-advanced@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.0.1.tgz#b551bb9ad3abf7a9a79f0cace3bf50264018df64" + integrity sha512-g+LB6GcihLXcBEdDh+mzk1qX9jgtBkVpzAg1OlgrH6C+qKIQYRHwAPyaoXy95Ci83sYYXlwJ0OrqLYTIUEBLZQ== dependencies: - autoprefixer "^9.4.7" - cssnano-preset-default "^4.0.7" - postcss-discard-unused "^4.0.1" - postcss-merge-idents "^4.0.1" - postcss-reduce-idents "^4.0.2" - postcss-zindex "^4.0.1" + autoprefixer "^10.0.2" + cssnano-preset-default "^5.0.1" + postcss-discard-unused "^5.0.0" + postcss-merge-idents "^5.0.0" + postcss-reduce-idents "^5.0.0" + postcss-zindex "^5.0.0" -cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== +cssnano-preset-default@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.0.1.tgz#76adc00f7aae36ae80552b8356e21bec4b233ca2" + integrity sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q== dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" - postcss-unique-selectors "^4.0.1" + css-declaration-sorter "6.0.0" + cssnano-utils "^2.0.0" + postcss-calc "^8.0.0" + postcss-colormin "^5.0.0" + postcss-convert-values "^5.0.0" + postcss-discard-comments "^5.0.0" + postcss-discard-duplicates "^5.0.0" + postcss-discard-empty "^5.0.0" + postcss-discard-overridden "^5.0.0" + postcss-merge-longhand "^5.0.1" + postcss-merge-rules "^5.0.0" + postcss-minify-font-values "^5.0.0" + postcss-minify-gradients "^5.0.0" + postcss-minify-params "^5.0.0" + postcss-minify-selectors "^5.0.0" + postcss-normalize-charset "^5.0.0" + postcss-normalize-display-values "^5.0.0" + postcss-normalize-positions "^5.0.0" + postcss-normalize-repeat-style "^5.0.0" + postcss-normalize-string "^5.0.0" + postcss-normalize-timing-functions "^5.0.0" + postcss-normalize-unicode "^5.0.0" + postcss-normalize-url "^5.0.0" + postcss-normalize-whitespace "^5.0.0" + postcss-ordered-values "^5.0.0" + postcss-reduce-initial "^5.0.0" + postcss-reduce-transforms "^5.0.0" + postcss-svgo "^5.0.0" + postcss-unique-selectors "^5.0.0" -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= +cssnano-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.0.tgz#b04baaa312aa3dd5a854b7f61d76b9d94be07f74" + integrity sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA== -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== +cssnano@^5.0.0, cssnano@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.2.tgz#3f6de4fd5ecb7b5fb636c1a606de5f38cd241493" + integrity sha512-8JK3EnPsjQsULme9/e5M2hF564f/480hwsdcHvQ7ZtAIMfQ1O3SCfs+b8Mjf5KJxhYApyRshR2QSovEJi2K72Q== dependencies: - postcss "^7.0.0" + cosmiconfig "^7.0.0" + cssnano-preset-default "^5.0.1" + is-resolvable "^1.1.0" -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== - -cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== - dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" - -csso@^4.0.2: +csso@^4.0.2, csso@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: css-tree "^1.1.2" -csstype@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" - integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -3657,7 +3254,7 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -define-properties@^1.1.2, define-properties@^1.1.3: +define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -3723,14 +3320,6 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -3764,15 +3353,6 @@ detect-port@^1.3.0: address "^1.0.1" debug "^2.6.0" -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -3815,6 +3395,15 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + dom-serializer@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" @@ -3823,11 +3412,6 @@ dom-serializer@~0.1.0: domelementtype "^1.3.0" entities "^1.1.1" -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -3838,6 +3422,11 @@ domelementtype@^2.0.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== +domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" @@ -3845,6 +3434,13 @@ domhandler@^2.3.0: dependencies: domelementtype "1" +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" + integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== + dependencies: + domelementtype "^2.2.0" + domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" @@ -3861,6 +3457,15 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^2.4.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" + integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -3886,16 +3491,6 @@ duplexer@^0.1.1, duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -3906,18 +3501,10 @@ electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz#5de813960f23581a268718a0058683dffa15d221" integrity sha512-VEXDzYblnlT+g8Q3gedwzgKOso1evkeJzV8lih7lV8mL8eAnGVnKyC3KsFT6S+R5PQO4ffdr1PI16/ElibY/kQ== -elliptic@^6.5.3: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" +electron-to-chromium@^1.3.723: + version "1.3.732" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz#2a07a8d61f74f2084b6f6bf2a908605a7a0b2d8d" + integrity sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw== "emoji-regex@>=6.0.0 <=6.1.1": version "6.1.1" @@ -3949,21 +3536,20 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" - integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== +enhanced-resolve@^5.8.0: + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" + graceful-fs "^4.2.4" + tapable "^2.2.0" entities@^1.1.1, entities@~1.1.1: version "1.1.2" @@ -3975,7 +3561,7 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== @@ -4011,6 +3597,11 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.2: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.0" +es-module-lexer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e" + integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA== + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -4050,12 +3641,12 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" esprima@^4.0.0: @@ -4063,7 +3654,7 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esrecurse@^4.1.0: +esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== @@ -4112,7 +3703,7 @@ events@^1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= -events@^3.0.0: +events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -4124,14 +3715,6 @@ eventsource@^1.0.7: dependencies: original "^1.0.0" -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -4248,7 +3831,7 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1, fast-glob@^3.2.4: +fast-glob@^3.1.1, fast-glob@^3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== @@ -4318,11 +3901,6 @@ feed@^4.2.2: dependencies: xml-js "^1.6.11" -figgy-pudding@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== - figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -4378,16 +3956,7 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: +find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -4411,18 +3980,13 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" + locate-path "^6.0.0" + path-exists "^4.0.0" flux@^4.0.1: version "4.0.1" @@ -4477,14 +4041,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -4495,23 +4051,6 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -4605,7 +4144,12 @@ glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -4657,7 +4201,7 @@ globby@11.0.1: merge2 "^1.3.0" slash "^3.0.0" -globby@^11.0.1, globby@^11.0.2: +globby@^11.0.1, globby@^11.0.2, globby@^11.0.3: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== @@ -4704,7 +4248,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -4795,30 +4339,13 @@ has-yarn@^2.1.0: resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== -has@^1.0.0, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - hast-to-hyperscript@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" @@ -4930,15 +4457,6 @@ history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - hoist-non-react-statics@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -4966,11 +4484,6 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - html-entities@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" @@ -4999,20 +4512,16 @@ html-void-elements@^1.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== -html-webpack-plugin@^4.5.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" - integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== +html-webpack-plugin@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz#8797327548e3de438e3494e0c6d06f181a7f20d1" + integrity sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ== dependencies: "@types/html-minifier-terser" "^5.0.0" - "@types/tapable" "^1.0.5" - "@types/webpack" "^4.41.8" html-minifier-terser "^5.0.1" - loader-utils "^1.2.3" lodash "^4.17.20" pretty-error "^2.1.1" - tapable "^1.1.3" - util.promisify "1.0.0" + tapable "^2.0.0" htmlparser2@^3.10.1, htmlparser2@^3.9.1: version "3.10.1" @@ -5092,11 +4601,6 @@ http-proxy@^1.17.0: follow-redirects "^1.0.0" requires-port "^1.0.0" -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5114,16 +4618,6 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.4: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" @@ -5134,14 +4628,6 @@ immer@8.0.1: resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - import-fresh@^3.2.1, import-fresh@^3.2.2, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -5178,15 +4664,10 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -infima@0.2.0-alpha.21: - version "0.2.0-alpha.21" - resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.21.tgz#53cc49dbcaf5a8d165cbe4acf214eee02bca6154" - integrity sha512-32uq+rWIrLNZx0jzNrwJWE8Go9NvpP0JTRKMXJ8aYlWZ0vm9OCgAEcVquwFBSW6ZP7R2rjBUjPy/nJ3PK7MhUA== +infima@0.2.0-alpha.23: + version "0.2.0-alpha.23" + resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.23.tgz#2c17b473784ae8244fd985f126f9c27a49b24523" + integrity sha512-V0RTjB1otjpH3E2asbydx3gz7ovdSJsuV7r9JTdBggqRilnelTJUcXxLawBQQKsjQi5qPcRTjxnlaV8xyyKhhw== inflight@^1.0.4: version "1.0.6" @@ -5196,16 +4677,11 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -5254,11 +4730,6 @@ ipaddr.js@1.9.1, ipaddr.js@^1.9.0: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - is-absolute-url@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" @@ -5356,7 +4827,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-color-stop@^1.0.0: +is-color-stop@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= @@ -5417,11 +4888,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - is-docker@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" @@ -5542,11 +5008,6 @@ is-path-inside@^3.0.2: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-obj@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -5572,7 +5033,7 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-resolvable@^1.0.0: +is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== @@ -5597,13 +5058,6 @@ is-string@^1.0.5: resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" - is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -5653,7 +5107,7 @@ isarray@0.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -5675,7 +5129,7 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jest-worker@^26.5.0: +jest-worker@^26.3.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -5708,6 +5162,13 @@ js-yaml@^3.11.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -5723,7 +5184,7 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -5812,14 +5273,6 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -last-call-webpack-plugin@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" - integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== - dependencies: - lodash "^4.17.5" - webpack-sources "^1.1.0" - latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -5837,10 +5290,10 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== loader-utils@2.0.0, loader-utils@^2.0.0: version "2.0.0" @@ -5851,7 +5304,7 @@ loader-utils@2.0.0, loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: +loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -5875,10 +5328,12 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" lodash.assignin@^4.0.9: version "4.2.0" @@ -5960,21 +5415,6 @@ lodash.some@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= -lodash.template@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.toarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" @@ -5985,7 +5425,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6019,13 +5459,6 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -6033,14 +5466,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -6065,15 +5490,6 @@ markdown-escapes@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - mdast-squeeze-paragraphs@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" @@ -6135,14 +5551,6 @@ memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -6195,14 +5603,6 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - mime-db@1.46.0, "mime-db@>= 1.43.0 < 2": version "1.46.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" @@ -6255,26 +5655,20 @@ mini-create-react-context@^0.4.0: "@babel/runtime" "^7.12.1" tiny-warning "^1.0.3" -mini-css-extract-plugin@^0.8.0: - version "0.8.2" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.2.tgz#a875e169beb27c88af77dd962771c9eedc3da161" - integrity sha512-a3Y4of27Wz+mqK3qrcd3VhYz6cU0iW5x3Sgvqzbj+XmlrSizmvu8QQMl5oMYJjgHOC4iyt+w7l4umP+dQeW3bw== +mini-css-extract-plugin@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz#b4db2525af2624899ed64a23b0016e0036411893" + integrity sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw== dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" webpack-sources "^1.1.0" -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: +minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -6287,58 +5681,6 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -6347,14 +5689,14 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -6364,18 +5706,6 @@ module-alias@^2.2.2: resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -6419,6 +5749,11 @@ nanoid@^3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -6441,7 +5776,7 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.5.0, neo-async@^2.6.1: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -6476,40 +5811,16 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - node-releases@^1.1.61, node-releases@^1.1.70: version "1.1.71" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -6527,22 +5838,7 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== - -normalize-url@^4.1.0: +normalize-url@^4.1.0, normalize-url@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== @@ -6573,18 +5869,12 @@ nth-check@^1.0.2, nth-check@~1.0.1: dependencies: boolbase "~1.0.0" -null-loader@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-4.0.1.tgz#8e63bd3a2dd3c64236a4679428632edd0a6dbc6a" - integrity sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg== +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + boolbase "^1.0.0" object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -6635,7 +5925,7 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: +object.getownpropertydescriptors@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== @@ -6712,14 +6002,6 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optimize-css-assets-webpack-plugin@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" - integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== - dependencies: - cssnano "^4.1.10" - last-call-webpack-plugin "^3.0.0" - original@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" @@ -6727,11 +6009,6 @@ original@^1.0.0: dependencies: url-parse "^1.4.3" -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -6749,7 +6026,7 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -6770,6 +6047,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -6804,20 +6088,6 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pako@~1.0.5: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - param-case@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -6833,17 +6103,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" - integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== - dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" @@ -6856,14 +6115,6 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -6907,11 +6158,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -6974,17 +6220,6 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -7033,13 +6268,6 @@ pkg-up@3.1.0: dependencies: find-up "^3.0.0" -pnp-webpack-plugin@^1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" - integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== - dependencies: - ts-pnp "^1.1.6" - portfinder@^1.0.26: version "1.0.28" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" @@ -7054,317 +6282,128 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-attribute-case-insensitive@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" - integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== dependencies: - postcss "^7.0.2" - postcss-selector-parser "^6.0.2" - -postcss-calc@^7.0.1: - version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" - integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== - dependencies: - postcss "^7.0.27" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.2" -postcss-color-functional-notation@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" - integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-color-gray@^5.0.0: +postcss-colormin@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" - integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.0.0.tgz#283b8934c8bdbc531e7648aeb0970107f6d06d0e" + integrity sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.5" - postcss-values-parser "^2.0.0" + browserslist "^4.16.0" + color "^3.1.1" + postcss-value-parser "^4.1.0" -postcss-color-hex-alpha@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" - integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== - dependencies: - postcss "^7.0.14" - postcss-values-parser "^2.0.1" - -postcss-color-mod-function@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" - integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-color-rebeccapurple@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" - integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== - dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-custom-media@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" - integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== - dependencies: - postcss "^7.0.14" - -postcss-custom-properties@^8.0.11: - version "8.0.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" - integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== - dependencies: - postcss "^7.0.17" - postcss-values-parser "^2.0.1" - -postcss-custom-selectors@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" - integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-dir-pseudo-class@^5.0.0: +postcss-convert-values@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" - integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.0.tgz#cd77e1d23ebe8fcf508640551eed08e232784cba" + integrity sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ== dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" + postcss-value-parser "^4.1.0" -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== +postcss-discard-comments@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.0.tgz#6c27310e0657c0b9e38a6175ad001b5aa28964bc" + integrity sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ== + +postcss-discard-duplicates@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.0.tgz#6a2c4f779e8d20da6781e90730f234f9e650c51c" + integrity sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ== + +postcss-discard-empty@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.0.tgz#0f0a9baee415f5f7be4ae046ba235e98626ba821" + integrity sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ== + +postcss-discard-overridden@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.0.tgz#ac00f695a60001eda52135a11fac87376b8da9ee" + integrity sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg== + +postcss-discard-unused@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.0.0.tgz#6aad1061a53088d4b4d4363496d85b9b0de34f7e" + integrity sha512-C+bchjnGRoGlSQjACMts/FlpY3LMDEUS5+9rHKxvl/NFUY/5OYWjkA1AEUo9HDWnFB44CFgcm6khLMSIbrjVEQ== dependencies: - postcss "^7.0.0" + postcss-selector-parser "^6.0.4" -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== - dependencies: - postcss "^7.0.0" - -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== - dependencies: - postcss "^7.0.0" - -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== - dependencies: - postcss "^7.0.0" - -postcss-discard-unused@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-4.0.1.tgz#ee7cc66af8c7e8c19bd36f12d09c4bde4039abea" - integrity sha512-/3vq4LU0bLH2Lj4NYN7BTf2caly0flUB7Xtrk9a5K3yLuXMkHMqMO/x3sDq8W2b1eQFSCyY0IVz2L+0HP8kUUA== - dependencies: - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - uniqs "^2.0.0" - -postcss-double-position-gradients@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" - integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== - dependencies: - postcss "^7.0.5" - postcss-values-parser "^2.0.0" - -postcss-env-function@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" - integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-focus-visible@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" - integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== - dependencies: - postcss "^7.0.2" - -postcss-focus-within@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" - integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== - dependencies: - postcss "^7.0.2" - -postcss-font-variant@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" - integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== - dependencies: - postcss "^7.0.2" - -postcss-gap-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" - integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== - dependencies: - postcss "^7.0.2" - -postcss-image-set-function@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" - integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-initial@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" - integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== - dependencies: - lodash.template "^4.5.0" - postcss "^7.0.2" - -postcss-lab-function@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" - integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-loader@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.2.0.tgz#f6993ea3e0f46600fb3ee49bbd010448123a7db4" - integrity sha512-mqgScxHqbiz1yxbnNcPdKYo/6aVt+XExURmEbQlviFVWogDbM4AJ0A/B+ZBpYsJrTRxKw7HyRazg9x0Q9SWwLA== +postcss-loader@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.3.0.tgz#1657f869e48d4fdb018a40771c235e499ee26244" + integrity sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw== dependencies: cosmiconfig "^7.0.0" klona "^2.0.4" - loader-utils "^2.0.0" - schema-utils "^3.0.0" semver "^7.3.4" -postcss-logical@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" - integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== +postcss-merge-idents@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.0.0.tgz#13b6598912a96e93552c778bbfeaaf2cfaf46b68" + integrity sha512-s8wwhAB/SJDPkcVxj31s2SGzgrO66ktUYjWh6j4qwY67Mzxx3/TkK+m/+v6tU/xyW4TmGd4yuyTXsHaaLC0jLg== dependencies: - postcss "^7.0.2" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-media-minmax@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" - integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== +postcss-merge-longhand@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.1.tgz#1a008ff72d14cd3e2f3d32accc2ad37948bcabf4" + integrity sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw== dependencies: - postcss "^7.0.2" + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.0" -postcss-merge-idents@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-4.0.1.tgz#b7df282a92f052ea0a66c62d8f8812e6d2cbed23" - integrity sha512-43S/VNdF6II0NZ31YxcvNYq4gfURlPAAsJW/z84avBXQCaP4I4qRHUH18slW/SOlJbcxxCobflPNUApYDddS7A== +postcss-merge-rules@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.0.tgz#e0d0c0d45c98376f4adb49eb1f1dfe2aebfd7048" + integrity sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg== dependencies: - cssnano-util-same-parent "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== - dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" - -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== - dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" + cssnano-utils "^2.0.0" + postcss-selector-parser "^6.0.4" + vendors "^1.0.3" -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== +postcss-minify-font-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.0.tgz#fee5d0fa192fae8757cb744870a0ad02be5f402e" + integrity sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== +postcss-minify-gradients@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.0.tgz#95dbe61567a45c0cd7ab897d78fb65d5096844ed" + integrity sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg== dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + is-color-stop "^1.1.0" + postcss-value-parser "^4.1.0" -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== +postcss-minify-params@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.0.tgz#12c7f75d69b0b4827fafbd6649970a53784a9c24" + integrity sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug== dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" uniqs "^2.0.0" -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== +postcss-minify-selectors@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.0.0.tgz#d3e43d97fd0ba83ba0010950fc5acfa420f7caa9" + integrity sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ== dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + alphanum-sort "^1.0.2" + postcss-selector-parser "^3.1.2" postcss-modules-extract-imports@^3.0.0: version "3.0.0" @@ -7394,228 +6433,105 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" - integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== - dependencies: - postcss "^7.0.2" +postcss-normalize-charset@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.0.tgz#59e1fe2094fb2e3371cc5b054cbc39828a41a710" + integrity sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ== -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== +postcss-normalize-display-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.0.tgz#4ff2d3b3b5146a366de28ec9e24131a1868f1933" + integrity sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA== dependencies: - postcss "^7.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== +postcss-normalize-positions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.0.tgz#fe1d9a8122dd385b9c6908bd2008140dea17750d" + integrity sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== +postcss-normalize-repeat-style@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.0.tgz#e11d88fbf63f89179c6a7391853b2fe7f46e589d" + integrity sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ== dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== +postcss-normalize-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.0.tgz#2ea08ff4cb8817ce160755e9fdc7e6ef6d495002" + integrity sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw== dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== +postcss-normalize-timing-functions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.0.tgz#380eb1c9b179f96efc307c659a8049116f16f381" + integrity sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q== dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== +postcss-normalize-unicode@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.0.tgz#aa46a89c86ae51a01cbca13e73c1ed7b0b38807e" + integrity sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== +postcss-normalize-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.0.tgz#626a4c7d30007f94466cdf245e7ed9f253f1dbd9" + integrity sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + is-absolute-url "^3.0.3" + normalize-url "^4.5.0" + postcss-value-parser "^4.1.0" -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== +postcss-normalize-whitespace@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.0.tgz#1faf147a4f8d3d93a3c75109d120b4eefa00589b" + integrity sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA== dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== +postcss-ordered-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.0.tgz#a50f224c5f40c566b338b0663655478737dcebee" + integrity sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== +postcss-reduce-idents@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.0.0.tgz#a6fbc9369b955daa756fe578de2ed916c01eed56" + integrity sha512-wDth7wkXAZ91i7GNe+/PJKyC9NOR2n04U0t5nnqlvlkKhMhnRn/8NJLYQRa7ZZHPGOZcOfvugrhblioTTg2X8A== dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-overflow-shorthand@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" - integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== +postcss-reduce-initial@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.0.tgz#c724e5513b0ae7f3d7bff16f0fc82133fb2f820a" + integrity sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA== dependencies: - postcss "^7.0.2" - -postcss-page-break@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" - integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== - dependencies: - postcss "^7.0.2" - -postcss-place@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" - integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-preset-env@^6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" - integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== - dependencies: - autoprefixer "^9.6.1" - browserslist "^4.6.4" - caniuse-lite "^1.0.30000981" - css-blank-pseudo "^0.1.4" - css-has-pseudo "^0.10.0" - css-prefers-color-scheme "^3.1.1" - cssdb "^4.4.0" - postcss "^7.0.17" - postcss-attribute-case-insensitive "^4.0.1" - postcss-color-functional-notation "^2.0.1" - postcss-color-gray "^5.0.0" - postcss-color-hex-alpha "^5.0.3" - postcss-color-mod-function "^3.0.3" - postcss-color-rebeccapurple "^4.0.1" - postcss-custom-media "^7.0.8" - postcss-custom-properties "^8.0.11" - postcss-custom-selectors "^5.1.2" - postcss-dir-pseudo-class "^5.0.0" - postcss-double-position-gradients "^1.0.0" - postcss-env-function "^2.0.2" - postcss-focus-visible "^4.0.0" - postcss-focus-within "^3.0.0" - postcss-font-variant "^4.0.0" - postcss-gap-properties "^2.0.0" - postcss-image-set-function "^3.0.1" - postcss-initial "^3.0.0" - postcss-lab-function "^2.0.1" - postcss-logical "^3.0.0" - postcss-media-minmax "^4.0.0" - postcss-nesting "^7.0.0" - postcss-overflow-shorthand "^2.0.0" - postcss-page-break "^2.0.0" - postcss-place "^4.0.1" - postcss-pseudo-class-any-link "^6.0.0" - postcss-replace-overflow-wrap "^3.0.0" - postcss-selector-matches "^4.0.0" - postcss-selector-not "^4.0.0" - -postcss-pseudo-class-any-link@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" - integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-reduce-idents@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-4.0.2.tgz#30447a6ec20941e78e21bd4482a11f569c4f455b" - integrity sha512-Tz70Ri10TclPoCtFfftjFVddx3fZGUkr0dEDbIEfbYhFUOFQZZ77TEqRrU0e6TvAvF+Wa5VVzYTpFpq0uwFFzw== - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== - dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== +postcss-reduce-transforms@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.0.tgz#5c820f71fbd4eec82b323523642b7b2d1c7d29ef" + integrity sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw== dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-replace-overflow-wrap@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" - integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== - dependencies: - postcss "^7.0.2" - -postcss-selector-matches@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" - integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-not@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" - integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-parser@^3.0.0: +postcss-selector-parser@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== @@ -7624,15 +6540,6 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" @@ -7643,80 +6550,53 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: uniq "^1.0.1" util-deprecate "^1.0.2" -postcss-sort-media-queries@^1.7.26: - version "1.31.21" - resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-1.31.21.tgz#3225ec6eb490402602284ac99963b80461783cee" - integrity sha512-h+HbXXfOVFeLvCJOzl/Z9SqQ25MNpG/73k71756ftisaaJy75h06/Dn6KOwC4OCMN10ewT2PXMzHV03JNKwBbg== +postcss-sort-media-queries@^3.8.9: + version "3.10.11" + resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-3.10.11.tgz#9e06c220c752c69d3ea4a6d55ac7d4960e201c4a" + integrity sha512-78Ak5YSnalr+UTdZa2OCSNAxvEnHg3GRqWccStljJW7MqeU0cJtMA5OzaMmn+upM+iI5vykWzibVEAYaaAlSzw== dependencies: - postcss "^7.0.27" - sort-css-media-queries "1.5.0" + sort-css-media-queries "1.5.4" -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== +postcss-svgo@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.0.tgz#c8d806e573394ab24f1e233cac5be4c199e9f1b2" + integrity sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA== dependencies: - is-svg "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" + postcss-value-parser "^4.1.0" + svgo "^2.3.0" -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== +postcss-unique-selectors@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.0.tgz#17856278f6c38d024defc9694d568bb09dd7f771" + integrity sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w== dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.2" uniqs "^2.0.0" -postcss-value-parser@^3.0.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" - integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== +postcss-zindex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.0.0.tgz#ffed3576b5a9f0001a9d78fdc075466e1da1839c" + integrity sha512-thJp90qNZedxzfljsAnu7V35L/Zue/nVvWzPDLKZuqHmwDuy1vd3xkFVYfEa8WZZQaetvHtsi3uwjVD3UJAVeg== dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-zindex@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-4.0.1.tgz#8db6a4cec3111e5d3fd99ea70abeda61873d10c1" - integrity sha512-d/8BlQcUdEugZNRM9AdCA2V4fqREUtn/wcixLN3L6ITgc2P/FMcVVYz8QZkhItWT9NB5qr8wuN2dJCE4/+dlrA== - dependencies: - has "^1.0.0" - postcss "^7.0.0" + has "^1.0.3" uniqs "^2.0.0" -postcss@^6.0.23: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== +postcss@^8.2.10, postcss@^8.2.4, postcss@^8.2.9: + version "8.2.15" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" + integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== dependencies: - chalk "^2.4.1" + colorette "^1.2.2" + nanoid "^3.1.23" source-map "^0.6.1" - supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" - integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -postcss@^8.2.7, postcss@^8.2.8: +postcss@^8.2.8: version "8.2.8" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== @@ -7725,11 +6605,6 @@ postcss@^8.2.7, postcss@^8.2.8: nanoid "^3.1.20" source-map "^0.6.1" -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -7765,16 +6640,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -7819,26 +6684,6 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -7847,21 +6692,12 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4, punycode@^1.3.2: +punycode@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= @@ -7893,19 +6729,6 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -7921,21 +6744,13 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: +randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - range-parser@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -8056,10 +6871,10 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== -react-loadable-ssr-addon@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon/-/react-loadable-ssr-addon-0.3.0.tgz#ae9b2d3b11721930f8d8255476d288c0e9f9290f" - integrity sha512-E+lnmDakV0k6ut6R2J77vurwCOwTKEwKlHs9S62G8ez+ujecLPcqjt3YAU8M58kIGjp2QjFlZ7F9QWkq/mr6Iw== +react-loadable-ssr-addon-v5-slorber@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883" + integrity sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A== dependencies: "@babel/runtime" "^7.10.3" @@ -8128,13 +6943,6 @@ react-textarea-autosize@^8.3.2: use-composed-ref "^1.0.0" use-latest "^1.0.0" -react-toggle@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.1.2.tgz#b00500832f925ad524356d909821821ae39f6c52" - integrity sha512-4Ohw31TuYQdhWfA6qlKafeXx3IOH7t4ZHhmRdwsm1fQREwOBGxJT+I22sgHqR/w8JRdk+AeMCJXPImEFSrNXow== - dependencies: - classnames "^2.2.5" - react@^16.10.2, react@^16.3.1: version "16.14.0" resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" @@ -8144,7 +6952,7 @@ react@^16.10.2, react@^16.3.1: object-assign "^4.1.1" prop-types "^15.6.2" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.1, readable-stream@^2.0.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -8157,7 +6965,7 @@ react@^16.10.2, react@^16.3.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: +readable-stream@^3.0.6, readable-stream@^3.1.1: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -8477,7 +7285,7 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -8491,24 +7299,21 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" +rtl-detect@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.3.tgz#42145b9a4f9cf0b94c4542aba90d57f0d18559bf" + integrity sha512-2sMcZO60tL9YDEFe24gqddg3hJ+xSmJFN8IExcQUxeHxQzydQrN6GHPL+yAWgzItXSI7es53hcZC9pJneuZDKA== -rtlcss@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-2.6.2.tgz#55b572b52c70015ba6e03d497e5c5cb8137104b4" - integrity sha512-06LFAr+GAPo+BvaynsXRfoYTJvSaWRyOhURCQ7aeI1MKph9meM222F+Zkt3bDamyHHJuGi3VPtiRkpyswmQbGA== +rtlcss@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-3.1.2.tgz#4800d3d03525791a720f676a8ad2c6acf8efdfb2" + integrity sha512-b04YSX37siupPOWUEguEBReWX2w4QT89C0PI9g2JzZycbq7zrgPmTr1DA1pizSWpKRFdCjjnrx/SSvU4fOHmGg== dependencies: - "@choojs/findup" "^0.2.1" - chalk "^2.4.2" - mkdirp "^0.5.1" - postcss "^6.0.23" - strip-json-comments "^2.0.0" + chalk "^4.1.0" + find-up "^5.0.0" + mkdirp "^1.0.4" + postcss "^8.2.4" + strip-json-comments "^3.1.1" run-parallel@^1.1.9: version "1.2.0" @@ -8517,13 +7322,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - rxjs@^6.6.3: version "6.6.6" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" @@ -8536,7 +7334,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8548,7 +7346,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8575,7 +7373,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.0.0, schema-utils@^2.6.5: +schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -8666,13 +7464,6 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - serialize-javascript@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" @@ -8732,7 +7523,7 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -8747,13 +7538,12 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + kind-of "^6.0.2" shebang-command@^1.2.0: version "1.2.0" @@ -8885,19 +7675,12 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" -sort-css-media-queries@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.0.tgz#8f605ad372caad0b81be010311882c046e738093" - integrity sha512-QofNE7CEVH1AKdhS7L9IPbV9UtyQYNXyw++8lC+xG6iOLlpzsmncZRiKbihTAESvZ8wOhwnPoesHbMrehrQyyw== +sort-css-media-queries@1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.4.tgz#24182b12002a13d01ba943ddf74f5098d7c244ce" + integrity sha512-YP5W/h4Sid/YP7Lp87ejJ5jP13/Mtqt2vx33XyhO+IAugKlufRPbOrPlIiEUuxmpNBSBd3EeeQpFhdu3RfI2Ag== -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: +source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== @@ -8936,7 +7719,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3, source-map@~0.7.2: +source-map@~0.7.2: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== @@ -8981,20 +7764,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" - -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -9025,43 +7794,6 @@ std-env@^2.2.1: dependencies: ci-info "^3.0.0" -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -9096,7 +7828,7 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -9155,7 +7887,12 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -9167,16 +7904,15 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== +stylehacks@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.0.tgz#c49b0b2cf9917fe37dc030b96a4c34698b932933" + integrity sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" -supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -9202,7 +7938,7 @@ svg-parser@^2.0.2: resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== -svgo@^1.0.0, svgo@^1.2.2: +svgo@^1.2.2: version "1.3.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== @@ -9221,54 +7957,42 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -tapable@^1.0.0, tapable@^1.1.3: +svgo@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" + integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== + dependencies: + "@trysound/sax" "0.1.1" + chalk "^4.1.0" + commander "^7.1.0" + css-select "^3.1.2" + css-tree "^1.1.2" + csso "^4.2.0" + stable "^0.1.8" + +tapable@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== -terser-webpack-plugin@^1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" - integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== +terser-webpack-plugin@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz#51d295eb7cc56785a67a372575fdc46e42d5c20c" + integrity sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q== dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser-webpack-plugin@^4.1.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" - integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== - dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - jest-worker "^26.5.0" - p-limit "^3.0.2" + jest-worker "^26.6.2" + p-limit "^3.1.0" schema-utils "^3.0.0" serialize-javascript "^5.0.1" source-map "^0.6.1" - terser "^5.3.4" - webpack-sources "^1.4.3" + terser "^5.7.0" -terser@^4.1.2, terser@^4.6.3: +terser@^4.6.3: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -9277,10 +8001,10 @@ terser@^4.1.2, terser@^4.6.3: source-map "~0.6.1" source-map-support "~0.5.12" -terser@^5.3.4: - version "5.6.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.1.tgz#a48eeac5300c0a09b36854bf90d9c26fb201973c" - integrity sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw== +terser@^5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" + integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== dependencies: commander "^2.20.0" source-map "~0.7.2" @@ -9291,26 +8015,11 @@ text-table@0.2.0, text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== -timers-browserify@^2.0.4: - version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" - integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== - dependencies: - setimmediate "^1.0.4" - timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" @@ -9331,11 +8040,6 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -9408,11 +8112,6 @@ ts-essentials@^2.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== -ts-pnp@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" - integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== - tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -9423,10 +8122,10 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +tslib@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== type-fest@^0.20.2: version "0.20.2" @@ -9453,11 +8152,6 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - ua-parser-js@^0.7.18: version "0.7.25" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.25.tgz#67689fa263a87a52dabbc251ede89891f59156ce" @@ -9547,20 +8241,6 @@ uniqs@^2.0.0: resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -9747,14 +8427,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" @@ -9765,20 +8437,6 @@ util.promisify@~1.0.0: has-symbols "^1.0.1" object.getownpropertydescriptors "^2.1.0" -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -9809,7 +8467,7 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.0: +vendors@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== @@ -9837,11 +8495,6 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - wait-on@^5.2.1: version "5.3.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.3.0.tgz#584e17d4b3fe7b46ac2b9f8e5e102c005c2776c7" @@ -9853,23 +8506,13 @@ wait-on@^5.2.1: minimist "^1.2.5" rxjs "^6.6.3" -watchpack-chokidar2@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" - integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== - dependencies: - chokidar "^2.1.8" - -watchpack@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" - integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== +watchpack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== dependencies: + glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" - neo-async "^2.5.0" - optionalDependencies: - chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.1" wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" @@ -9956,14 +8599,15 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-merge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== +webpack-merge@^5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" + integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== dependencies: - lodash "^4.17.15" + clone-deep "^4.0.1" + wildcard "^2.0.0" -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.1.0, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -9971,34 +8615,42 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.44.1: - version "4.46.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" - integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== +webpack-sources@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" + integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/wasm-edit" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - acorn "^6.4.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack@^5.28.0: + version "5.37.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.1.tgz#2deb5acd350583c1ab9338471f323381b0b0c14b" + integrity sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.47" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/wasm-edit" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" + acorn "^8.2.1" + browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.5.0" - eslint-scope "^4.0.3" + enhanced-resolve "^5.8.0" + es-module-lexer "^0.4.0" + eslint-scope "^5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.3" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.7.4" - webpack-sources "^1.4.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.0.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.1" + watchpack "^2.0.0" + webpack-sources "^2.1.1" webpackbar@^5.0.0-3: version "5.0.0-3" @@ -10065,12 +8717,10 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== worker-rpc@^0.1.0: version "0.1.1" @@ -10136,7 +8786,7 @@ xml-js@^1.6.11: dependencies: sax "^1.2.4" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -10146,11 +8796,6 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From c0aa4ff5870583b708a1bf1459328fb56a522472 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 20 May 2021 11:27:41 +0200 Subject: [PATCH 029/106] adding dependencies, macos improvements --- website/docs/dev_build.md | 112 +++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 14 deletions(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index 2ee0d9a052..5fcda2b36c 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -188,6 +188,8 @@ To build pype on MacOS you wil need: - **[Homebrew](https://brew.sh)** - easy way of installing everything necessary. - **[CMake](https://cmake.org/)** to build some external OpenPype dependencies. - **XCode Command Line Tools** (or some other build system) +- **[create-dmg](https://formulae.brew.sh/formula/create-dmg)** to create dmg image from application +bundle. 1) Install **Homebrew**: ```shell @@ -223,23 +225,70 @@ $ pyenv install 3.7.9 $ pyenv local 3.7.9 ``` +6) Install `create-dmg` +```shell +$ brew install create-dmg +``` + #### To build Pype: 1. Run `./tools/create_env.sh` to create virtual environment in `./venv` -2. Run `./tools/build.sh` to build Pype executables in `./build/` +2. Run `./tools/build.sh` to build OpenPype Application bundle in `./build/` + +#### -## Script tools +## Adding dependencies +### Python modules +If you are extending OpenPype and you need some new modules not included, you can add them +to `pyproject.toml` to `[tool.poetry.dependencies]` section. +```toml title="/pyproject.toml" +[tool.poetry.dependencies] +python = "3.7.*" +aiohttp = "^3.7" +aiohttp_json_rpc = "*" # TVPaint server +acre = { git = "https://github.com/pypeclub/acre.git" } +opentimelineio = { version = "0.14.0.dev1", source = "openpype" } +#... +``` +It is useful to add comment to it so others can see why this was added and where it is used. +As you can see you can add git repositories or custom wheels (those must be +added to `[[tool.poetry.source]]` section). + +To add something only for specific platform, you can use markers like: +```toml title="Install pywin32 only on Windows" +pywin32 = { version = "300", markers = "sys_platform == 'win32'" } +``` + +For more information see [Poetry documentation](https://python-poetry.org/docs/dependency-specification/). + +### Binary dependencies +To add some binary tool or something that doesn't fit standard Python distribution methods, you +can use [fetch_thirdparty_libs](#fetch_thirdparty_libs) script. It will take things defined in +`pyproject.toml` under `[openpype]` section like this: + +```toml title="/pyproject.toml" +[openpype] + +[openpype.thirdparty.ffmpeg.windows] +url = "https://distribute.openpype.io/thirdparty/ffmpeg-4.4-windows.zip" +hash = "dd51ba29d64ee238e7c4c3c7301b19754c3f0ee2e2a729c20a0e2789e72db925" +# ... +``` +This defines FFMpeg for Windows. It will be downloaded from specified url, its checksum will +be validated (it's sha256) and it will be extracted to `/vendor/bin/ffmpeg/windows` (partly taken +from its section name). + +## Script tools (replace extension with the one for your system - `ps1` for windows, `sh` for linux/macos) ### build - This will build OpenPype to `build` directory. If virtual environment is not created yet, it will install [Poetry](https://python-poetry.org/) and using it download and install necessary -packages needed for build. It is recommended that you run [fetch_thirdparty_libs](#fetch-thirdparty-libs) +packages needed for build. It is recommended that you run [fetch_thirdparty_libs](#fetch_thirdparty_libs) to download FFMpeg, OpenImageIO and others that are needed by OpenPype and are copied during the build. #### Arguments @@ -247,7 +296,6 @@ to download FFMpeg, OpenImageIO and others that are needed by OpenPype and are c feature changes in submodules. ### build_win_installer - This will take already existing build in `build` directory and create executable installer using [Inno Setup](https://jrsoftware.org/isinfo.php) and definitions in `./inno_setup.iss`. You need OpenPype build using [build script](#build), Inno Setup installed and in PATH before running this script. @@ -257,7 +305,6 @@ Windows only ::: ### create_env - Script to create virtual environment for build and running OpenPype from sources. It is using [Poetry](https://python-poetry.org/). All dependencies are defined in `pyproject.toml`, resolved by Poetry into `poetry.lock` file and then installed. Running this script without Poetry will download @@ -268,41 +315,78 @@ to update packages version, just run `poetry update` or delete lock file. `--verbose` - to increase verbosity of Poetry. This can be useful for debugging package conflicts. ### create_zip - Script to create packaged OpenPype version from current sources. This will strip developer stuff and package it into zip that can be used for [auto-updates for studio wide distributions](admin_distribute#automatic-updates), etc. +Same as: +```shell +poetry run python ./tools/create_zip.py +``` ### docker_build.sh - Script to build OpenPype on [Docker](https://www.docker.com/) enabled systems - usually Linux and Windows with [Docker Desktop](https://docs.docker.com/docker-for-windows/install/) and [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) (WSL) installed. It must be run with administrative privileges - `sudo ./docker_build.sh`. -It will use Centos 7 base image to build OpenPype. You'll see your build in `./build` folder. +It will use **Centos 7** base image to build OpenPype. You'll see your build in `./build` folder. ### fetch_thirdparty_libs - This script will download necessary tools for OpenPype defined in `pyproject.toml` like FFMpeg, OpenImageIO and USD libraries and put them to `./vendor/bin`. Those are then included in build. Running it will overwrite everything on their respective paths. +Same as: +```shell +poetry run python ./tools/fetch_thirdparty_libs.py +``` ### make_docs - Script will run [sphinx](https://www.sphinx-doc.org/) to build api documentation in html. You should see it then under `./docs/build/html`. ### run_documentation - This will start up [Docusaurus](https://docusaurus.io/) to display OpenPype user documentation. Useful for offline browsing or editing documentation itself. You will need [Node.js](https://nodejs.org/) and [Yarn](https://yarnpkg.com/) to run this script. After executing it, you'll see new browser window with current OpenPype documentation. +Same as: +```shell +./website/yarn start +``` ### run_mongo - Helper script to run local mongoDB server for development and testing. You will need [mongoDB server](https://www.mongodb.com/try/download/community) installed in standard location or in PATH (standard location works only on Windows). It will start by default on port `2707` and -it will put its db files to `../mongo_db_data` relative to OpenPype sources. \ No newline at end of file +it will put its db files to `../mongo_db_data` relative to OpenPype sources. + +### run_project_manager +Helper script to start OpenPype Project Manager tool. +Same as: +```shell +poetry run python start.py projectmanager +``` + +### run_settings +Helper script to open OpenPype Settings UI. +Same as: +```shell +poetry run python start.py settings --dev +``` + +### run_tests +Runs OpenPype test suite. + +### run_tray +Helper script to run OpenPype Tray. +Same as: +```shell +poetry run python start.py tray +``` + +### update_submodules +Helper script to update OpenPype git submodules. +Same as: +```shell +git submodule update --recursive --remote +``` From a72a892a9fc5f520525fb903ffba8d7ecd8706f3 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 20 May 2021 11:30:48 +0200 Subject: [PATCH 030/106] remove empty header --- website/docs/dev_build.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index 5fcda2b36c..c5bf1d5c47 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -232,10 +232,8 @@ $ brew install create-dmg #### To build Pype: -1. Run `./tools/create_env.sh` to create virtual environment in `./venv` -2. Run `./tools/build.sh` to build OpenPype Application bundle in `./build/` - -#### +1. Run `./tools/create_env.sh` to create virtual environment in `./venv`. +2. Run `./tools/build.sh` to build OpenPype Application bundle in `./build/`. From 9ff9aab0292fd5defb6d49134a730ea5f6bc80ce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:09:15 +0200 Subject: [PATCH 031/106] implemented alpha slider that can move pointer on click --- .../widgets/color_widgets/color_inputs.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index a4409988b2..b8737afd99 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -25,6 +25,40 @@ QSlider::handle:horizontal:hover { }""" +class AlphaSlider(QtWidgets.QSlider): + def __init__(self, *args, **kwargs): + super(AlphaSlider, self).__init__(*args, **kwargs) + self._mouse_clicked = False + self.setSingleStep(1) + self.setMinimum(0) + self.setMaximum(255) + self.setValue(255) + + self.setStyleSheet(slide_style) + + def mousePressEvent(self, event): + self._mouse_clicked = True + if event.button() == QtCore.Qt.LeftButton: + self._set_value_to_pos(event.pos().x()) + return event.accept() + return super(AlphaSlider, self).mousePressEvent(event) + + def _set_value_to_pos(self, pos_x): + value = ( + self.maximum() - self.minimum() + ) * pos_x / self.width() + self.minimum() + self.setValue(value) + + def mouseMoveEvent(self, event): + if self._mouse_clicked: + self._set_value_to_pos(event.pos().x()) + super(AlphaSlider, self).mouseMoveEvent(event) + + def mouseReleaseEvent(self, event): + self._mouse_clicked = True + super(AlphaSlider, self).mouseReleaseEvent(event) + + class AlphaInputs(QtWidgets.QWidget): alpha_changed = QtCore.Signal(int) From ce6c129f9ea27002d9d7b4d4a1a120776b61120a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:18:30 +0200 Subject: [PATCH 032/106] removed labels from input widgets and set content's margines --- openpype/widgets/color_widgets/color_inputs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index b8737afd99..f19e28ba1d 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -183,7 +183,7 @@ class RGBInputs(QtWidgets.QWidget): input_blue.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("RGB", self), 0) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(input_red, 1) layout.addWidget(input_green, 1) layout.addWidget(input_blue, 1) @@ -265,7 +265,7 @@ class CMYKInputs(QtWidgets.QWidget): input_black.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("CMYK", self)) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(input_cyan, 1) layout.addWidget(input_magenta, 1) layout.addWidget(input_yellow, 1) @@ -331,7 +331,7 @@ class HEXInputs(QtWidgets.QWidget): input_field = QtWidgets.QLineEdit(self) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("HEX", self), 0) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(input_field, 1) input_field.textChanged.connect(self._on_change) @@ -392,7 +392,7 @@ class HSVInputs(QtWidgets.QWidget): input_val.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("HSV", self), 0) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(input_hue, 1) layout.addWidget(input_sat, 1) layout.addWidget(input_val, 1) @@ -466,7 +466,7 @@ class HSLInputs(QtWidgets.QWidget): input_light.setMaximum(255) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("HSL", self), 0) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(input_hue, 1) layout.addWidget(input_sat, 1) layout.addWidget(input_light, 1) From b9b18f34af3eef3d93dfb3f7e75b85385af8797b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:19:18 +0200 Subject: [PATCH 033/106] removed alpha slider from alpha inputs --- .../widgets/color_widgets/color_inputs.py | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index f19e28ba1d..9aa35021c2 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -68,18 +68,6 @@ class AlphaInputs(QtWidgets.QWidget): self._block_changes = False self.alpha_value = None - # Opacity slider - alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) - alpha_slider.setSingleStep(1) - alpha_slider.setMinimum(0) - alpha_slider.setMaximum(255) - alpha_slider.setStyleSheet(slide_style) - alpha_slider.setValue(255) - - inputs_widget = QtWidgets.QWidget(self) - inputs_layout = QtWidgets.QHBoxLayout(inputs_widget) - inputs_layout.setContentsMargins(0, 0, 0, 0) - percent_input = QtWidgets.QDoubleSpinBox(self) percent_input.setButtonSymbols(QtWidgets.QSpinBox.NoButtons) percent_input.setMinimum(0) @@ -91,21 +79,16 @@ class AlphaInputs(QtWidgets.QWidget): int_input.setMinimum(0) int_input.setMaximum(255) - inputs_layout.addWidget(int_input) - inputs_layout.addWidget(QtWidgets.QLabel("0-255")) - inputs_layout.addWidget(percent_input) - inputs_layout.addWidget(QtWidgets.QLabel("%")) + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(int_input) + layout.addWidget(QtWidgets.QLabel("0-255")) + layout.addWidget(percent_input) + layout.addWidget(QtWidgets.QLabel("%")) - layout = QtWidgets.QVBoxLayout(self) - layout.addWidget(QtWidgets.QLabel("Alpha", self)) - layout.addWidget(alpha_slider) - layout.addWidget(inputs_widget) - - alpha_slider.valueChanged.connect(self._on_slider_change) percent_input.valueChanged.connect(self._on_percent_change) int_input.valueChanged.connect(self._on_int_change) - self.alpha_slider = alpha_slider self.percent_input = percent_input self.int_input = int_input @@ -118,13 +101,6 @@ class AlphaInputs(QtWidgets.QWidget): self.update_alpha() - def _on_slider_change(self): - if self._block_changes: - return - self.alpha_value = self.alpha_slider.value() - self.alpha_changed.emit(self.alpha_value) - self.update_alpha() - def _on_percent_change(self): if self._block_changes: return @@ -142,10 +118,6 @@ class AlphaInputs(QtWidgets.QWidget): def update_alpha(self): self._block_changes = True - - if self.alpha_slider.value() != self.alpha_value: - self.alpha_slider.setValue(self.alpha_value) - if self.int_input.value() != self.alpha_value: self.int_input.setValue(self.alpha_value) From cbed588a75b8682f0ab3cbc9e4956df6dc29ec12 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:28:28 +0200 Subject: [PATCH 034/106] formatting changes --- openpype/widgets/color_widgets/color_inputs.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index 9aa35021c2..ddb832c655 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -4,13 +4,17 @@ from Qt import QtWidgets, QtCore, QtGui slide_style = """ QSlider::groove:horizontal { - background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #000, stop: 1 #fff); + background: qlineargradient( + x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #000, stop: 1 #fff + ); height: 8px; border-radius: 4px; } QSlider::handle:horizontal { - background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #ddd, stop:1 #bbb); + background: qlineargradient( + x1:0, y1:0, x2:1, y2:1, stop:0 #ddd, stop:1 #bbb + ); border: 1px solid #777; width: 8px; margin-top: -1px; @@ -19,7 +23,9 @@ QSlider::handle:horizontal { } QSlider::handle:horizontal:hover { - background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #eee, stop:1 #ddd); + background: qlineargradient( + x1:0, y1:0, x2:1, y2:1, stop:0 #eee, stop:1 #ddd + ); border: 1px solid #444;ff border-radius: 4px; }""" From 9f86bcff621298f82bdb11eda7d904ad3ada53ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:29:13 +0200 Subject: [PATCH 035/106] inputs are handled inside ColorPickerWidget --- .../color_widgets/color_picker_widget.py | 141 ++++++++++++------ 1 file changed, 93 insertions(+), 48 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 5786c529ed..7158a426a4 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -6,7 +6,13 @@ from .color_view import ColorViewer from .color_screen_pick import PickScreenColorWidget from .color_inputs import ( ColorInputsWidget, - AlphaInputs + AlphaSlider, + AlphaInputs, + HEXInputs, + RGBInputs, + HSLInputs, + HSVInputs, + CMYKInputs ) @@ -16,24 +22,27 @@ class ColorPickerWidget(QtWidgets.QWidget): def __init__(self, color=None, parent=None): super(ColorPickerWidget, self).__init__(parent) - # Eye picked widget - pick_widget = PickScreenColorWidget() - - # Color utils - utils_widget = QtWidgets.QWidget(self) - utils_layout = QtWidgets.QVBoxLayout(utils_widget) - - bottom_utils_widget = QtWidgets.QWidget(utils_widget) + top_part = QtWidgets.QWidget(self) + left_side = QtWidgets.QWidget(top_part) # Color triangle - color_triangle = QtColorTriangle(utils_widget) + color_triangle = QtColorTriangle(left_side) - # Color preview - color_view = ColorViewer(bottom_utils_widget) - color_view.setMaximumHeight(50) + alpha_slider = AlphaSlider(QtCore.Qt.Horizontal, left_side) + + left_layout = QtWidgets.QVBoxLayout(left_side) + left_layout.setContentsMargins(0, 0, 0, 0) + left_layout.addWidget(color_triangle) + left_layout.addWidget(alpha_slider) + + right_side = QtWidgets.QWidget(top_part) + + # Eye picked widget + pick_widget = PickScreenColorWidget() + pick_widget.setMaximumHeight(50) # Color pick button - btn_pick_color = QtWidgets.QPushButton(bottom_utils_widget) + btn_pick_color = QtWidgets.QPushButton(right_side) icon_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "eyedropper.png" @@ -41,50 +50,62 @@ class ColorPickerWidget(QtWidgets.QWidget): btn_pick_color.setIcon(QtGui.QIcon(icon_path)) btn_pick_color.setToolTip("Pick a color") - # Color inputs widget - color_inputs = ColorInputsWidget(self) + # Color preview + color_view = ColorViewer(right_side) + color_view.setMaximumHeight(50) - # Alpha inputs - alpha_input_wrapper_widget = QtWidgets.QWidget(self) - alpha_input_wrapper_layout = QtWidgets.QVBoxLayout( - alpha_input_wrapper_widget - ) + row = 0 + right_layout = QtWidgets.QGridLayout(right_side) + right_layout.setContentsMargins(0, 0, 0, 0) + right_layout.addWidget(btn_pick_color, row, 0) + right_layout.addWidget(color_view, row, 1) - alpha_inputs = AlphaInputs(alpha_input_wrapper_widget) - alpha_input_wrapper_layout.addWidget(alpha_inputs) - alpha_input_wrapper_layout.addWidget(QtWidgets.QWidget(), 1) + color_inputs_color = QtGui.QColor() + col_inputs_by_label = [ + ("HEX", HEXInputs(color_inputs_color, right_side)), + ("RGB", RGBInputs(color_inputs_color, right_side)), + ("HSL", HSLInputs(color_inputs_color, right_side)), + ("HSV", HSVInputs(color_inputs_color, right_side)) + ] + color_input_fields = [] + for label, input_field in col_inputs_by_label: + row += 1 + right_layout.addWidget(QtWidgets.QLabel(label, right_side), row, 0) + right_layout.addWidget(input_field, row, 1) + input_field.value_changed.connect( + self._on_color_input_value_change + ) + color_input_fields.append(input_field) - bottom_utils_layout = QtWidgets.QHBoxLayout(bottom_utils_widget) - bottom_utils_layout.setContentsMargins(0, 0, 0, 0) - bottom_utils_layout.addWidget(color_view, 1) - bottom_utils_layout.addWidget(btn_pick_color, 0) - - utils_layout.addWidget(bottom_utils_widget, 0) - utils_layout.addWidget(color_triangle, 1) + row += 1 + alpha_inputs = AlphaInputs(right_side) + right_layout.addWidget(QtWidgets.QLabel("Alpha", right_side), row, 0) + right_layout.addWidget(alpha_inputs, row, 1) layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(utils_widget, 1) - layout.addWidget(color_inputs, 0) - layout.addWidget(alpha_input_wrapper_widget, 0) + layout.setSpacing(5) + layout.addWidget(left_side, 1) + layout.addWidget(right_side, 0) color_view.set_color(color_triangle.cur_color) - color_inputs.set_color(color_triangle.cur_color) color_triangle.color_changed.connect(self.triangle_color_changed) + alpha_slider.valueChanged.connect(self._on_alpha_slider_change) pick_widget.color_selected.connect(self.on_color_change) - color_inputs.color_changed.connect(self.on_color_change) - alpha_inputs.alpha_changed.connect(self.alpha_changed) + alpha_inputs.alpha_changed.connect(self._on_alpha_inputs_changed) btn_pick_color.released.connect(self.pick_color) + self.color_input_fields = color_input_fields + self.color_inputs_color = color_inputs_color + self.pick_widget = pick_widget - self.utils_widget = utils_widget - self.bottom_utils_widget = bottom_utils_widget self.color_triangle = color_triangle + self.alpha_slider = alpha_slider + self.color_view = color_view - self.btn_pick_color = btn_pick_color - self.color_inputs = color_inputs self.alpha_inputs = alpha_inputs + self.btn_pick_color = btn_pick_color if color: self.set_color(color) @@ -92,9 +113,7 @@ class ColorPickerWidget(QtWidgets.QWidget): def showEvent(self, event): super(ColorPickerWidget, self).showEvent(event) - triangle_width = int(( - self.utils_widget.height() - self.bottom_utils_widget.height() - ) / 5 * 4) + triangle_width = int(self.height() / 5 * 4) self.color_triangle.setMinimumWidth(triangle_width) def color(self): @@ -109,12 +128,38 @@ class ColorPickerWidget(QtWidgets.QWidget): def triangle_color_changed(self, color): self.color_view.set_color(color) - self.color_inputs.set_color(color) + if self.color_inputs_color != color: + self.color_inputs_color.setRgb( + color.red(), color.green(), color.blue() + ) + for color_input in self.color_input_fields: + color_input.color_changed() def on_color_change(self, color): self.color_view.set_color(color) self.color_triangle.set_color(color) - self.color_inputs.set_color(color) + if self.color_inputs_color != color: + self.color_inputs_color.setRgb( + color.red(), color.green(), color.blue() + ) + for color_input in self.color_input_fields: + color_input.color_changed() - def alpha_changed(self, alpha): - self.color_view.set_alpha(alpha) + def _on_color_input_value_change(self): + for input_field in self.color_input_fields: + input_field.color_changed() + self.on_color_change(QtGui.QColor(self.color_inputs_color)) + + def alpha_changed(self, value): + self.color_view.set_alpha(value) + if self.alpha_slider.value() != value: + self.alpha_slider.setValue(value) + + if self.alpha_inputs.alpha_value != value: + self.alpha_inputs.set_alpha(value) + + def _on_alpha_inputs_changed(self, value): + self.alpha_changed(value) + + def _on_alpha_slider_change(self, value): + self.alpha_changed(value) From 3245e97884c724037de5a14c1ba130f5d818857e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 12:29:37 +0200 Subject: [PATCH 036/106] checkerboard can be drawn out of ColorViewer --- openpype/widgets/color_widgets/color_view.py | 52 +++++++++++--------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/openpype/widgets/color_widgets/color_view.py b/openpype/widgets/color_widgets/color_view.py index a4393a6625..d6d7f0a666 100644 --- a/openpype/widgets/color_widgets/color_view.py +++ b/openpype/widgets/color_widgets/color_view.py @@ -1,6 +1,34 @@ from Qt import QtWidgets, QtCore, QtGui +def draw_checkerboard_tile(piece_size=None, color_1=None, color_2=None): + if piece_size is None: + piece_size = 7 + + if color_1 is None: + color_1 = QtGui.QColor(188, 188, 188) + + if color_2 is None: + color_2 = QtGui.QColor(90, 90, 90) + + pix = QtGui.QPixmap(piece_size * 2, piece_size * 2) + pix_painter = QtGui.QPainter(pix) + + rect = QtCore.QRect( + 0, 0, piece_size, piece_size + ) + pix_painter.fillRect(rect, color_1) + rect.moveTo(piece_size, piece_size) + pix_painter.fillRect(rect, color_1) + rect.moveTo(piece_size, 0) + pix_painter.fillRect(rect, color_2) + rect.moveTo(0, piece_size) + pix_painter.fillRect(rect, color_2) + pix_painter.end() + + return pix + + class ColorViewer(QtWidgets.QWidget): def __init__(self, parent=None): super(ColorViewer, self).__init__(parent) @@ -14,29 +42,7 @@ class ColorViewer(QtWidgets.QWidget): def checkerboard(self): if not self._checkerboard: - checkboard_piece_size = 10 - color_1 = QtGui.QColor(188, 188, 188) - color_2 = QtGui.QColor(90, 90, 90) - - pix = QtGui.QPixmap( - checkboard_piece_size * 2, - checkboard_piece_size * 2 - ) - pix_painter = QtGui.QPainter(pix) - - rect = QtCore.QRect( - 0, 0, checkboard_piece_size, checkboard_piece_size - ) - pix_painter.fillRect(rect, color_1) - rect.moveTo(checkboard_piece_size, checkboard_piece_size) - pix_painter.fillRect(rect, color_1) - rect.moveTo(checkboard_piece_size, 0) - pix_painter.fillRect(rect, color_2) - rect.moveTo(0, checkboard_piece_size) - pix_painter.fillRect(rect, color_2) - pix_painter.end() - self._checkerboard = pix - + self._checkerboard = draw_checkerboard_tile() return self._checkerboard def color(self): From c4ec9cb7f1f0d5a2798fe1dc9acd902e2ca84095 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:10:49 +0200 Subject: [PATCH 037/106] use draw_checkerboard_tile to draw checkerboard --- .../tools/settings/settings/color_widget.py | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index 7b534b749c..b84c8dd9cc 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -2,7 +2,10 @@ from Qt import QtWidgets, QtCore, QtGui from .item_widgets import InputWidget -from openpype.widgets.color_widgets import ColorPickerWidget +from openpype.widgets.color_widgets import ( + ColorPickerWidget, + draw_checkerboard_tile +) class ColorWidget(InputWidget): @@ -77,29 +80,7 @@ class ColorViewer(QtWidgets.QWidget): def checkerboard(self): if not self._checkerboard: - checkboard_piece_size = 10 - color_1 = QtGui.QColor(188, 188, 188) - color_2 = QtGui.QColor(90, 90, 90) - - pix = QtGui.QPixmap( - checkboard_piece_size * 2, - checkboard_piece_size * 2 - ) - pix_painter = QtGui.QPainter(pix) - - rect = QtCore.QRect( - 0, 0, checkboard_piece_size, checkboard_piece_size - ) - pix_painter.fillRect(rect, color_1) - rect.moveTo(checkboard_piece_size, checkboard_piece_size) - pix_painter.fillRect(rect, color_1) - rect.moveTo(checkboard_piece_size, 0) - pix_painter.fillRect(rect, color_2) - rect.moveTo(0, checkboard_piece_size) - pix_painter.fillRect(rect, color_2) - pix_painter.end() - self._checkerboard = pix - + self._checkerboard = draw_checkerboard_tile() return self._checkerboard def color(self): From 5680f96a499a59844d84b591d39c3b52cb431242 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:13:10 +0200 Subject: [PATCH 038/106] changed how triangle size is set --- openpype/widgets/color_widgets/color_picker_widget.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 7158a426a4..725d0b374e 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -107,14 +107,21 @@ class ColorPickerWidget(QtWidgets.QWidget): self.alpha_inputs = alpha_inputs self.btn_pick_color = btn_pick_color + self._minimum_size_set = False + if color: self.set_color(color) self.alpha_changed(color.alpha()) def showEvent(self, event): super(ColorPickerWidget, self).showEvent(event) - triangle_width = int(self.height() / 5 * 4) - self.color_triangle.setMinimumWidth(triangle_width) + if self._minimum_size_set: + return + + triangle_size = max(int(self.width() / 5 * 3), 180) + self.color_triangle.setMinimumWidth(triangle_size) + self.color_triangle.setMinimumHeight(triangle_size) + self._minimum_size_set = True def color(self): return self.color_view.color() From 20c119f3555ee267c5784ce1e8d4e7db8d65ae9a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:13:20 +0200 Subject: [PATCH 039/106] added draw_checkerboard_tile to init file --- openpype/widgets/color_widgets/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/widgets/color_widgets/__init__.py b/openpype/widgets/color_widgets/__init__.py index 3423e26cf8..324b23543d 100644 --- a/openpype/widgets/color_widgets/__init__.py +++ b/openpype/widgets/color_widgets/__init__.py @@ -1,6 +1,14 @@ -from .color_picker_widget import ColorPickerWidget +from .color_picker_widget import ( + ColorPickerWidget +) + +from .color_view import ( + draw_checkerboard_tile +) __all__ = ( "ColorPickerWidget", + + "draw_checkerboard_tile" ) From 4bb432284fe4dea23bb61e2272d84d952e8ff4a3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:13:39 +0200 Subject: [PATCH 040/106] added stretch at the end of gridlayout --- openpype/widgets/color_widgets/color_picker_widget.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 725d0b374e..3b1eb1aca0 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -82,6 +82,9 @@ class ColorPickerWidget(QtWidgets.QWidget): right_layout.addWidget(QtWidgets.QLabel("Alpha", right_side), row, 0) right_layout.addWidget(alpha_inputs, row, 1) + row += 1 + right_layout.setRowStretch(row, 1) + layout = QtWidgets.QHBoxLayout(self) layout.setSpacing(5) layout.addWidget(left_side, 1) From a688a1510e8dcb439267308112a72e81e61c546c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:13:50 +0200 Subject: [PATCH 041/106] alpha slider has proxy --- openpype/widgets/color_widgets/color_picker_widget.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 3b1eb1aca0..117e1c9aef 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -28,7 +28,12 @@ class ColorPickerWidget(QtWidgets.QWidget): # Color triangle color_triangle = QtColorTriangle(left_side) - alpha_slider = AlphaSlider(QtCore.Qt.Horizontal, left_side) + alpha_slider_proxy = QtWidgets.QWidget(left_side) + alpha_slider = AlphaSlider(QtCore.Qt.Horizontal, alpha_slider_proxy) + + alpha_slider_layout = QtWidgets.QHBoxLayout(alpha_slider_proxy) + alpha_slider_layout.setContentsMargins(5, 5, 5, 5) + alpha_slider_layout.addWidget(alpha_slider, 1) left_layout = QtWidgets.QVBoxLayout(left_side) left_layout.setContentsMargins(0, 0, 0, 0) From e40847f61ff49b1ae47bce8b471f87ec98352852 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:14:05 +0200 Subject: [PATCH 042/106] added stretched of triangle and alpha slider --- openpype/widgets/color_widgets/color_picker_widget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 117e1c9aef..23c06929c0 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -37,8 +37,8 @@ class ColorPickerWidget(QtWidgets.QWidget): left_layout = QtWidgets.QVBoxLayout(left_side) left_layout.setContentsMargins(0, 0, 0, 0) - left_layout.addWidget(color_triangle) - left_layout.addWidget(alpha_slider) + left_layout.addWidget(color_triangle, 1) + left_layout.addWidget(alpha_slider_proxy, 0) right_side = QtWidgets.QWidget(top_part) From 97c1a14de48b48713bee78c1248573bf0f969e7e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 13:14:17 +0200 Subject: [PATCH 043/106] added spacing between left and right widget --- openpype/widgets/color_widgets/color_picker_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 23c06929c0..40e20496f6 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -91,7 +91,7 @@ class ColorPickerWidget(QtWidgets.QWidget): right_layout.setRowStretch(row, 1) layout = QtWidgets.QHBoxLayout(self) - layout.setSpacing(5) + layout.setSpacing(20) layout.addWidget(left_side, 1) layout.addWidget(right_side, 0) From 12a910aaca3c386d392e5322ede1b9c288bf2359 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 20 May 2021 13:50:21 +0200 Subject: [PATCH 044/106] fix create env order and public git address --- website/docs/dev_build.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index c5bf1d5c47..2899dbd754 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -26,6 +26,11 @@ This is outline of build steps. Most of them are done automatically via scripts: - On Mac application bundle and dmg image will be created from built code. - On Windows, you can create executable installer with `./tools/build_win_installer.ps1` +### Clone OpenPype repository: +```powershell +git clone --recurse-submodules https://github.com/pypeclub/OpenPype.git +``` + ## Platform specific steps @@ -233,7 +235,8 @@ $ brew install create-dmg #### To build Pype: 1. Run `./tools/create_env.sh` to create virtual environment in `./venv`. -2. Run `./tools/build.sh` to build OpenPype Application bundle in `./build/`. +2. Run `./tools/fetch_thirdparty_libs.sh` to get **ffmpeg**, **oiio** and other tools needed. +3. Run `./tools/build.sh` to build OpenPype Application bundle in `./build/`. From a097f9969663a5ed0c7721dbf490277d6873beb0 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 20 May 2021 14:37:47 +0200 Subject: [PATCH 045/106] fix yarn example --- website/docs/dev_build.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/dev_build.md b/website/docs/dev_build.md index 2899dbd754..2c4bd1e9af 100644 --- a/website/docs/dev_build.md +++ b/website/docs/dev_build.md @@ -352,7 +352,8 @@ and [Yarn](https://yarnpkg.com/) to run this script. After executing it, you'll browser window with current OpenPype documentation. Same as: ```shell -./website/yarn start +cd ./website +yarn start ``` ### run_mongo From 0579cb2983d32205deed83d778bd4fbbac3c44e7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 15:33:43 +0200 Subject: [PATCH 046/106] nicer alpha slider --- .../widgets/color_widgets/color_inputs.py | 90 ++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index ddb832c655..d3c801bc0f 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -1,6 +1,8 @@ import re from Qt import QtWidgets, QtCore, QtGui +from .color_view import draw_checkerboard_tile + slide_style = """ QSlider::groove:horizontal { @@ -40,7 +42,14 @@ class AlphaSlider(QtWidgets.QSlider): self.setMaximum(255) self.setValue(255) - self.setStyleSheet(slide_style) + self._checkerboard = None + + def checkerboard(self): + if self._checkerboard is None: + self._checkerboard = draw_checkerboard_tile( + 3, QtGui.QColor(255, 255, 255), QtGui.QColor(27, 27, 27) + ) + return self._checkerboard def mousePressEvent(self, event): self._mouse_clicked = True @@ -64,6 +73,85 @@ class AlphaSlider(QtWidgets.QSlider): self._mouse_clicked = True super(AlphaSlider, self).mouseReleaseEvent(event) + def paintEvent(self, event): + painter = QtGui.QPainter(self) + opt = QtWidgets.QStyleOptionSlider() + self.initStyleOption(opt) + + painter.fillRect(event.rect(), QtCore.Qt.transparent) + + painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) + rect = self.style().subControlRect( + QtWidgets.QStyle.CC_Slider, + opt, + QtWidgets.QStyle.SC_SliderGroove, + self + ) + final_height = 9 + offset_top = 0 + if rect.height() > final_height: + offset_top = int((rect.height() - final_height) / 2) + rect = QtCore.QRect( + rect.x(), + offset_top, + rect.width(), + final_height + ) + + pix_rect = QtCore.QRect(event.rect()) + pix_rect.setX(rect.x()) + pix_rect.setWidth(rect.width() - (2 * rect.x())) + pix = QtGui.QPixmap(pix_rect.width(), pix_rect.height()) + pix_painter = QtGui.QPainter(pix) + pix_painter.drawTiledPixmap(pix_rect, self.checkerboard()) + gradient = QtGui.QLinearGradient(rect.topLeft(), rect.bottomRight()) + gradient.setColorAt(0, QtCore.Qt.transparent) + gradient.setColorAt(1, QtCore.Qt.white) + pix_painter.fillRect(pix_rect, gradient) + pix_painter.end() + + brush = QtGui.QBrush(pix) + painter.save() + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(brush) + ratio = rect.height() / 2 + painter.drawRoundedRect(rect, ratio, ratio) + painter.restore() + + _handle_rect = self.style().subControlRect( + QtWidgets.QStyle.CC_Slider, + opt, + QtWidgets.QStyle.SC_SliderHandle, + self + ) + + handle_rect = QtCore.QRect(rect) + if offset_top > 1: + height = handle_rect.height() + handle_rect.setY(handle_rect.y() - 1) + handle_rect.setHeight(height + 2) + handle_rect.setX(_handle_rect.x()) + handle_rect.setWidth(handle_rect.height()) + + painter.save() + + gradient = QtGui.QRadialGradient() + radius = handle_rect.height() / 2 + center_x = handle_rect.width() / 2 + handle_rect.x() + center_y = handle_rect.height() + gradient.setCenter(center_x, center_y) + gradient.setCenterRadius(radius) + gradient.setFocalPoint(center_x, center_y) + + gradient.setColorAt(0.9, QtGui.QColor(127, 127, 127)) + gradient.setColorAt(1, QtCore.Qt.transparent) + + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(gradient) + painter.drawEllipse(handle_rect) + + painter.restore() + class AlphaInputs(QtWidgets.QWidget): alpha_changed = QtCore.Signal(int) From 3e2a16af94b8538ceda2df531abc83fb7f0fb1e5 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 20 May 2021 15:37:04 +0200 Subject: [PATCH 047/106] Delivery in LibraryLoader - added new Delivery loader Extracted methods from existing Delivery Action on FTrack Fixed Delivery Action for sequences --- openpype/lib/delivery.py | 296 +++++++++++++++++ .../event_handlers_user/action_delivery.py | 243 ++------------ openpype/plugins/load/delivery.py | 309 ++++++++++++++++++ vendor/debug_library_loader.py | 31 ++ 4 files changed, 659 insertions(+), 220 deletions(-) create mode 100644 openpype/lib/delivery.py create mode 100644 openpype/plugins/load/delivery.py create mode 100644 vendor/debug_library_loader.py diff --git a/openpype/lib/delivery.py b/openpype/lib/delivery.py new file mode 100644 index 0000000000..d5b18bca0a --- /dev/null +++ b/openpype/lib/delivery.py @@ -0,0 +1,296 @@ +"""Functions useful for delivery action or loader""" +import os +from avalon import pipeline +from avalon.vendor import filelink +import shutil +import clique +import collections + + +def sizeof_fmt(num, suffix='B'): + """Returns formatted string with size in appropriate unit""" + for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']: + if abs(num) < 1024.0: + return "%3.1f%s%s" % (num, unit, suffix) + num /= 1024.0 + return "%.1f%s%s" % (num, 'Yi', suffix) + + +def path_from_represenation(representation, anatomy): + try: + template = representation["data"]["template"] + + except KeyError: + return None + + try: + context = representation["context"] + context["root"] = anatomy.roots + path = pipeline.format_template_with_optional_keys( + context, template + ) + + except KeyError: + # Template references unavailable data + return None + + return os.path.normpath(path) + + +def copy_file(src_path, dst_path): + """Hardlink file if possible(to save space), copy if not""" + if os.path.exists(dst_path): + return + try: + filelink.create( + src_path, + dst_path, + filelink.HARDLINK + ) + except OSError: + shutil.copyfile(src_path, dst_path) + + +def get_format_dict(anatomy, location_path): + """Returns replaced root values from user provider value. + + Args: + anatomy (Anatomy) + location_path (str): user provided value + Returns: + (dict): prepared for formatting of a template + """ + format_dict = {} + if location_path: + location_path = location_path.replace("\\", "/") + root_names = anatomy.root_names_from_templates( + anatomy.templates["delivery"] + ) + if root_names is None: + format_dict["root"] = location_path + else: + format_dict["root"] = {} + for name in root_names: + format_dict["root"][name] = location_path + return format_dict + + +def check_destination_path(repre_id, + anatomy, anatomy_data, + datetime_data, template_name): + """ Try to create destination path based on 'template_name'. + + In the case that path cannot be filled, template contains unmatched + keys, provide error message to filter out repre later. + + Args: + anatomy (Anatomy) + anatomy_data (dict): context to fill anatomy + datetime_data (dict): values with actual date + template_name (str): to pick correct delivery template + Returns: + (collections.defauldict): {"TYPE_OF_ERROR":"ERROR_DETAIL"} + """ + anatomy_data.update(datetime_data) + anatomy_filled = anatomy.format_all(anatomy_data) + dest_path = anatomy_filled["delivery"][template_name] + report_items = collections.defaultdict(list) + sub_msg = None + if not dest_path.solved: + msg = ( + "Missing keys in Representation's context" + " for anatomy template \"{}\"." + ).format(template_name) + + if dest_path.missing_keys: + keys = ", ".join(dest_path.missing_keys) + sub_msg = ( + "Representation: {}
- Missing keys: \"{}\"
" + ).format(repre_id, keys) + + if dest_path.invalid_types: + items = [] + for key, value in dest_path.invalid_types.items(): + items.append("\"{}\" {}".format(key, str(value))) + + keys = ", ".join(items) + sub_msg = ( + "Representation: {}
" + "- Invalid value DataType: \"{}\"
" + ).format(repre_id, keys) + + report_items[msg].append(sub_msg) + + return report_items + + +def process_single_file( + src_path, _repre, anatomy, template_name, anatomy_data, format_dict, + report_items, log +): + """Copy single file to calculated path based on template + + Args: + src_path(str): path of source representation file + _repre (dict): full repre, used only in process_sequence, here only + as to share same signature + anatomy (Anatomy) + template_name (string): user selected delivery template name + anatomy_data (dict): data from repre to fill anatomy with + format_dict (dict): root dictionary with names and values + report_items (collections.defaultdict): to return error messages + log (Logger): for log printing + Returns: + (collections.defaultdict , int) + """ + anatomy_filled = anatomy.format(anatomy_data) + if format_dict: + template_result = anatomy_filled["delivery"][template_name] + delivery_path = template_result.rootless.format(**format_dict) + else: + delivery_path = anatomy_filled["delivery"][template_name] + + delivery_folder = os.path.dirname(delivery_path) + if not os.path.exists(delivery_folder): + os.makedirs(delivery_folder) + + log.debug("Copying single: {} -> {}".format(src_path, delivery_path)) + print("Copying single: {} -> {}".format(src_path, delivery_path)) + copy_file(src_path, delivery_path) + + return report_items, 1 + + +def process_sequence( + src_path, repre, anatomy, template_name, anatomy_data, format_dict, + report_items, log +): + """ For Pype2(mainly - works in 3 too) where representation might not + contain files. + + Uses listing physical files (not 'files' on repre as a)might not be + present, b)might not be reliable for representation and copying them. + + TODO Should be refactored when files are sufficient to drive all + representations. + + Args: + src_path(str): path of source representation file + repre (dict): full representation + anatomy (Anatomy) + template_name (string): user selected delivery template name + anatomy_data (dict): data from repre to fill anatomy with + format_dict (dict): root dictionary with names and values + report_items (collections.defaultdict): to return error messages + log (Logger): for log printing + Returns: + (collections.defaultdict , int) + """ + dir_path, file_name = os.path.split(str(src_path)) + + context = repre["context"] + ext = context.get("ext", context.get("representation")) + + if not ext: + msg = "Source extension not found, cannot find collection" + report_items[msg].append(src_path) + log.warning("{} <{}>".format(msg, context)) + return report_items, 0 + + ext = "." + ext + + src_collections, remainder = clique.assemble(os.listdir(dir_path)) + src_collection = None + for col in src_collections: + if col.tail != ext: + continue + + src_collection = col + break + + if src_collection is None: + msg = "Source collection of files was not found" + report_items[msg].append(src_path) + log.warning("{} <{}>".format(msg, src_path)) + return report_items, 0 + + frame_indicator = "@####@" + + anatomy_data["frame"] = frame_indicator + anatomy_filled = anatomy.format(anatomy_data) + + if format_dict: + template_result = anatomy_filled["delivery"][template_name] + delivery_path = template_result.rootless.format(**format_dict) + else: + delivery_path = anatomy_filled["delivery"][template_name] + + delivery_folder = os.path.dirname(delivery_path) + dst_head, dst_tail = delivery_path.split(frame_indicator) + dst_padding = src_collection.padding + dst_collection = clique.Collection( + head=dst_head, + tail=dst_tail, + padding=dst_padding + ) + + if not os.path.exists(delivery_folder): + os.makedirs(delivery_folder) + + src_head = src_collection.head + src_tail = src_collection.tail + uploaded = 0 + for index in src_collection.indexes: + src_padding = src_collection.format("{padding}") % index + src_file_name = "{}{}{}".format(src_head, src_padding, src_tail) + src = os.path.normpath( + os.path.join(dir_path, src_file_name) + ) + + dst_padding = dst_collection.format("{padding}") % index + dst = "{}{}{}".format(dst_head, dst_padding, dst_tail) + log.debug("Copying single: {} -> {}".format(src, dst)) + copy_file(src, dst) + uploaded += 1 + + return report_items, uploaded + + +def report(report_items): + """Returns dict with final status of delivery (succes, fail etc.).""" + items = [] + title = "Delivery report" + for msg, _items in report_items.items(): + if not _items: + continue + + if items: + items.append({"type": "label", "value": "---"}) + + items.append({ + "type": "label", + "value": "# {}".format(msg) + }) + if not isinstance(_items, (list, tuple)): + _items = [_items] + __items = [] + for item in _items: + __items.append(str(item)) + + items.append({ + "type": "label", + "value": '

{}

'.format("
".join(__items)) + }) + + if not items: + return { + "success": True, + "message": "Delivery Finished" + } + + return { + "items": items, + "title": title, + "success": False, + "message": "Delivery Finished" + } diff --git a/openpype/modules/ftrack/event_handlers_user/action_delivery.py b/openpype/modules/ftrack/event_handlers_user/action_delivery.py index 88fdbe3669..1cf2a701d8 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delivery.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delivery.py @@ -1,18 +1,21 @@ import os import copy import json -import shutil import collections -import clique from bson.objectid import ObjectId -from avalon import pipeline -from avalon.vendor import filelink - from openpype.api import Anatomy, config from openpype.modules.ftrack.lib import BaseAction, statics_icon from openpype.modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY +from openpype.lib.delivery import ( + path_from_represenation, + get_format_dict, + check_destination_path, + process_single_file, + process_sequence, + report +) from avalon.api import AvalonMongoDB @@ -450,18 +453,7 @@ class Delivery(BaseAction): anatomy = Anatomy(project_name) - format_dict = {} - if location_path: - location_path = location_path.replace("\\", "/") - root_names = anatomy.root_names_from_templates( - anatomy.templates["delivery"] - ) - if root_names is None: - format_dict["root"] = location_path - else: - format_dict["root"] = {} - for name in root_names: - format_dict["root"][name] = location_path + format_dict = get_format_dict(anatomy, location_path) datetime_data = config.get_datetime_data() for repre in repres_to_deliver: @@ -471,41 +463,14 @@ class Delivery(BaseAction): debug_msg += " with published path {}.".format(source_path) self.log.debug(debug_msg) - # Get destination repre path anatomy_data = copy.deepcopy(repre["context"]) - anatomy_data.update(datetime_data) - anatomy_filled = anatomy.format_all(anatomy_data) - test_path = anatomy_filled["delivery"][anatomy_name] + repre_report_items = check_destination_path(anatomy, + anatomy_data, + datetime_data, + anatomy_name) - if not test_path.solved: - msg = ( - "Missing keys in Representation's context" - " for anatomy template \"{}\"." - ).format(anatomy_name) - - if test_path.missing_keys: - keys = ", ".join(test_path.missing_keys) - sub_msg = ( - "Representation: {}
- Missing keys: \"{}\"
" - ).format(str(repre["_id"]), keys) - - if test_path.invalid_types: - items = [] - for key, value in test_path.invalid_types.items(): - items.append("\"{}\" {}".format(key, str(value))) - - keys = ", ".join(items) - sub_msg = ( - "Representation: {}
" - "- Invalid value DataType: \"{}\"
" - ).format(str(repre["_id"]), keys) - - report_items[msg].append(sub_msg) - self.log.warning( - "{} Representation: \"{}\" Filled: <{}>".format( - msg, str(repre["_id"]), str(test_path) - ) - ) + if repre_report_items: + report_items.update(repre_report_items) continue # Get source repre path @@ -514,187 +479,25 @@ class Delivery(BaseAction): if frame: repre["context"]["frame"] = len(str(frame)) * "#" - repre_path = self.path_from_represenation(repre, anatomy) + repre_path = path_from_represenation(repre, anatomy) # TODO add backup solution where root of path from component - # is repalced with root + # is replaced with root args = ( repre_path, + repre, anatomy, anatomy_name, anatomy_data, format_dict, - report_items + report_items, + self.log ) if not frame: - self.process_single_file(*args) + process_single_file(*args) else: - self.process_sequence(*args) + process_sequence(*args) - return self.report(report_items) - - def process_single_file( - self, repre_path, anatomy, anatomy_name, anatomy_data, format_dict, - report_items - ): - anatomy_filled = anatomy.format(anatomy_data) - if format_dict: - template_result = anatomy_filled["delivery"][anatomy_name] - delivery_path = template_result.rootless.format(**format_dict) - else: - delivery_path = anatomy_filled["delivery"][anatomy_name] - - delivery_folder = os.path.dirname(delivery_path) - if not os.path.exists(delivery_folder): - os.makedirs(delivery_folder) - - self.copy_file(repre_path, delivery_path) - - def process_sequence( - self, repre_path, anatomy, anatomy_name, anatomy_data, format_dict, - report_items - ): - dir_path, file_name = os.path.split(str(repre_path)) - - base_name, ext = os.path.splitext(file_name) - file_name_items = None - if "#" in base_name: - file_name_items = [part for part in base_name.split("#") if part] - - elif "%" in base_name: - file_name_items = base_name.split("%") - - if not file_name_items: - msg = "Source file was not found" - report_items[msg].append(repre_path) - self.log.warning("{} <{}>".format(msg, repre_path)) - return - - src_collections, remainder = clique.assemble(os.listdir(dir_path)) - src_collection = None - for col in src_collections: - if col.tail != ext: - continue - - # skip if collection don't have same basename - if not col.head.startswith(file_name_items[0]): - continue - - src_collection = col - break - - if src_collection is None: - # TODO log error! - msg = "Source collection of files was not found" - report_items[msg].append(repre_path) - self.log.warning("{} <{}>".format(msg, repre_path)) - return - - frame_indicator = "@####@" - - anatomy_data["frame"] = frame_indicator - anatomy_filled = anatomy.format(anatomy_data) - - if format_dict: - template_result = anatomy_filled["delivery"][anatomy_name] - delivery_path = template_result.rootless.format(**format_dict) - else: - delivery_path = anatomy_filled["delivery"][anatomy_name] - - delivery_folder = os.path.dirname(delivery_path) - dst_head, dst_tail = delivery_path.split(frame_indicator) - dst_padding = src_collection.padding - dst_collection = clique.Collection( - head=dst_head, - tail=dst_tail, - padding=dst_padding - ) - - if not os.path.exists(delivery_folder): - os.makedirs(delivery_folder) - - src_head = src_collection.head - src_tail = src_collection.tail - for index in src_collection.indexes: - src_padding = src_collection.format("{padding}") % index - src_file_name = "{}{}{}".format(src_head, src_padding, src_tail) - src = os.path.normpath( - os.path.join(dir_path, src_file_name) - ) - - dst_padding = dst_collection.format("{padding}") % index - dst = "{}{}{}".format(dst_head, dst_padding, dst_tail) - - self.copy_file(src, dst) - - def path_from_represenation(self, representation, anatomy): - try: - template = representation["data"]["template"] - - except KeyError: - return None - - try: - context = representation["context"] - context["root"] = anatomy.roots - path = pipeline.format_template_with_optional_keys( - context, template - ) - - except KeyError: - # Template references unavailable data - return None - - return os.path.normpath(path) - - def copy_file(self, src_path, dst_path): - if os.path.exists(dst_path): - return - try: - filelink.create( - src_path, - dst_path, - filelink.HARDLINK - ) - except OSError: - shutil.copyfile(src_path, dst_path) - - def report(self, report_items): - items = [] - title = "Delivery report" - for msg, _items in report_items.items(): - if not _items: - continue - - if items: - items.append({"type": "label", "value": "---"}) - - items.append({ - "type": "label", - "value": "# {}".format(msg) - }) - if not isinstance(_items, (list, tuple)): - _items = [_items] - __items = [] - for item in _items: - __items.append(str(item)) - - items.append({ - "type": "label", - "value": '

{}

'.format("
".join(__items)) - }) - - if not items: - return { - "success": True, - "message": "Delivery Finished" - } - - return { - "items": items, - "title": title, - "success": False, - "message": "Delivery Finished" - } + return report(report_items) def register(session): diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py new file mode 100644 index 0000000000..013ea73dd2 --- /dev/null +++ b/openpype/plugins/load/delivery.py @@ -0,0 +1,309 @@ +import collections +import os +import copy + +from avalon import api, style +from avalon.vendor.Qt import QtWidgets, QtCore, QtGui +from avalon.api import AvalonMongoDB +from openpype.api import Anatomy, config +from openpype import resources +from openpype.api import get_anatomy_settings + +from openpype.lib.delivery import ( + sizeof_fmt, + path_from_represenation, + get_format_dict, + check_destination_path, + process_single_file, + process_sequence, + report +) + + +class Delivery(api.SubsetLoader): + """Export selected versions to folder structure from Template""" + + is_multiple_contexts_compatible = True + sequence_splitter = "__sequence_splitter__" + + representations = ["*"] + families = ["*"] + # tool_names = ["library_loader"] + + label = "Delivery Versions" + order = 35 + icon = "upload" + color = "#d8d8d8" + + def message(self, text): + msgBox = QtWidgets.QMessageBox() + msgBox.setText(text) + msgBox.setStyleSheet(style.load_stylesheet()) + msgBox.setWindowFlags( + msgBox.windowFlags() | QtCore.Qt.FramelessWindowHint + ) + msgBox.exec_() + + def load(self, contexts, name=None, namespace=None, options=None): + try: + dialog = DeliveryOptionsDialog(contexts, self.log) + dialog.exec_() + except Exception: + self.log.error("Failed to deliver versions.", exc_info=True) + + +class DeliveryOptionsDialog(QtWidgets.QDialog): + """Dialog to select template where to deliver selected representations.""" + SIZE_W = 950 + SIZE_H = 350 + + def __init__(self, contexts, log=None, parent=None): + super(DeliveryOptionsDialog, self).__init__(parent=parent) + + self.project = contexts[0]["project"]["name"] + self._representations = None + self.log = log + self.currently_uploaded = 0 + + self.dbcon = AvalonMongoDB() + self.dbcon.Session["AVALON_PROJECT"] = self.project + self.dbcon.install() + + self._set_representations(contexts) + + self.setWindowTitle("OpenPype - Deliver versions") + icon = QtGui.QIcon(resources.pype_icon_filepath()) + self.setWindowIcon(icon) + + self.setWindowFlags( + QtCore.Qt.WindowCloseButtonHint | + QtCore.Qt.WindowMinimizeButtonHint + ) + self.setStyleSheet(style.load_stylesheet()) + self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H)) + + layout = QtWidgets.QVBoxLayout() + + input_layout = QtWidgets.QFormLayout() + input_layout.setContentsMargins(10, 15, 5, 5) + + dropdown = QtWidgets.QComboBox() + self.templates = self._get_templates(self.project) + for name, _ in self.templates.items(): + dropdown.addItem(name) + + template_label = QtWidgets.QLabel() + template_label.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor)) + template_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) + + root_line_edit = QtWidgets.QLineEdit() + root_line_edit.setText("c:/PETR_TEST") # TEMP + + repre_checkboxes_layout = QtWidgets.QFormLayout() + repre_checkboxes_layout.setContentsMargins(10, 5, 5, 20) + + self._representation_checkboxes = {} + for repre in self._get_representation_names(): + checkbox = QtWidgets.QCheckBox() + checkbox.setChecked(True) + self._representation_checkboxes[repre] = checkbox + + checkbox.stateChanged.connect(self._update_selected_label) + repre_checkboxes_layout.addRow(repre, checkbox) + + selected_label = QtWidgets.QLabel() + + input_layout.addRow("Selected representations", selected_label) + input_layout.addRow("Delivery template", dropdown) + input_layout.addRow("Template value", template_label) + input_layout.addRow("Root", root_line_edit) + input_layout.addRow("Representations", repre_checkboxes_layout) + + btn_delivery = QtWidgets.QPushButton("Deliver") + + progress_bar = QtWidgets.QProgressBar(self) + progress_bar.setMinimum = 0 + progress_bar.setMaximum = 100 + progress_bar.hide() + + text_area = QtWidgets.QTextEdit() + text_area.setReadOnly(True) + text_area.hide() + text_area.setMinimumHeight(100) + + layout.addLayout(input_layout) + layout.addWidget(btn_delivery) + layout.addWidget(progress_bar) + layout.addWidget(text_area) + + self.setLayout(layout) + + self.selected_label = selected_label + self.template_label = template_label + self.dropdown = dropdown + self.root_line_edit = root_line_edit + self.progress_bar = progress_bar + self.text_area = text_area + self.btn_delivery = btn_delivery + + self.files_selected, self.size_selected = \ + self._get_counts(self._get_selected_repres()) + + self._update_selected_label() + self._update_template_value() + + btn_delivery.clicked.connect(self.deliver) + dropdown.currentIndexChanged.connect(self._update_template_value) + + def deliver(self): + """Main method to loop through all selected representations""" + self.progress_bar.show() + self.btn_delivery.setEnabled(False) + # self.resize(self.width(), self.height() + 50) + + report_items = collections.defaultdict(list) + + selected_repres = self._get_selected_repres() + anatomy = Anatomy(self.project) + datetime_data = config.get_datetime_data() + template_name = self.dropdown.currentText() + format_dict = get_format_dict(anatomy, self.root_line_edit.text()) + for repre in self._representations: + if repre["name"] not in selected_repres: + continue + + repre_path = path_from_represenation(repre, anatomy) + if not os.path.exists(repre_path): + msg = "{} doesn't exist for {}".format(repre_path, + repre["_id"]) + report_items["Source file was not found"].append(msg) + continue + + anatomy_data = copy.deepcopy(repre["context"]) + new_report_items = check_destination_path(str(repre["_id"]), + anatomy, + anatomy_data, + datetime_data, + template_name) + + report_items.update(new_report_items) + if new_report_items: + continue + + args = [ + repre_path, + repre, + anatomy, + template_name, + anatomy_data, + format_dict, + report_items, + self.log + ] + + if repre.get("files"): + for repre_file in repre["files"]: + src_path = anatomy.fill_root(repre_file["path"]) + args[0] = src_path + new_report_items, uploaded = process_single_file(*args) + report_items.update(new_report_items) + self._update_progress(uploaded) + else: # fallback for Pype2 and representations without files + frame = repre['context'].get('frame') + if frame: + repre["context"]["frame"] = len(str(frame)) * "#" + + if not frame: + new_report_items, uploaded = process_single_file(*args) + else: + new_report_items, uploaded = process_sequence(*args) + report_items.update(new_report_items) + self._update_progress(uploaded) + + self.text_area.setText(self._format_report(report(report_items), + report_items)) + self.text_area.show() + + self.resize(self.width(), self.height() + 125) + + def _get_representation_names(self): + """Get set of representation names for checkbox filtering.""" + return set([repre["name"] for repre in self._representations]) + + def _get_templates(self, project_name): + """Adds list of delivery templates from Anatomy to dropdown.""" + settings = get_anatomy_settings(project_name) + templates = {} + for template_name, value in settings["templates"]["delivery"].items(): + templates[template_name] = value + + return templates + + def _set_representations(self, contexts): + version_ids = [context["version"]["_id"] for context in contexts] + + repres = list(self.dbcon.find({ + "type": "representation", + "parent": {"$in": version_ids} + })) + + self._representations = repres + + def _get_counts(self, selected_repres=None): + """Returns tuple of number of selected files and their size.""" + files_selected = 0 + size_selected = 0 + for repre in self._representations: + if repre["name"] in selected_repres: + for repre_file in repre.get("files", []): + + files_selected += 1 + size_selected += repre_file["size"] + + return files_selected, size_selected + + def _prepare_label(self): + """Provides text with no of selected files and their size.""" + label = "{} files, size {}".format(self.files_selected, + sizeof_fmt(self.size_selected)) + return label + + def _get_selected_repres(self): + """Returns list of representation names filtered from checkboxes.""" + selected_repres = [] + for repre_name, chckbox in self._representation_checkboxes.items(): + if chckbox.isChecked(): + selected_repres.append(repre_name) + + return selected_repres + + def _update_selected_label(self): + """Updates label with list of number of selected files.""" + selected_repres = self._get_selected_repres() + self.files_selected, self.size_selected = \ + self._get_counts(selected_repres) + self.selected_label.setText(self._prepare_label()) + + def _update_template_value(self, _index=None): + """Sets template value to label after selection in dropdown.""" + name = self.dropdown.currentText() + template_value = self.templates.get(name) + if template_value: + self.template_label.setText(template_value) + + def _update_progress(self, uploaded): + """Update progress bar after each repre copied.""" + self.currently_uploaded += uploaded + + ratio = self.currently_uploaded / self.files_selected + self.progress_bar.setValue(ratio * self.progress_bar.maximum()) + + def _format_report(self, result, report_items): + """Format final result and error details as html.""" + txt = "

{}

".format(result["message"]) + for header, data in report_items.items(): + txt += "

{}

".format(header) + for item in data: + txt += "{}
".format(item) + + return txt diff --git a/vendor/debug_library_loader.py b/vendor/debug_library_loader.py new file mode 100644 index 0000000000..1bbd963f16 --- /dev/null +++ b/vendor/debug_library_loader.py @@ -0,0 +1,31 @@ +import os +import pyblish +import pyblish.cli +import pyblish.plugin + +os.environ["AVALON_MONGO"] = "mongodb://localhost:27017" +os.environ["OPENPYPE_MONGO"] = "mongodb://localhost:27017" +os.environ["AVALON_DB"] = "avalon" +os.environ["OPENPYPE_DATABASE_NAME"] = "avalon" +os.environ["AVALON_TIMEOUT"] = '3000' +os.environ["OPENPYPE_DEBUG"] = "3" +os.environ["AVALON_CONFIG"] = "pype" +os.environ["AVALON_ASSET"] = "Jungle" +os.environ["AVALON_PROJECT"] = "petr_second" + +from avalon.tools.libraryloader import show +import openpype +openpype.install() + +# REGISTERED = pyblish.plugin.registered_paths() +# PACKAGEPATH = pyblish.lib.main_package_path() +# ENVIRONMENT = os.environ.get("PYBLISHPLUGINPATH", "") +# PLUGINPATH = os.path.join(PACKAGEPATH, '..', 'tests', 'plugins') +# +# REGISTERED.append("C:\\Users\\petrk\\PycharmProjects\\Pype3.0\\pype\\openpype\\plugins\\load") +# pyblish.plugin.deregister_all_paths() +# for path in REGISTERED: +# register_plugin_path(avalon.Loader, LOAD_PATH) +# pyblish.plugin.register_plugin_path(path) + +show(debug=True, show_projects=True, show_libraries=True) \ No newline at end of file From dbf70d34ea039a31ebd3b22dfbdc90d48a8ed61c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 15:38:03 +0200 Subject: [PATCH 048/106] darker white --- openpype/widgets/color_widgets/color_inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index d3c801bc0f..eda8c618f1 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -47,7 +47,7 @@ class AlphaSlider(QtWidgets.QSlider): def checkerboard(self): if self._checkerboard is None: self._checkerboard = draw_checkerboard_tile( - 3, QtGui.QColor(255, 255, 255), QtGui.QColor(27, 27, 27) + 3, QtGui.QColor(173, 173, 173), QtGui.QColor(27, 27, 27) ) return self._checkerboard From faa6fdcd08065e9de928a68f3a82b093f3318795 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 15:39:19 +0200 Subject: [PATCH 049/106] removed unused imports --- openpype/widgets/color_widgets/color_picker_widget.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 40e20496f6..fd0f31e342 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -5,14 +5,12 @@ from .color_triangle import QtColorTriangle from .color_view import ColorViewer from .color_screen_pick import PickScreenColorWidget from .color_inputs import ( - ColorInputsWidget, AlphaSlider, AlphaInputs, HEXInputs, RGBInputs, HSLInputs, - HSVInputs, - CMYKInputs + HSVInputs ) From 7e2a9ef3e6e55d6aedd1a3af59dfc236983db688 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 20 May 2021 15:56:50 +0200 Subject: [PATCH 050/106] Delivery in LibraryLoader - added documentation --- openpype/plugins/load/delivery.py | 2 +- website/docs/artist_tools.md | 16 ++++++++++++++++ .../docs/assets/tools/tools_delivery_loader.png | Bin 0 -> 16082 bytes 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 website/docs/assets/tools/tools_delivery_loader.png diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index 013ea73dd2..6c83886686 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -30,7 +30,7 @@ class Delivery(api.SubsetLoader): families = ["*"] # tool_names = ["library_loader"] - label = "Delivery Versions" + label = "Deliver Versions" order = 35 icon = "upload" color = "#d8d8d8" diff --git a/website/docs/artist_tools.md b/website/docs/artist_tools.md index 5bc3f4c1fd..603e5fe590 100644 --- a/website/docs/artist_tools.md +++ b/website/docs/artist_tools.md @@ -177,6 +177,22 @@ Library loader is extended [loader](#loader) which allows to load published subs +### Delivery loader ### + +Library Loader contains functionality to export any selected asset, subsets and their version to configurable folder. +Delivery follows structure based on defined template, this template must be configured first by Admin in the Settings. + +![delivery_loader](assets/tools/tools_delivery_loader.png) + +* Usage +- Select all required subsets for export (you can change theirs versions by double clicking on 'Version' value) +- Right click and select **Deliver Versions** from context menu +- Select predefined Delivery template (must be configured by Admin system or project wide) +- Fill value for root folder (folder will be created if it doesn't exist) +- Filter out type of representation you are not interested in +- Push **Deliver** button +- Dialog must be kept open until export is finished +- In a case of problems with any of the representation, that one will be skipped, description of error will be provided in the dialog * * * ## Publisher diff --git a/website/docs/assets/tools/tools_delivery_loader.png b/website/docs/assets/tools/tools_delivery_loader.png new file mode 100644 index 0000000000000000000000000000000000000000..511cd24fbb542bb38981a8e3ecffe598177760bf GIT binary patch literal 16082 zcmeIZXIxX;zAnttrLH9cx)edG4Urm=9w4!Tf)wdJ3euYpdIAyIf=Y=90jUvb(xnqh z5CtMN(o28{2q9EM2oOs0PIT{c&pz*d&pr3t_kOz{_zmXFoO6sZ$AA3G^E~r~fu0uE zQGufz92{JC@7yxv;P_pZgX6c*KMn(Dbd#+%faW*2q1FwKk{%%{aPYg+b=~V69A#+E z-G_&O<3AtYv4C@MaDU$a`;FlB{t*WU#Ody>>&Ah$%M%{%Hk5S!EhrBTi455KbKl#DvCcu`kZEI9L(Ub^pVy+=`xu6n23@h?(d30l!eYG`Qi%9hQ! zN!^r>^|Qs&(J9)AP|T=+X$mw{+;g(a(R1WfS(((FvSyc8 zY;Bbvq)w!k7d2x~nqJ+*pq--XIt2HJHlCXcjojW~qnjdQ0-Rys_jb@d@7QbwYqoF zN-DL?`=+nMP4_Pmx;Ao6VuF(=z3E}hTBc6T^xVywY4$iXdFxB!k&Zus2XOd>ELxE} z2q`!Gl=! zjiNCG==Ni!beYRssdl0C+*+K=&4%qL+*(_A!`idHFw+QeaeNZUoU^oruV7%n&;nn)+33+Mx3NQIv1P6wJ1>v3?#rHnCYc->i$v7-70ZxfneZWdS7{^p19&M z>+v)!I@N|QhkbfFwPLXR;ZCIJ^QN7aELsyp<2V|*buj1cZLueDPx+u}C~etKhbBI`sX_q~=0RHSWJ|L$&Q8T~8a-6Ch{_s+2& z^UYh^yTdczvY5Vc#d!_D3V$^|`hK^*6y;&@pCgl+Q}3 z1?ejJ8t1dDxx1uUU39AUOGNi9ho)ISUbTtuBx-ARYqxU{REBPAo{>noA|e&&0jtvD zVR<51f}l1tPR263pQc6D5YR_5r2?{#0dL`(|G;6;&{gL+1#asWq{QR6?efcqWXh-X z+0#zmKiC?Au&oYe;No_%`r|THJ9}6Czi3IyN>uVR0v5y9L}PA^_cMK4v#>Fgj9UKE zq^Exd!JnHM(w~C6FKc&mOX^DFUp38BNcW_buDjTT&miPzkIba=zrS(~S5J1eFS^82 zlW%+&7F%lkmm3bPT@mL8L`S9A$DU+g0=>nG`AvSvB<_EP%7-t6L_2Aa_a z?5%H}`P{Ze4qwl^2-VKl@zyByXt_@ur&}5QcqcW9_q!1KBVLN;zwI&*liKk)!bdSm zMo_7xv?(u7Ve;!qbSq)4HwS-$%=Cn$#E5Qxem;|b<~Ghli`AFfI1;+l8d%cTGClho zY8_bCUCr#FtTC}@FNOEbw8j_EXb_ZUjoj$fn)$XG3c)uVm-u4H?ns)UHzBTcV6L0S zN9tL$LsEpb=xcRbBQ$rGXsex2{y~?UJRd7UJopD%B$~X36dBl>T=bR$rX}4ppTYD= zv=*y!Pc7T^*q{Lmrr3+Y*>g1u0%wBG zR92u}V`8&z2Wf1MKHC6Cc`6s9HBJLol-#Cht4%c?tjm`ry*^ASGpXa?_!v^WCgxNa z)|2lkVmRUcNJgQ=yKKsId<-cyNABmXnXEsz6L3>$f>*f|hGs6!D(>A{n2WLLWjFJ* z#A&fzcVmv!%vvcKkc8g78~EEJCuBnp!ngX0ZPOccA`)U-g8wnLz0g>9p=&|lus&g= zH!3IPVE(1HRtm(5+gQ5dlX?O;tEi^wQX-~VJGNrfyQs3kQ@(h21WgDte3E6a3m%fR z0W9CNs9Ha23<3fdyBNi#rc!2xb_~D06KWXQqfKs^WuY`!rNq5qnmAGYG@JOfXNz!9 zG^!Cr1fM7}{ri?4>pXCRVtE)Opv*h^7_bPO3Ac4Z1XtOVh7IjwVmA%nEjZJds?>rT zEu`%ZH;JOwv9g#@NL5ZA`~3j)lYBnzx=Y}t=~?F1_G@wn^1Od&-fnlW8G|!qgT1~e z7#9kzEZjGQTXF|>}j8ddKaCIPqh-M73U6%23}!p!h(t_)jc*gZMSV3s%U)P%gwNs zRrQVDEk@J&RA2cZLJV&Z99PO}AE;t<@YPLAVGFs1#+mBCVsdn9Y>e2)xLG$ibw<=O zGpv9J^gMO7k+-ILGWy7*5o@&nV#rRTD*JZa9VoAk6F~c(7j#_3s%&;(wM-{BQqw$EwDY_vffyQadnGzj7Auf6iI{w>$Yq zD&)5;!vBUy@FIV6780fs#b4vz2toe>*>s363Pkt52vZ68VV>4b8CMN}lNFMBy6?2S z2={iE#A4Q$(G)_&yLtt=beR&30Iq7QcMUx~?(UvG>b5EtxNE~qh5?*yFu)ErZPK#Dv!#Q|JOJNhN)ixnOHU>8i=Cw(5q%3c5f6MKa-Jg>l1%BII~avf0V?#vf= zbab+JCO?4KR0q6;%G%bx(if9igZM#Y=du7ptH}!2z1=a`8esFjBpBv!mzTZZx_k`fZQ&H{SVY+rq=8^{Ik;m7blx6%3wD zM-cL+T!MJx$nOtxTx3f9n?AVn?vT~MWkpCk_7s2N*!3Adr)lZ}y#Is5jfxpBA9b1R z-6aUD%5#kUk*Q)_MJxBa%9z6pe$VlZcCsf?@MJ_^Dxj(&%q;U5_ALj!m zY0gj}C#iLyA*bB)wzmC6e?9E`V454IW`T8}&sVHe>Yf|PS)GiKL{UqtpYA2u`XZ)% zT_(nsT}?oxHZ}ehCQJ}XD}2w%!I~XtX|-WzBVHVQ{bew{K*lDcqs;c(yK3n%RV^+B z>F}|T?}p6f)E9i(XWU<-!S$u%sHm{4w#1}@JhmTaiSG3OMKAUq%w17OzS6Oc>pMEDRLob(frC5j77pGtoOt;!DC%xF? ziESGx;WVM9na|+=ND(4x+hoMxGA3JlR4S4dCNpqvEDB>yOyRK$t^s?-@P}u628WED zDGf;nbi_~3HF>YyNi+Y;+%j_jb%*#^UG2>_ugir8=57`b0C)YsZ%Fp>iSV*|C@TM+ zqF`O*G}RO&*F7X9Q%H9^B4$#>nUWJ{i`+SKy6KQ?Na{pxBEf+1dZ-2(Aw{s&x0<~l zIx38f9>H+e6?+Ke=ZDCtRs66^3w>zsaz^2Oe%uBb+xW#a5ffWhmv~o7kx(I!e@V+2 zbDf$bYf3Ymh#gGJN=zwjs<9rlbE$~Kq-}~_PcHx#M8m@S4@pa*oA)*eJ?hj}$YIkrrXH%Mu@W&gBdDy<c>la!k5xj#F1g6Hpv^11YC6Yqz^C)&1?q-Jd$ zrUYCACzC8y0&qDbGsg03w;{r9m&QJSOz6EeYTxvjy)H?{)`&L-d;-WBoQG3zZy7~+i@B=O3%sv185BH zq`U+gj%SyC)!6@eyu#khF|Vt$qvz_D1<~h_`+&q^cekMO^fqJB+l{qxgPTe*I3#;H zLB^`Oh2b_lU5sTZV1e@aV=(>OO&$#X6@Fu-o|!gyH;hyF_T>cKRHdI=vIy?A_g%cq zWu^_eu<^$~75)EuK!eR6Z|}#d^RaryJdrb_c%-*ZxExqc071{+A?yW@-`+450*7AC z=*kmt3)o+3)56b+vU7GmyAOoGZ+K?-?1o2fMRU(ZkrHj^%>G(`QZI8z4u6WM@mhbs zo;=}3GXCDz9{3P>wNA^_GV6h4tg!meXuJBhF{`zB&)|DQF-DwcA~YsKFS~baczQkz z)D{K(A`av62M-{kO}hE{U&5ZxRQ(p2!VKA&VU}gi%Yve##JStb z@)Z(YEsnL|!U@w|pSJSni*@BaU@3lAC!H}vFP_K6v7Y0++LUL^rnR$t*DMfP;^&KP zuPUFJDcDsvk|znTtm+v#Q885(pS>t5qCuwU-V;gFCHP-JJwpnzXJRib(DXsW@PBmDn9d# zTKZG2;=ToRTo`@UL5p>fwVLAVzckA0J+*Y>>v>i9(k<&~s>=Pb+?Wtwp4P`gAdnz7 znqMGlYLteYI4P%G=~WhStJ-swsSS1+4XY#UwY6Vhf_3`My(d?GgF&|m-m*PyqM|Ct z+4fWi4FrxIzU+NfHz|S~rMyY$me1I>R%aEHJ1I$#r;eLvXbMZ5{b5C#o+WqIXjC*x za`ZjI`t6;yRS#0lV2&FxeOuzOJMLX+?s4qb8Z;{eF(E00h9y8t?^5FQL#|F+mHyld z0VW==-r0VA7r)~E&F=A8|J)~^Zcx(g>TYNd^20zTlEK8Wvt4dpHpv)tq4JPaIy)_!a#0=}A(H~Xv z-m;<|bwtg+4aCM=w^7E+W(_BM$-x5WyEcK@ZNS^DKoIoR8Jr?P{%=`a=PsP z=S|qB2ZWa{S4=?!nU?p`Cr*avm$w)pvNj8063VJ~O%sNOr=?&Mr+50pvfmO$<)iko z({YD@^UiTa9^cL*PC&tZqI^2KYFG1zZf+W=H-3VhQH8r+t&7yM_XWbP@%gibcNSyf z^Xxr`GXnk3cJ?zhy|y%Zt(b?A7-lhu2M?4=_O&QkM_Ee$prh02l+vXUsI}3IUGbXf zBa)q#7)PAz+4WGR0!#gY``iz9S!NeR*v1Z@3ltV`>yBO01MXiETs6OsjZu7H><+W6 z0CuKICCUo9Q`L~zBH6bMAY=A(@z|G?jg=R0rxZ;cVEik0g}JSL317`~s5g|N*AqfT z{K`&$G!~ND>$o!rKIyS**p^e_eGWk*TiC$uO-#igdNMgHo4CKFAI%6?19Ht^1&)Kazbk*xN##QK+I{gS?28N{K z0x$0Q5LQDJgHeTj1LwJzpor`qMZP&%g8XC4+SaX_5_JGBdKDPqqw3*4xD)_SfYWtPSaRME- zUTc)d^7$jigkA8516qAEXA3)nZG#Rp0kQ8xY*9aq7e_M8OQRBQtvverbovfd)zXHP znJ&N+V6~7Se>ydFf0>$OAWtH2P=)&`AK0bz+egxo`E`+k_I%_GXMMKqQ}zm z^4=bDw|YMgvYNdh!aEryXCOG$Tv&)kXhvy`|6zOI>Ew~e3nZE>8)KmofCBxmRVo z^&o9)E{e9W2<>z#dFC67=SL~q6o#Nq5MEr`wz?l`R%F2} zu5>4vH#sn6C$-#+=8EZoPNir}BCW%B+PuSM*Kv@nhAqO{h85Q!@ETE@+7t+UtX{-y zooT4wi!EdnQ4oz8JB(0R{sAZtI5>?Vt+vtX)H5N8junDO5~-GHk#57K0VQp%I$GRq znc*%fC;05adI@b6Q(xKxFTjqB#cTYo8N46z8y>G2LcC;VhZoE8k=s2g@FJh4ghn8f z6%uGVUeCRR7G^fQ6h`>pwpK|c>$q7!sJ|gqGL}2V)uvYxyfgxGyN2H#8@81zY1*j5 zlB))i;S&YOfF;q`m3CU6lPjeI=@10-8rG7p36KuS0l9Lw(ALN*oS$jW51y0*zbUPr z^JI@nwW&7l&6t;LVX2+GGk6PhkmuY6n!>6jo8^vB8sP*B;+j1yl}N$h_Uu=7Rc#9C zk6}u@qiSFvtMPv6s^mB{&jPJ8n-osMCp5}ru+ocBYvfmhhssT7<#`F*A}^9WFD&~7 zp!^!Tyqb=!rqqY-Db_5FxvDj}<(#C{`7u2gsj;|NzAec$+aHTr$%8O89kj#hy!m>D zEZaK?{}2j}mux~d@Fp+DJE|0OK{_`AWn33({=Wm z?&6bsPCbacm5D@(`rsvJwT^*;V~HX=V@OEpCl6t`&kkjMW2JG!y@PFo$RC>;G4Q3t z^XUsk`&>a@(d5}|!*SNzJ$m2Z3qTQiK*4+my6g2-w-4@2CRU>Kl}={>me?FNa=9s9Dy8+(h@C3uav+4Hf=){UbfWqsvV&3+aY(#!BEyoUk4n?AOM zFLocEgrA4kZyI%81(9rU8CP}I#!Sx)L6u{$;*8ykytwX*T)5E_Jlcb2eUUlqfYXGn!CW^luATYk@*#1ShO|W+J}H^-f<^cgT~#f@fl_IN9ZkllBgVjUmjspy z*R99=9-eFTCFUUPnH7Q0cHH`fk6J$xcPtXu6IFi$&F*W52oY_2yw+AS`D2Z{FQs1Q z9WX!UBwn!ox?fI28Jc&2qf({gHmM5B%hQ-z3XT&S7~RZ^iF^E>$azJ zvsQ-b!+m(Z)uf0`j}-SE)m~|G&KbX=cU=`eF?0sn{(fP@Kt}4le#+f+xW%S=_Ll$N z?jWQyQFu|Zrb$F*KZPzUr#!HpY>-E=NOK2-h!q|57 zWvnfyWHbdQCVJWUb=2M=4%Q9P8f}L|f}4`UHD;3-H@p3<%9boW;;@GoSQ_}3#6Qps(*H#Vw$%H(ZGx1Nw=+Erf9da-$ z9`#F3?6!F>ruc$niW$~%n)zhSGU!xjN*Y7zDRc(d2w$eB%$R?@3hFGym^yq|vQ|>( z;aW4JOCy4vs|$q8%uaLB)%_%8mjpWJ97F>L9r~R^BZ)Q^6^N{4UeDqAH`)R)sbw2C z9l!4om+bywt$rVu-0Mtord!@hSvId@Kh{5_m(>5x(j%+sjOq40=e%9R6d6dofDNip zGV-(a#hqLg;1B6)f2Gv>tu=xyi zli16}zOb0__BDwQ12_{ZDfaUYDNv;-%ok3;k0cg!^kkru$|E(sjuA5O$xCETns#tv z(Zacuy>o%Px7MqpZ{#gHsW_f~htDst!;`y&L0HXU2d50Ej^Bc|s0p$XK}l?_$tAxv)`D7+k%8zhUmKr@uE#D+Y^6ge*rW+Yh7=W8r{Ls=^(O4^!b-Wbd7k9IN$!RnE@y0VKSD8jGCD4;Jqe(u zRvkvkUzF-_%Ihp0a_ylCxEd?D(UL1HYy8q>%yuaYK8riHuoYG#IWIBv0=7{}nM4*w zi4<9;!!y=wT(@7vmTg`cj1zKF^*(A1h*-a$g4q}vCWNg(b)S2*xSYMy)NlS@dnd;>i zUa{DYvF#5rp-y5NIVdwZ&ZZ?<9K;5DDV9m)Jnvcj zkPlLGJ$YQRxAXsM3tMV1?SXf$FW&9l&R0nsYpjX}o8I22Sj?{97(TI(sGqudyU&xA zYLk@XU@}bqtGlD-ng42zW6ErO=3qjQplN&(CgFNN{p*OJxPFrBUmB@rkh#a zwy5laGtp(VcH_)^aD^h>D$%Ubt?+he>V#lSM!VP`nco2f?_S9l6A*S2E^HhEdt()P zX^UCedbn{@COOP4Z^OLLmsPxwYy^Ns<{Nf#dztk+yMZhjmjaU-{x>B%%AX4|^zX(m zO6K6EiP^4&s(Fjw_nlz(T0-LoU|M$>Rin~qE)$H`1x82hW#XXb&|>4{m%YFyGi&e} zkWiPcEZvKc%1XAh(kou;UmqXNC>#v6tqI1X6Ww?dV#}^S$hAH5C@2tLx1sad4gXAS zqsAkZFuqW0x#YI$?5dWOQ@@n%h}oPxI-V)OH_Ay0^is!qZZDa4=2qByZgj&h03}@% zHCs<7(dLO!o}G`1hH-~fw{FJscAU0v;jTxYd16wgddh(Rq&B$?-D+@8HZ*J47dBY1 zk$OodU4xO3=v$3k;fr!Gl_cIV0Wsmf#IQG&2suT>5{lQ zGzOyk7hM5K$%boE&S9OMC40K{TJGrk$EH|EcwlZf^m zd}q1knvg~VRMyF*;qiwB%~Wmj>!J6X$~U#`#fX2aE-9QPhE+r3T`N(#B}v4zHj-kO zQE-@Q90sxR+Onf*DQNKNe|Hg$I!Q&&t}3M0Zwf4qX) zV||&L$uaxrjq`G++j(({@LY?ZHw}8}$0gQ<=zNHlw%8 zL$vb-W_sb_USrF6J+bLsXl`Coc%>fWN{aGbi3NDoR*+}z1p=HrvD&_^u_~q3gOQvo zBeUcJShYh7>hHaOTeNjriCWh(%a5?j!s<+myaMlPH{MJt^qJhr8+B^y821`JQaB@j zWL^O~tdQhtT~zUt@qOI%)p)g8Sp8|Qz4bh%5OCR0>Jic4_v_Ers{+W~lp?*O z*3ObQGTp~2?|ubPRF9|5<6*lH(fU_U>9F`C8?Q^1=?p?-~FOS8x^}cxV?4j=!ELOq18YuiV zw|DF>c0(JQ)b~05TCbvqqI~_{)8EQej08jhrg`ek8Gv`rxu!{G1%?7SdQxJIrP6WA z>Aor3JT!pmK0(}U-l+v@ak{El_`x#xwy)}yIKbcSQ(plE7QOCgfX6{fWV$&QB{;NG0Ik^eJ2~IMSnhE zY=lJG*cRlww&Oazu^tH&Py4@8>+PtNp}s=7s(zR(5oDs5_PRH4>7b56}Z2L^QU(-t?xo z#Q}9NqhY@JOAX+oMen z^|fAfTLjl~tBBV`9WQi?wK+4+q|;XFSLfis$X_mZ3>F^X`!Kn?kO$%Af$ly=?ktVg z`tJopYH%{C%7hujM$0%l^i*l%h9v}$aJ~f)v%Th^!zKUmdZ#gO5E1B~eBlRWoZsekzW-hRPZ(PIFB`__4=2;QTt zml2EWs2SgPJp1s!!RNQ8Cd=XYJ-KlxpL`OXYAMsN-2vLAMs3(2%4-Izt6j3^o(1?{ zn*5>#V1Xt1-o4*uRhFAjfpYT(;I@UN6;s#P$iaHwtFf>VUVDtCynX%jCt5rw1t3SB z*jWH-=DXx4n}jdUFHhfVEn6zCM_fc%NOKJ~eUuZHGYE3ue90w;`wHKj zZi1_p5QyRS)s-ESopRyCP5aU9$W20QzLDIheEF-kpGbXEnqh?}q(*v~ePc7BXR+ruKfry4#~;Q=_dgehCYwrpdKJ?6$G*zT;T@XUBntiooG; z+L&AE>`zbQ!4+!q`%5oRN0%pdtJiED?9){OSjaBcyjITG$tF34fuUDJ>FMb)a7xc? z{{F~$4gu*xVOd8C_!q-O^)6R;8ye3=SmKD4g?;q%K)8h*QBbi&-pP&dkroE)7BXG?hQeK)kaX}LKTz|zGf z0!;fy@cGBTEp|u5a4O0uZ6MXFmnO-+cNQ_9^cVfBSf7acHs^ zk?H@*SV%4KqHSHm&+{#9larHVBH`i0h#L6Bg*}b3MQYy9fVp01Hf^uJsp&-y+p0fO z9yGd3P=-aD!Ppkn8-UkiJ?g@52k$mi`W4LnxaY3ISPqnjRZoSZp z)>Ua8CoT0!J5dspMxyZ~%5+wbqf}V;Gg#%zr`HViP`L_|BXelfCC}X-$Sy!#J<7HF zVkCj9dps>f!?UMB#AbExn)~*bYu4P9@gNL;3XQikVqzIFLTw1)J<#mQnjK(se;6ucnzr zRtdUD&Mmh|4FY09E%8t5$2`fga3khCK&m|~5f3IUsM&$_uw5iq>y#I`1!}F3Je=u# zcMxJH*`phvwOWlVZ)X|BL}i^k$-MHHT4x1d9nROk9T*z><{Z6TcYMY~QC4;?3RnCzbiY5ejlUD%gTlvbjj~)Yo^XQ3irt`736&CIdE=^xaUM*hP>24J$Ld|q$dTy4@ zznTFZ1&m;S1DGA)D>5>oY3HlGe4!E?h+6tW88WN#bS;p(A{eief-3qr{;2Div=S3Q zNhY`XuIK8tJ|f=1ci$3v-d{*Y`7Ap6dQ4gh=n8w;ss)r&Uk%-@Q)_=Df#(3cfb;P))i7%suFD2+*gfD8Sxw@Sd#DKiuM8T)?UBut^%A=w9w z%t8GSNs-X4sjZFC3h(7@1~4@%C9hb*=F$tC=-y>p#B$ZIsr_mF5xicLfsnNgVGIV+ z*JhD=h-xpg2sUUTe=7-ue?tUT`EvEC+OLE|Me>45p4RVOdTZ>pklX!OPjI&1Yq#MN zOf?X9%=P!vqs5&sTGOQ=+x`D;%Yqg8vrcA}DPs$&?AcQ)V7a(oDwpf6-{z;+dYh4s zRSB$H>P=1lH-Xo+0w{Y{GyuPMjYw7T{qZ13MNaVMkqs?e^DU79{)`w}$C|wn^Yv|n zmexCjr|f7Q1p}n}MZFdpCsP6F zBOnIw4`VC6+VEGGy20DQS%__9TD|}}g2dG}4~R{{RabzkYU#hrniIA!^iaAr+QctJ zYz$KA??4$EAEac{Iu4#71;49DUGz7rRtr2o7r`yP9u}AKyyb=c>{&q4$q|qabTQ(a zR%jeu`zv8seXaeIv@M(02-$Z?MD1Mt7Q1IJ^Hr1qHAKE}`#0xf#8@*KU~_)+JX!lq z#Nwd#U!jYdvkKiQ5U(G~PcX4$h#7wvCO%u+w^(Eawu+5fw2?GeR4EHCCe zY94Ft=WKcc22fs#-P{_$65PpQ-U;HzrbXe}0V3u5BfKZg8iOrWIE>&5SV?nd5WS?vp}jC@Zk5ySvq`v@wwgSj**VDYMd} z)*pi_0K?|z=YNidtle=Rsg=W$tP5OdPGojy8WaU7v8n%cxzgXO5+JsS{;SWa{<(aR zYh1nXOTjD`QoDNn*S&8-cefAy`nUE!-E{wd{Yaf@s{6abJ9n79_xHZvKv;#Me7}^| z|3Ux#FFVc#Ze9F8E64ut)As-O&i~hkegABU|KY2@|Nf7r!z*E7Ok_g|ATw+Y7u|i} zK3OiduSVqfaCNu@hQ{I}0?rMwmrLMKl->fQjVuDpHSyq&N8Pjy}hP}(M&qN0zbfk0}nhmLR@ z2exp^8KLLt5^p~k=$!YP8~rCqn^Ao8$OKfFlH2E8SeZN1QdW7M!i|$erSw zcF$>g3DnH6_hR=&QV4vx)8oFVB|VJn;Un)5YXj4zu|+B}9N$940V%7rcF4WxbwaCQ zf9$;ijb4pY`lUb2H2(*0@q!cc#}~=|0~{+}fTMT}Ta3*t)9#OP=ch{SsV~^cJkM7# z-NwWf_-Usf`-{Bk)J_5xN9$^AikWzWK<^Sd|;oc<1l=3{W>zN{pHPyX8}NCChwx7)Su6No^ZEa^!7-q_H7Exb$tyt|^5X@u<)moH z+3AJN8NpH(Vap=Oe<=_NTkpzv*%2HQauz~M7N5>4^WBkt2AoFuCbgBeZ8p(dcL~p) zbtht~n%D?JaiqwL8t7J7ZL+@drl&iTiX|XWYkH80JCchTZ!{Rom-!sPu!AQkM#&V4 ztlD1t;Ho~sIzZn#NU_+e-o{X^)OHL#N6Ks0Z*j`la{k^<826n;Ds>vUXi|4Kp#~wk zIUb>6C5a^%g-Ox-+NH>26L9i#GdIw?h_#uOuZmV3Zb8>gBc$31=>|4KQmW)m;@x70 z&G}e@JuK&}_5zvIIV@!r95NuWm`K7@?JT`-vSr{4`($l8C*;g1fqnA6XL~?utIKm) z^bX2ZHC%7H=$F@v<#YHh(=N}PwIJAb&|@(X8z0?^I;HV_+dR7#X?64?e~yPkK5RC< zWFAqX7{z#eVHwm_o!bfb$E#~#V~9kSddaR!h12~#Vxllm?o6^93!D(CSj7*Cp5wJA zR#EJoUpcGv7=YDT<9x)hPZ3tb1d$M5{CW|H-Si0Ws%`;36fksw7$U(6-4&&^^0DEN zNE7BPWm<<#+E5Al=8TlVwl=P`tN0?X^r%oig6Tg{74nnp7J}X9L|tau#`x~28f_?_ zPJ^*N^Uzg4;2Y^1q_V71P>C(h@TlFzR3*%6)R9RxD{!VSr%$Cwe3166WS8tvS9dzm e&(E)w&9me5?oh*11_SAPyZj8G7Z)M literal 0 HcmV?d00001 From 227513b646c7db2de6b6f592e0933a8135a9d707 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 20 May 2021 16:04:34 +0200 Subject: [PATCH 051/106] Delivery in LibraryLoader - removed unwanted file --- vendor/debug_library_loader.py | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 vendor/debug_library_loader.py diff --git a/vendor/debug_library_loader.py b/vendor/debug_library_loader.py deleted file mode 100644 index 1bbd963f16..0000000000 --- a/vendor/debug_library_loader.py +++ /dev/null @@ -1,31 +0,0 @@ -import os -import pyblish -import pyblish.cli -import pyblish.plugin - -os.environ["AVALON_MONGO"] = "mongodb://localhost:27017" -os.environ["OPENPYPE_MONGO"] = "mongodb://localhost:27017" -os.environ["AVALON_DB"] = "avalon" -os.environ["OPENPYPE_DATABASE_NAME"] = "avalon" -os.environ["AVALON_TIMEOUT"] = '3000' -os.environ["OPENPYPE_DEBUG"] = "3" -os.environ["AVALON_CONFIG"] = "pype" -os.environ["AVALON_ASSET"] = "Jungle" -os.environ["AVALON_PROJECT"] = "petr_second" - -from avalon.tools.libraryloader import show -import openpype -openpype.install() - -# REGISTERED = pyblish.plugin.registered_paths() -# PACKAGEPATH = pyblish.lib.main_package_path() -# ENVIRONMENT = os.environ.get("PYBLISHPLUGINPATH", "") -# PLUGINPATH = os.path.join(PACKAGEPATH, '..', 'tests', 'plugins') -# -# REGISTERED.append("C:\\Users\\petrk\\PycharmProjects\\Pype3.0\\pype\\openpype\\plugins\\load") -# pyblish.plugin.deregister_all_paths() -# for path in REGISTERED: -# register_plugin_path(avalon.Loader, LOAD_PATH) -# pyblish.plugin.register_plugin_path(path) - -show(debug=True, show_projects=True, show_libraries=True) \ No newline at end of file From 0afa78f0e08386357245b4ed5ef0dabbf8bbe97d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 20 May 2021 17:01:37 +0200 Subject: [PATCH 052/106] Delivery in LibraryLoader - fix no templates --- openpype/plugins/load/delivery.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index 6c83886686..f2dc94c636 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -97,7 +97,6 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): template_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) root_line_edit = QtWidgets.QLineEdit() - root_line_edit.setText("c:/PETR_TEST") # TEMP repre_checkboxes_layout = QtWidgets.QFormLayout() repre_checkboxes_layout.setContentsMargins(10, 5, 5, 20) @@ -120,6 +119,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): input_layout.addRow("Representations", repre_checkboxes_layout) btn_delivery = QtWidgets.QPushButton("Deliver") + btn_delivery.setEnabled(bool(dropdown.currentText())) progress_bar = QtWidgets.QProgressBar(self) progress_bar.setMinimum = 0 @@ -289,6 +289,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): name = self.dropdown.currentText() template_value = self.templates.get(name) if template_value: + self.btn_delivery.setEnabled(True) self.template_label.setText(template_value) def _update_progress(self, uploaded): From a32624f22bbf75d964d9b235a05a903ea5e336f3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 17:10:46 +0200 Subject: [PATCH 053/106] fake blender addons from blender user scripts --- openpype/hosts/blender/api/lib.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index 6aa1cb46ac..e4d063a583 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -3,6 +3,7 @@ import traceback import importlib import bpy +import addon_utils def load_scripts(paths): @@ -74,6 +75,23 @@ def load_scripts(paths): for mod in bpy.utils.modules_from_path(path, loaded_modules): test_register(mod) + addons_paths = [] + for base_path in paths: + addons_path = os.path.join(base_path, "addons") + if os.path.exists(addons_path): + addons_paths.append(addons_path) + + if addons_paths: + # Fake addons + origin_paths = addon_utils.paths + + def new_paths(): + paths = origin_paths() + addons_paths + return paths + + addon_utils.paths = new_paths + addon_utils.modules_refresh() + # load template (if set) if any(bpy.utils.app_template_paths()): import bl_app_template_utils From df5c4aebd8cd2adc31144eaecb3819c9561421ee Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 17:13:23 +0200 Subject: [PATCH 054/106] also prepend modules to sys path --- openpype/hosts/blender/api/lib.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index e4d063a583..fe5d3f93e9 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -78,8 +78,12 @@ def load_scripts(paths): addons_paths = [] for base_path in paths: addons_path = os.path.join(base_path, "addons") - if os.path.exists(addons_path): - addons_paths.append(addons_path) + if not os.path.exists(addons_path): + continue + addons_paths.append(addons_path) + addons_module_path = os.path.join(addons_path, "modules") + if os.path.exists(addons_module_path): + bpy.utils._sys_path_ensure_prepend(addons_module_path) if addons_paths: # Fake addons From be3b277c2de5bf58bfab294f019657681cef8b7c Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 20 May 2021 17:46:56 +0200 Subject: [PATCH 055/106] Delivery in LibraryLoader - fixes for missing source files Fix for double dot in file name --- openpype/lib/delivery.py | 19 ++++++++++++++++++- openpype/plugins/load/delivery.py | 7 +------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/openpype/lib/delivery.py b/openpype/lib/delivery.py index d5b18bca0a..9e87d854f5 100644 --- a/openpype/lib/delivery.py +++ b/openpype/lib/delivery.py @@ -125,7 +125,7 @@ def check_destination_path(repre_id, def process_single_file( - src_path, _repre, anatomy, template_name, anatomy_data, format_dict, + src_path, repre, anatomy, template_name, anatomy_data, format_dict, report_items, log ): """Copy single file to calculated path based on template @@ -143,6 +143,12 @@ def process_single_file( Returns: (collections.defaultdict , int) """ + if not os.path.exists(src_path): + msg = "{} doesn't exist for {}".format(src_path, + repre["_id"]) + report_items["Source file was not found"].append(msg) + return report_items, 0 + anatomy_filled = anatomy.format(anatomy_data) if format_dict: template_result = anatomy_filled["delivery"][template_name] @@ -150,6 +156,9 @@ def process_single_file( else: delivery_path = anatomy_filled["delivery"][template_name] + # context.representation could be .psd + delivery_path = delivery_path.replace("..", ".") + delivery_folder = os.path.dirname(delivery_path) if not os.path.exists(delivery_folder): os.makedirs(delivery_folder) @@ -186,6 +195,12 @@ def process_sequence( Returns: (collections.defaultdict , int) """ + if not os.path.exists(src_path): + msg = "{} doesn't exist for {}".format(src_path, + repre["_id"]) + report_items["Source file was not found"].append(msg) + return report_items, 0 + dir_path, file_name = os.path.split(str(src_path)) context = repre["context"] @@ -198,6 +213,8 @@ def process_sequence( return report_items, 0 ext = "." + ext + # context.representation could be .psd + ext = ext.replace("..", ".") src_collections, remainder = clique.assemble(os.listdir(dir_path)) src_collection = None diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index f2dc94c636..360ef4af82 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -28,7 +28,7 @@ class Delivery(api.SubsetLoader): representations = ["*"] families = ["*"] - # tool_names = ["library_loader"] + tool_names = ["library_loader"] label = "Deliver Versions" order = 35 @@ -173,11 +173,6 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): continue repre_path = path_from_represenation(repre, anatomy) - if not os.path.exists(repre_path): - msg = "{} doesn't exist for {}".format(repre_path, - repre["_id"]) - report_items["Source file was not found"].append(msg) - continue anatomy_data = copy.deepcopy(repre["context"]) new_report_items = check_destination_path(str(repre["_id"]), From c496386b47ef126bda0a6623f0411dc4920ac79c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 19:59:54 +0200 Subject: [PATCH 056/106] ok btn has same width as cancel btn --- openpype/tools/settings/settings/color_widget.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index b84c8dd9cc..7aa3a4bba3 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -141,9 +141,18 @@ class ColorDialog(QtWidgets.QDialog): cancel_btn.clicked.connect(self.on_cancel_clicked) self.picker_widget = picker_widget + self.ok_btn = ok_btn + self.cancel_btn = cancel_btn self._result = None + def showEvent(self, event): + super(ColorDialog, self).showEvent(event) + + btns_width = max(self.ok_btn.width(), self.cancel_btn.width()) + self.ok_btn.setFixedWidth(btns_width) + self.cancel_btn.setFixedWidth(btns_width) + def on_ok_clicked(self): self._result = self.picker_widget.color() self.close() From 69ed30f15c5fd8c5f7c19c2a8e34541a56a390e3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 20:23:26 +0200 Subject: [PATCH 057/106] colorpicker widget is one big grid --- .../color_widgets/color_picker_widget.py | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index fd0f31e342..27b9f8fc82 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -21,31 +21,23 @@ class ColorPickerWidget(QtWidgets.QWidget): super(ColorPickerWidget, self).__init__(parent) top_part = QtWidgets.QWidget(self) - left_side = QtWidgets.QWidget(top_part) # Color triangle - color_triangle = QtColorTriangle(left_side) + color_triangle = QtColorTriangle(self) - alpha_slider_proxy = QtWidgets.QWidget(left_side) + alpha_slider_proxy = QtWidgets.QWidget(self) alpha_slider = AlphaSlider(QtCore.Qt.Horizontal, alpha_slider_proxy) alpha_slider_layout = QtWidgets.QHBoxLayout(alpha_slider_proxy) alpha_slider_layout.setContentsMargins(5, 5, 5, 5) alpha_slider_layout.addWidget(alpha_slider, 1) - left_layout = QtWidgets.QVBoxLayout(left_side) - left_layout.setContentsMargins(0, 0, 0, 0) - left_layout.addWidget(color_triangle, 1) - left_layout.addWidget(alpha_slider_proxy, 0) - - right_side = QtWidgets.QWidget(top_part) - # Eye picked widget pick_widget = PickScreenColorWidget() pick_widget.setMaximumHeight(50) # Color pick button - btn_pick_color = QtWidgets.QPushButton(right_side) + btn_pick_color = QtWidgets.QPushButton(self) icon_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "eyedropper.png" @@ -54,44 +46,52 @@ class ColorPickerWidget(QtWidgets.QWidget): btn_pick_color.setToolTip("Pick a color") # Color preview - color_view = ColorViewer(right_side) + color_view = ColorViewer(self) color_view.setMaximumHeight(50) - row = 0 - right_layout = QtWidgets.QGridLayout(right_side) - right_layout.setContentsMargins(0, 0, 0, 0) - right_layout.addWidget(btn_pick_color, row, 0) - right_layout.addWidget(color_view, row, 1) + alpha_inputs = AlphaInputs(self) color_inputs_color = QtGui.QColor() col_inputs_by_label = [ - ("HEX", HEXInputs(color_inputs_color, right_side)), - ("RGB", RGBInputs(color_inputs_color, right_side)), - ("HSL", HSLInputs(color_inputs_color, right_side)), - ("HSV", HSVInputs(color_inputs_color, right_side)) + ("HEX", HEXInputs(color_inputs_color, self)), + ("RGB", RGBInputs(color_inputs_color, self)), + ("HSL", HSLInputs(color_inputs_color, self)), + ("HSV", HSVInputs(color_inputs_color, self)) ] + + layout = QtWidgets.QGridLayout(self) + empty_col = 1 + label_col = empty_col + 1 + input_col = label_col + 1 + empty_widget = QtWidgets.QWidget(self) + empty_widget.setFixedWidth(10) + layout.addWidget(empty_widget, 0, empty_col) + + row = 0 + layout.addWidget(btn_pick_color, row, label_col) + layout.addWidget(color_view, row, input_col) + row += 1 + color_input_fields = [] for label, input_field in col_inputs_by_label: - row += 1 - right_layout.addWidget(QtWidgets.QLabel(label, right_side), row, 0) - right_layout.addWidget(input_field, row, 1) + layout.addWidget(QtWidgets.QLabel(label, self), row, label_col) + layout.addWidget(input_field, row, input_col) input_field.value_changed.connect( self._on_color_input_value_change ) color_input_fields.append(input_field) + row += 1 + layout.addWidget(color_triangle, 0, 0, row + 1, 1) + layout.setRowStretch(row, 1) row += 1 - alpha_inputs = AlphaInputs(right_side) - right_layout.addWidget(QtWidgets.QLabel("Alpha", right_side), row, 0) - right_layout.addWidget(alpha_inputs, row, 1) + layout.addWidget(alpha_slider_proxy, row, 0) + + layout.addWidget(QtWidgets.QLabel("Alpha", self), row, label_col) + layout.addWidget(alpha_inputs, row, input_col) row += 1 - right_layout.setRowStretch(row, 1) - - layout = QtWidgets.QHBoxLayout(self) - layout.setSpacing(20) - layout.addWidget(left_side, 1) - layout.addWidget(right_side, 0) + layout.setRowStretch(row, 1) color_view.set_color(color_triangle.cur_color) From c77094aeb6bd5666d791c4486834123f06780362 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 20:52:44 +0200 Subject: [PATCH 058/106] nicer view of color in setting ui --- .../tools/settings/settings/color_widget.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index 7aa3a4bba3..fa0cd2c989 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -80,7 +80,7 @@ class ColorViewer(QtWidgets.QWidget): def checkerboard(self): if not self._checkerboard: - self._checkerboard = draw_checkerboard_tile() + self._checkerboard = draw_checkerboard_tile(self.height() / 4) return self._checkerboard def color(self): @@ -101,15 +101,21 @@ class ColorViewer(QtWidgets.QWidget): def paintEvent(self, event): rect = event.rect() - # Paint everything to pixmap as it has transparency - pix = QtGui.QPixmap(rect.width(), rect.height()) - pix_painter = QtGui.QPainter(pix) - pix_painter.drawTiledPixmap(rect, self.checkerboard()) - pix_painter.fillRect(rect, self.actual_color) - pix_painter.end() - painter = QtGui.QPainter(self) - painter.drawPixmap(rect, pix) + painter.setRenderHint(QtGui.QPainter.Antialiasing) + + radius = rect.height() / 2 + rounded_rect = QtGui.QPainterPath() + rounded_rect.addRoundedRect(QtCore.QRectF(rect), radius, radius) + painter.setClipPath(rounded_rect) + + pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 67)) + pen.setWidth(1) + painter.setPen(pen) + painter.drawTiledPixmap(rect, self.checkerboard()) + painter.fillRect(rect, self.actual_color) + painter.drawPath(rounded_rect) + painter.end() From c4a7a3ac5013476cab7079c31b6d614422551bea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 21:16:46 +0200 Subject: [PATCH 059/106] added border to color viewer in the dialog --- openpype/widgets/color_widgets/color_view.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/openpype/widgets/color_widgets/color_view.py b/openpype/widgets/color_widgets/color_view.py index d6d7f0a666..8644281a1d 100644 --- a/openpype/widgets/color_widgets/color_view.py +++ b/openpype/widgets/color_widgets/color_view.py @@ -42,7 +42,7 @@ class ColorViewer(QtWidgets.QWidget): def checkerboard(self): if not self._checkerboard: - self._checkerboard = draw_checkerboard_tile() + self._checkerboard = draw_checkerboard_tile(4) return self._checkerboard def color(self): @@ -70,15 +70,14 @@ class ColorViewer(QtWidgets.QWidget): self.update() def paintEvent(self, event): - rect = event.rect() - - # Paint everything to pixmap as it has transparency - pix = QtGui.QPixmap(rect.width(), rect.height()) - pix_painter = QtGui.QPainter(pix) - pix_painter.drawTiledPixmap(rect, self.checkerboard()) - pix_painter.fillRect(rect, self.actual_color) - pix_painter.end() + clip_rect = event.rect() + rect = clip_rect.adjusted(0, 0, -1, -1) painter = QtGui.QPainter(self) - painter.drawPixmap(rect, pix) + painter.setClipRect(clip_rect) + painter.drawTiledPixmap(rect, self.checkerboard()) + painter.setBrush(self.actual_color) + pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 67)) + painter.setPen(pen) + painter.drawRect(rect) painter.end() From 0d40c89f471f6abccfbe6ae58667bb5304086422 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 20 May 2021 21:18:16 +0200 Subject: [PATCH 060/106] removed unused variable --- openpype/widgets/color_widgets/color_picker_widget.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 27b9f8fc82..81ec1f87aa 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -20,8 +20,6 @@ class ColorPickerWidget(QtWidgets.QWidget): def __init__(self, color=None, parent=None): super(ColorPickerWidget, self).__init__(parent) - top_part = QtWidgets.QWidget(self) - # Color triangle color_triangle = QtColorTriangle(self) From 21076a76bf45222fae054ac5fdbd6472cd9f705c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 21 May 2021 11:10:09 +0200 Subject: [PATCH 061/106] removed review creator --- .../tvpaint/plugins/create/create_review.py | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 openpype/hosts/tvpaint/plugins/create/create_review.py diff --git a/openpype/hosts/tvpaint/plugins/create/create_review.py b/openpype/hosts/tvpaint/plugins/create/create_review.py deleted file mode 100644 index 88b039c8e4..0000000000 --- a/openpype/hosts/tvpaint/plugins/create/create_review.py +++ /dev/null @@ -1,19 +0,0 @@ -from avalon.tvpaint import pipeline -from openpype.hosts.tvpaint.api import plugin - - -class CreateReview(plugin.Creator): - """Review for global review of all layers.""" - name = "review" - label = "Review" - family = "review" - icon = "cube" - defaults = ["Main"] - - def process(self): - instances = pipeline.list_instances() - for instance in instances: - if instance["family"] == self.family: - self.log.info("Review family is already Created.") - return - super(CreateReview, self).process() From d978c9c22960174a9e914f321f8e6fa5161c7ace Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 21 May 2021 11:13:20 +0200 Subject: [PATCH 062/106] always create review instance if is not in instances of workfile metadata --- .../plugins/publish/collect_instances.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openpype/hosts/tvpaint/plugins/publish/collect_instances.py b/openpype/hosts/tvpaint/plugins/publish/collect_instances.py index 27bd8e9ede..61cf7eb780 100644 --- a/openpype/hosts/tvpaint/plugins/publish/collect_instances.py +++ b/openpype/hosts/tvpaint/plugins/publish/collect_instances.py @@ -17,6 +17,20 @@ class CollectInstances(pyblish.api.ContextPlugin): json.dumps(workfile_instances, indent=4) )) + # Backwards compatibility for workfiles that already have review + # instance in metadata. + review_instance_exist = False + for instance_data in workfile_instances: + if instance_data["family"] == "review": + review_instance_exist = True + break + + # Fake review instance if review was not found in metadata families + if not review_instance_exist: + workfile_instances.append( + self._create_review_instance_data(context) + ) + for instance_data in workfile_instances: instance_data["fps"] = context.data["sceneFps"] @@ -90,6 +104,16 @@ class CollectInstances(pyblish.api.ContextPlugin): instance, json.dumps(instance.data, indent=4) )) + def _create_review_instance_data(self, context): + """Fake review instance data.""" + + return { + "family": "review", + "asset": context.data["workfile_context"]["asset"], + # Dummy subset name + "subset": "reviewMain" + } + def create_render_layer_instance(self, context, instance_data): name = instance_data["name"] # Change label From 632e57d21c110b44cb8494efcffe0ef9afb8b020 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 21 May 2021 11:13:40 +0200 Subject: [PATCH 063/106] skip instances without uuid on instance toggle as review instancemay not have uuid --- openpype/hosts/tvpaint/api/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/tvpaint/api/__init__.py b/openpype/hosts/tvpaint/api/__init__.py index bd9ef51a76..57a03d38b7 100644 --- a/openpype/hosts/tvpaint/api/__init__.py +++ b/openpype/hosts/tvpaint/api/__init__.py @@ -19,6 +19,10 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create") def on_instance_toggle(instance, old_value, new_value): + # Review may not have real instance in wokrfile metadata + if not instance.data.get("uuid"): + return + instance_id = instance.data["uuid"] found_idx = None current_instances = pipeline.list_instances() From c8d6519f5ab23008708a3271140b54cd8e645265 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 21 May 2021 11:20:14 +0200 Subject: [PATCH 064/106] reformat and update commands and usage --- website/docs/admin_distribute.md | 24 ++- website/docs/admin_openpype_commands.md | 221 +++++++++++++----------- website/docs/admin_use.md | 58 ++++++- 3 files changed, 195 insertions(+), 108 deletions(-) diff --git a/website/docs/admin_distribute.md b/website/docs/admin_distribute.md index b0ab71e2f3..b574a21cb2 100644 --- a/website/docs/admin_distribute.md +++ b/website/docs/admin_distribute.md @@ -41,10 +41,26 @@ version to run for the artist, until a higher version is detected in the update #### Manual Updates If for some reason you don't want to use the automatic updates, you can distribute your -zips manually. Your artist will then have to unpack them to the correct place on their disk. +zips manually. Your artist will then have to put them to the correct place on their disk. +Zips will be automatically unzipped there. The default locations are: -- Windows: `C:\Users\%USERNAME%\AppData\Local\pypeclub\openpype` -- Linux: ` ` -- Mac: ` ` +- Windows: `%LOCALAPPDATA%\pypeclub\openpype` +- Linux: `~/.local/share/pypeclub/openpype` +- Mac: `~/Library/Application Support/pypeclub/openpype` + + +### Staging vs. Production +You can have version of OpenPype with experimental features you want to try somewhere but you +don't want to disrupt your production. You can tag version as **staging** simply by appending `+staging` +to its name. + +So if you have OpenPype version like `OpenPype-v3.0.0.zip` just name it `OpenPype-v3.0.0+staging.zip`. +When both these versions are present, production one will always take precedence over staging. + +You can run OpenPype with `--use-staging` argument to add use staging versions. + +:::note +Running staging version is identified by orange **P** icon in system tray. +::: \ No newline at end of file diff --git a/website/docs/admin_openpype_commands.md b/website/docs/admin_openpype_commands.md index 6e187c3c8a..324e0e8481 100644 --- a/website/docs/admin_openpype_commands.md +++ b/website/docs/admin_openpype_commands.md @@ -4,137 +4,154 @@ title: OpenPype Commands Reference sidebar_label: OpenPype Commands --- +:::info +You can substitute `openpype_console` with `poetry run python start.py` if you want to run it +directly from sources. +::: -## `tray` +:::note +Running OpenPype without any commands will default to `tray`. +::: -To launch Tray: -```sh -pype tray +## Common arguments +`--use-version` to specify explicit version to use: +```shell +openpype_console --use-version=3.0.0-foo+bar ``` -### `--debug` +`--use-staging` - to use staging versions of OpenPype. + +For more information [see here](admin_use#run-openpype). + +## Commands + +| Command | Description | Arguments | +| --- | --- |: --- :| +| tray | Launch OpenPype Tray. | [📑](#tray-arguments) +| eventserver | This should be ideally used by system service (such as systemd or upstart on linux and window service). | [📑](#eventserver-arguments) | +| launch | Launch application in Pype environment. | [📑](#launch-arguments) | +| publish | Pype takes JSON from provided path and use it to publish data in it. | [📑](#publish-arguments) | +| extractenvironments | Extract environment variables for entered context to a json file. | [📑](#extractenvironments-arguments) | +| run | Execute given python script within OpenPype environment. | [📑](#run-arguments) | +| projectmanager | Launch Project Manager UI | [📑](#projectmanager-arguments) | +| settings | Open Settings UI | [📑](#settings-arguments) | +| standalonepublisher | Open Standalone Publisher UI | [📑](#standalonepublisher-arguments) | + +--- +### `tray` arguments {#tray-arguments} +| Argument | Description | +| --- | --- | +| `--debug` | print verbose information useful for debugging (works with `openpype_console`) | To launch Tray with debugging information: -```sh -pype tray --debug +```shell +openpype_console tray --debug ``` +--- +### `launch` arguments {#eventserver-arguments} +You have to set either proper environment variables to provide URL and credentials or use +option to specify them. If you use `--store_credentials` provided credentials will be stored for later use. --------------------- - - -## `eventserver` - -This command launches ftrack event server. - -This should be ideally used by system service (such us systemd or upstart -on linux and window service). - -You have to set either proper environment variables to provide URL and -credentials or use option to specify them. If you use `--store_credentials` -provided credentials will be stored for later use. +| Argument | Description | +| --- | --- | +| `--debug` | print debug info | +| `--ftrack-url` | URL to ftrack server (can be set with `FTRACK_SERVER`) | +| `--ftrack-user` |user name to log in to ftrack (can be set with `FTRACK_API_USER`) | +| `--ftrack-api-key` | ftrack api key (can be set with `FTRACK_API_KEY`) | +| `--ftrack-events-path` | path to event server plugins (can be set with `FTRACK_EVENTS_PATH`) | +| `--no-stored-credentials` | will use credential specified with options above | +| `--store-credentials` | will store credentials to file for later use | +| `--legacy` | run event server without mongo storing | +| `--clockify-api-key` | Clockify API key (can be set with `CLOCKIFY_API_KEY`) | +| `--clockify-workspace` | Clockify workspace (can be set with `CLOCKIFY_WORKSPACE`) | To run ftrack event server: -```sh -pype eventserver --ftrack-url= --ftrack-user= --ftrack-api-key= --ftrack-events-path= --no-stored-credentials --store-credentials +```shell +openpype_console eventserver --ftrack-url= --ftrack-user= --ftrack-api-key= --ftrack-events-path= --no-stored-credentials --store-credentials ``` +--- +### `launch` arguments {#launch-arguments} -### `--debug` -- print debug info - -### `--ftrack-url` -- URL to ftrack server - -### `--ftrack-user` -- user name to log in to ftrack - -### `--ftrack-api-key` -- ftrack api key - -### `--ftrack-events-path` -- path to event server plugins - -### `--no-stored-credentials` -- will use credential specified with options above - -### `--store-credentials` -- will store credentials to file for later use - --------------------- - -## `launch` - -Launch application in Pype environment. - -### `--app` - -Application name - this should be the same as it's [defining toml](admin_hosts#launchers) file (without .toml) - -### `--project` -Project name - -### `--asset` -Asset name - -### `--task` -Task name - -### `--tools` -*Optional: Additional tools environment files to add* - -### `--user` -*Optional: User on behalf to run* - -### `--ftrack-server` / `-fs` -*Optional: Ftrack server URL* - -### `--ftrack-user` / `-fu` -*Optional: Ftrack user* - -### `--ftrack-key` / `-fk` -*Optional: Ftrack API key* +| Argument | Description | +| --- | --- | +| `--app` | Application name - this should be the key for application from Settings. | +| `--project` | Project name (default taken from `AVALON_PROJECT` if set) | +| `--asset` | Asset name (default taken from `AVALON_ASSET` if set) | +| `--task` | Task name (default taken from `AVALON_TASK` is set) | +| `--tools` | *Optional: Additional tools to add* | +| `--user` | *Optional: User on behalf to run* | +| `--ftrack-server` / `-fs` | *Optional: Ftrack server URL* | +| `--ftrack-user` / `-fu` | *Optional: Ftrack user* | +| `--ftrack-key` / `-fk` | *Optional: Ftrack API key* | For example to run Python interactive console in Pype context: -```sh +```shell pype launch --app python --project my_project --asset my_asset --task my_task ``` --------------------- +--- +### `publish` arguments {#publish-arguments} +| Argument | Description | +| --- | --- | +| `--debug` | print more verbose infomation | -## `publish` - -Pype takes JSON from provided path and use it to publish data in it. -```sh +```shell pype publish ``` -### `--debug` -- print more verbose infomation - --------------------- - -## `extractenvironments` - -Extract environment variables for entered context to a json file. +--- +### `extractenvironments` arguments {#extractenvironments-arguments} Entered output filepath will be created if does not exists. - All context options must be passed otherwise only openpype's global environments will be extracted. +Context options are `project`, `asset`, `task`, `app` -Context options are "project", "asset", "task", "app" +| Argument | Description | +| --- | --- | +| `output_json_path` | Absolute path to the exported json file | +| `--project` | Project name | +| `--asset` | Asset name | +| `--task` | Task name | +| `--app` | Application name | -### `output_json_path` -- Absolute path to the exported json file +```shell +openpype_console /home/openpype/env.json --project Foo --asset Bar --task modeling --app maya-2019 +``` -### `--project` -- Project name +--- +### `run` arguments {#run-arguments} -### `--asset` -- Asset name +| Argument | Description | +| `--script` | run specified python script | -### `--task` -- Task name +Note that additional arguments are passed to the script. -### `--app` -- Application name \ No newline at end of file +```shell +openpype_console run --script /foo/bar/baz.py arg1 arg2 +``` + +--- +### `projectmanager` arguments {#projectmanager-arguments} +`projectmanager` has no command-line arguments. +```shell +openpype_console projectmanager +``` + +--- +### `settings` arguments {#settings-arguments} + +| Argument | Description | +| `-d` / `--dev` | Run settings in developer mode. | + +```shell +openpypeconsole settings +``` + +--- +### `standalonepublisher` arguments {#standalonepublisher-arguments} +`standalonepublisher` has no command-line arguments. +```shell +openpype_console standalonepublisher +``` \ No newline at end of file diff --git a/website/docs/admin_use.md b/website/docs/admin_use.md index 376e9397a1..4a2b56e6f4 100644 --- a/website/docs/admin_use.md +++ b/website/docs/admin_use.md @@ -32,6 +32,60 @@ Once artist enters the Mongo URL address, OpenPype will remember the connection next launch, so it is a one time process.From that moment OpenPype will do it's best to always keep up to date with the latest studio updates. -If the launch was successfull, the artist should see a green OpenPype logo in their +If the launch was successful, the artist should see a green OpenPype logo in their tray menu. Keep in mind that on Windows this icon might be hidden by default, in which case, -the artist can simply drag the icon down to the tray. \ No newline at end of file +the artist can simply drag the icon down to the tray. + +You can use following command line arguments: + +`--use-version` - to specify version you want to run explicitly, like: +```shell +openpype_console --use-version=3.0.1 +``` + +`--use-staging` - to specify you prefer staging version. In that case it will be used +(if found) instead of production one. + +### Details +When you run OpenPype from executable, few check are made: + +#### Check for mongoDB database connection +MongoDB connection string is in format: +```shell +mongodb[+srv]://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options] +``` +More on that in [MongoDB documentation](https://docs.mongodb.com/manual/reference/connection-string/). + +Example connection strings are `mongodb://local-unprotected-server:2707` or +`mongodb+srv://user:superpassword:some.mongodb-hosted-on.net:27072`. + +When you start OpenPype first time, Igniter UI will show up and ask you for this string. It will then +save it in secure way to your systems keyring - on Windows it is **Credential Manager**, on MacOS it will use its +**Keychain**, on Linux it can be **GNOME Keyring** or other software, depending on your distribution. + +This can be also set beforehand with environment variable `OPENPYPE_MONGO`. If set it takes precedence +over the one set in keyring. + +#### Check for OpenPype version path +When connection to MongoDB is made, OpenPype will get various settings from there - one among them is +directory location where OpenPype versions are stored. If this directory exists OpenPype tries to +find the latest version there and if succeed it will copy it to user system and use it. + +This path can be set is OpenPype settings, but also with environment variable `OPENPYPE_PATH` or with +`openPypePath` in json file located application directory depending on your system. + +- Windows: `%LOCALAPPDATA%\pypeclub\openpype` +- Linux: `~/.local/share/pypeclub/openpype` +- Mac: `~/Library/Application Support/pypeclub/openpype` + +### Runtime provided environment variables +OpenPype is providing following environment variables for its subprocesses that can be used +in various places, like scripting, etc. + +- `OPENPYPE_ROOT` - this will point to currently running code. +- `OPENPYPE_VERSION` - string of current version - like `3.0.0-foo+bar` +- `OPENPYPE_REPOS_ROOT` - this is path where all components can be find (like Avalon Core and OpenPype) +- `OPENPYPE_DATABASE_NAME` - database name in MongoDB used by OpenPype +- `OPENPYPE_EXECUTABLE` - path to executable used to run OpenPype - when run from sources it will point +to **python** stored in virtual environment. If run from frozen code, it will point to either `openpype_gui` or + `openpype_console`. From 5cea400239ee0dcf1c68aee01339c55366514e6a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 21 May 2021 11:58:23 +0200 Subject: [PATCH 065/106] Delivery in LibraryLoader - small fixes in documentation and imports --- openpype/plugins/load/delivery.py | 1 - website/docs/artist_tools.md | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index 360ef4af82..f4e74f17a0 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -1,5 +1,4 @@ import collections -import os import copy from avalon import api, style diff --git a/website/docs/artist_tools.md b/website/docs/artist_tools.md index 603e5fe590..f099b48a9a 100644 --- a/website/docs/artist_tools.md +++ b/website/docs/artist_tools.md @@ -177,12 +177,12 @@ Library loader is extended [loader](#loader) which allows to load published subs -### Delivery loader ### +### Delivery Action ### Library Loader contains functionality to export any selected asset, subsets and their version to configurable folder. Delivery follows structure based on defined template, this template must be configured first by Admin in the Settings. -![delivery_loader](assets/tools/tools_delivery_loader.png) +![delivery_action](assets/tools/tools_delivery_loader.png) * Usage - Select all required subsets for export (you can change theirs versions by double clicking on 'Version' value) From 7efd2aeecea330ce985c819fbbb45ca6b689496d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Fri, 21 May 2021 13:02:44 +0200 Subject: [PATCH 066/106] enhance windows and add linux launcher --- tools/run_project_manager.ps1 | 42 ++++++++++++++ tools/run_projectmanager.sh | 103 ++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 tools/run_projectmanager.sh diff --git a/tools/run_project_manager.ps1 b/tools/run_project_manager.ps1 index 67c2d2eb5e..9886a80316 100644 --- a/tools/run_project_manager.ps1 +++ b/tools/run_project_manager.ps1 @@ -10,9 +10,51 @@ PS> .\run_project_manager.ps1 #> + +$art = @" + + . . .. . .. + _oOOP3OPP3Op_. . + .PPpo~. .. ~2p. .. .... . . + .Ppo . .pPO3Op.. . O:. . . . + .3Pp . oP3'. 'P33. . 4 .. . . . .. . . . + .~OP 3PO. .Op3 : . .. _____ _____ _____ + .P3O . oP3oP3O3P' . . . . / /./ /./ / + O3:. O3p~ . .:. . ./____/./____/ /____/ + 'P . 3p3. oP3~. ..P:. . . .. . . .. . . . + . ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . . + . '_ .. . . _OP3.. . .https://openpype.io.. . + ~P3.OPPPO3OP~ . .. . + . ' '. . .. . . . .. . + +"@ + +Write-Host $art -ForegroundColor DarkGreen + $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent $openpype_root = (Get-Item $script_dir).parent.FullName + +$env:_INSIDE_OPENPYPE_TOOL = "1" + +# make sure Poetry is in PATH +if (-not (Test-Path 'env:POETRY_HOME')) { + $env:POETRY_HOME = "$openpype_root\.poetry" +} +$env:PATH = "$($env:PATH);$($env:POETRY_HOME)\bin" + Set-Location -Path $openpype_root + +Write-Host ">>> " -NoNewline -ForegroundColor Green +Write-Host "Reading Poetry ... " -NoNewline +if (-not (Test-Path -PathType Container -Path "$openpype_root\.poetry\bin")) { + Write-Host "NOT FOUND" -ForegroundColor Yellow + Write-Host "*** " -NoNewline -ForegroundColor Yellow + Write-Host "We need to install Poetry create virtual env first ..." + & "$openpype_root\tools\create_env.ps1" +} else { + Write-Host "OK" -ForegroundColor Green +} + & poetry run python "$($openpype_root)\start.py" projectmanager Set-Location -Path $current_dir diff --git a/tools/run_projectmanager.sh b/tools/run_projectmanager.sh new file mode 100644 index 0000000000..312f321d67 --- /dev/null +++ b/tools/run_projectmanager.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +# Run OpenPype Settings GUI + + +art () { + cat <<-EOF + + . . .. . .. + _oOOP3OPP3Op_. . + .PPpo~· ·· ~2p. ·· ···· · · + ·Ppo · .pPO3Op.· · O:· · · · + .3Pp · oP3'· 'P33· · 4 ·· · · · ·· · · · + ·~OP 3PO· .Op3 : · ·· _____ _____ _____ + ·P3O · oP3oP3O3P' · · · · / /·/ /·/ / + O3:· O3p~ · ·:· · ·/____/·/____/ /____/ + 'P · 3p3· oP3~· ·.P:· · · ·· · · ·· · · · + · ': · Po' ·Opo'· .3O· . o[ by Pype Club ]]]==- - - · · + · '_ .. · . _OP3·· · ·https://openpype.io·· · + ~P3·OPPPO3OP~ · ·· · + · ' '· · ·· · · · ·· · + +EOF +} + +# Colors for terminal + +RST='\033[0m' # Text Reset + +# Regular Colors +Black='\033[0;30m' # Black +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Blue='\033[0;34m' # Blue +Purple='\033[0;35m' # Purple +Cyan='\033[0;36m' # Cyan +White='\033[0;37m' # White + +# Bold +BBlack='\033[1;30m' # Black +BRed='\033[1;31m' # Red +BGreen='\033[1;32m' # Green +BYellow='\033[1;33m' # Yellow +BBlue='\033[1;34m' # Blue +BPurple='\033[1;35m' # Purple +BCyan='\033[1;36m' # Cyan +BWhite='\033[1;37m' # White + +# Bold High Intensity +BIBlack='\033[1;90m' # Black +BIRed='\033[1;91m' # Red +BIGreen='\033[1;92m' # Green +BIYellow='\033[1;93m' # Yellow +BIBlue='\033[1;94m' # Blue +BIPurple='\033[1;95m' # Purple +BICyan='\033[1;96m' # Cyan +BIWhite='\033[1;97m' # White + + +############################################################################## +# Return absolute path +# Globals: +# None +# Arguments: +# Path to resolve +# Returns: +# None +############################################################################### +realpath () { + echo $(cd $(dirname "$1"); pwd)/$(basename "$1") +} + +# Main +main () { + + # Directories + openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}"))) + + _inside_openpype_tool="1" + + # make sure Poetry is in PATH + if [[ -z $POETRY_HOME ]]; then + export POETRY_HOME="$openpype_root/.poetry" + fi + export PATH="$POETRY_HOME/bin:$PATH" + + pushd "$openpype_root" > /dev/null || return > /dev/null + + echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c" + if [ -f "$POETRY_HOME/bin/poetry" ]; then + echo -e "${BIGreen}OK${RST}" + else + echo -e "${BIYellow}NOT FOUND${RST}" + echo -e "${BIYellow}***${RST} We need to install Poetry and virtual env ..." + . "$openpype_root/tools/create_env.sh" || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return; } + fi + + echo -e "${BIGreen}>>>${RST} Generating zip from current sources ..." + poetry run python "$openpype_root/start.py" projectmanager +} + +main From 85d3ce529e149b75321f7bfdb76081195be14610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Fri, 21 May 2021 13:04:18 +0200 Subject: [PATCH 067/106] set shell script executable --- tools/run_projectmanager.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/run_projectmanager.sh diff --git a/tools/run_projectmanager.sh b/tools/run_projectmanager.sh old mode 100644 new mode 100755 From 4c1d9e7e8d01d3af4df18385b35d6ef9596c81d2 Mon Sep 17 00:00:00 2001 From: jezscha Date: Fri, 21 May 2021 14:45:17 +0000 Subject: [PATCH 068/106] Create draft PR for #1412 From 526895a7e4d3f207492ea64fdb6139cff0444ea3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 21 May 2021 18:25:23 +0200 Subject: [PATCH 069/106] Delivery in LibraryLoader - fix for selection of repre without files only --- openpype/plugins/load/delivery.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index f4e74f17a0..53f8033c32 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -249,10 +249,14 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): size_selected = 0 for repre in self._representations: if repre["name"] in selected_repres: - for repre_file in repre.get("files", []): - + files = repre.get("files", []) + if not files: # for repre without files, cannot divide by 0 files_selected += 1 - size_selected += repre_file["size"] + size_selected += 0 + else: + for repre_file in files: + files_selected += 1 + size_selected += repre_file["size"] return files_selected, size_selected From cb6e09f2e19f84b539c68698740da5bb11312140 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 24 May 2021 11:23:07 +0200 Subject: [PATCH 070/106] Delivery in LibraryLoader - fix for wrong signature --- openpype/modules/ftrack/event_handlers_user/action_delivery.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_delivery.py b/openpype/modules/ftrack/event_handlers_user/action_delivery.py index 1cf2a701d8..7f2d9bb43a 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delivery.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delivery.py @@ -464,7 +464,8 @@ class Delivery(BaseAction): self.log.debug(debug_msg) anatomy_data = copy.deepcopy(repre["context"]) - repre_report_items = check_destination_path(anatomy, + repre_report_items = check_destination_path(repre["_id"], + anatomy, anatomy_data, datetime_data, anatomy_name) From 01cf1dde71d6f436b5d137c1e0527aec564ea35c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 24 May 2021 13:13:36 +0200 Subject: [PATCH 071/106] Nuke: set context callback on script load --- openpype/hosts/nuke/api/lib.py | 2 +- openpype/hosts/nuke/startup/menu.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index e6dde813a7..63cac0fd8b 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -1059,7 +1059,7 @@ class WorkfileSettings(object): # replace reset resolution from avalon core to pype's self.reset_frame_range_handles() # add colorspace menu item - # self.set_colorspace() + self.set_colorspace() def set_favorites(self): work_dir = os.getenv("AVALON_WORKDIR") diff --git a/openpype/hosts/nuke/startup/menu.py b/openpype/hosts/nuke/startup/menu.py index 9eb656afa9..c452acb709 100644 --- a/openpype/hosts/nuke/startup/menu.py +++ b/openpype/hosts/nuke/startup/menu.py @@ -1,6 +1,7 @@ from openpype.hosts.nuke.api.lib import ( on_script_load, - check_inventory_versions + check_inventory_versions, + WorkfileSettings ) import nuke @@ -9,8 +10,14 @@ from openpype.api import Logger log = Logger().get_logger(__name__) -nuke.addOnScriptSave(on_script_load) +# fix ffmpeg settings on script +nuke.addOnScriptLoad(on_script_load) + +# set checker for last versions on loaded containers nuke.addOnScriptLoad(check_inventory_versions) nuke.addOnScriptSave(check_inventory_versions) +# # set apply all workfile settings on script load and save +nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) + log.info('Automatic syncing of write file knob to script version') From 1f73b96bd053fed35c957d1c5e1d1d69fd3a4cf3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 24 May 2021 17:40:01 +0200 Subject: [PATCH 072/106] Hiero: publishing issues - ffmpeg path with space - no need to add `ftrackreview` to tags --- .../publish/extract_otio_audio_tracks.py | 18 +++++++++--------- .../plugins/publish/extract_otio_review.py | 14 ++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/openpype/plugins/publish/extract_otio_audio_tracks.py b/openpype/plugins/publish/extract_otio_audio_tracks.py index 43e40097f7..57da6d274c 100644 --- a/openpype/plugins/publish/extract_otio_audio_tracks.py +++ b/openpype/plugins/publish/extract_otio_audio_tracks.py @@ -53,14 +53,14 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): audio_inputs.insert(0, empty) # create cmd - cmd = self.ffmpeg_path + " " + cmd = '"{}"'.format(self.ffmpeg_path) + " " cmd += self.create_cmd(audio_inputs) - cmd += audio_temp_fpath + cmd += "\"{}\"".format(audio_temp_fpath) # run subprocess self.log.debug("Executing: {}".format(cmd)) openpype.api.run_subprocess( - cmd, shell=True, logger=self.log + cmd, logger=self.log ) # remove empty @@ -97,17 +97,17 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): audio_fpath = self.create_temp_file(name) cmd = " ".join([ - self.ffmpeg_path, + '"{}"'.format(self.ffmpeg_path), "-ss {}".format(start_sec), "-t {}".format(duration_sec), - "-i {}".format(audio_file), + "-i \"{}\"".format(audio_file), audio_fpath ]) # run subprocess self.log.debug("Executing: {}".format(cmd)) openpype.api.run_subprocess( - cmd, shell=True, logger=self.log + cmd, logger=self.log ) else: audio_fpath = recycling_file.pop() @@ -218,11 +218,11 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): # create empty cmd cmd = " ".join([ - self.ffmpeg_path, + '"{}"'.format(self.ffmpeg_path), "-f lavfi", "-i anullsrc=channel_layout=stereo:sample_rate=48000", "-t {}".format(max_duration_sec), - empty_fpath + "\"{}\"".format(empty_fpath) ]) # generate empty with ffmpeg @@ -230,7 +230,7 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): self.log.debug("Executing: {}".format(cmd)) openpype.api.run_subprocess( - cmd, shell=True, logger=self.log + cmd, logger=self.log ) # return dict with output diff --git a/openpype/plugins/publish/extract_otio_review.py b/openpype/plugins/publish/extract_otio_review.py index 07fe6f2731..2f46bcb375 100644 --- a/openpype/plugins/publish/extract_otio_review.py +++ b/openpype/plugins/publish/extract_otio_review.py @@ -209,7 +209,7 @@ class ExtractOTIOReview(openpype.api.Extractor): "frameStart": start, "frameEnd": end, "stagingDir": self.staging_dir, - "tags": ["review", "ftrackreview", "delete"] + "tags": ["review", "delete"] } collection = clique.Collection( @@ -313,7 +313,7 @@ class ExtractOTIOReview(openpype.api.Extractor): out_frame_start += end_offset # start command list - command = [ffmpeg_path] + command = ['"{}"'.format(ffmpeg_path)] if sequence: input_dir, collection = sequence @@ -326,7 +326,7 @@ class ExtractOTIOReview(openpype.api.Extractor): # form command for rendering gap files command.extend([ "-start_number {}".format(in_frame_start), - "-i {}".format(input_path) + "-i \"{}\"".format(input_path) ]) elif video: @@ -341,7 +341,7 @@ class ExtractOTIOReview(openpype.api.Extractor): command.extend([ "-ss {}".format(sec_start), "-t {}".format(sec_duration), - "-i {}".format(video_path) + "-i \"{}\"".format(video_path) ]) elif gap: @@ -360,11 +360,13 @@ class ExtractOTIOReview(openpype.api.Extractor): # add output attributes command.extend([ "-start_number {}".format(out_frame_start), - output_path + "\"{}\"".format(output_path) ]) # execute self.log.debug("Executing: {}".format(" ".join(command))) - output = openpype.api.run_subprocess(" ".join(command), shell=True) + output = openpype.api.run_subprocess( + " ".join(command), logger=self.log + ) self.log.debug("Output: {}".format(output)) def _generate_used_frames(self, duration, end_offset=None): From a883ca1c77cf7566f8b963c724d7da4ab5257279 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 24 May 2021 18:56:23 +0200 Subject: [PATCH 073/106] Delivery in LibraryLoader - fixes for comments --- openpype/lib/delivery.py | 46 +---------- .../event_handlers_user/action_delivery.py | 44 +++++++++- openpype/plugins/load/delivery.py | 82 ++++++++++--------- 3 files changed, 87 insertions(+), 85 deletions(-) diff --git a/openpype/lib/delivery.py b/openpype/lib/delivery.py index 9e87d854f5..411ae42e80 100644 --- a/openpype/lib/delivery.py +++ b/openpype/lib/delivery.py @@ -1,7 +1,5 @@ """Functions useful for delivery action or loader""" import os -from avalon import pipeline -from avalon.vendor import filelink import shutil import clique import collections @@ -17,6 +15,8 @@ def sizeof_fmt(num, suffix='B'): def path_from_represenation(representation, anatomy): + from avalon import pipeline # safer importing + try: template = representation["data"]["template"] @@ -39,6 +39,8 @@ def path_from_represenation(representation, anatomy): def copy_file(src_path, dst_path): """Hardlink file if possible(to save space), copy if not""" + from avalon.vendor import filelink # safer importing + if os.path.exists(dst_path): return try: @@ -271,43 +273,3 @@ def process_sequence( uploaded += 1 return report_items, uploaded - - -def report(report_items): - """Returns dict with final status of delivery (succes, fail etc.).""" - items = [] - title = "Delivery report" - for msg, _items in report_items.items(): - if not _items: - continue - - if items: - items.append({"type": "label", "value": "---"}) - - items.append({ - "type": "label", - "value": "# {}".format(msg) - }) - if not isinstance(_items, (list, tuple)): - _items = [_items] - __items = [] - for item in _items: - __items.append(str(item)) - - items.append({ - "type": "label", - "value": '

{}

'.format("
".join(__items)) - }) - - if not items: - return { - "success": True, - "message": "Delivery Finished" - } - - return { - "items": items, - "title": title, - "success": False, - "message": "Delivery Finished" - } diff --git a/openpype/modules/ftrack/event_handlers_user/action_delivery.py b/openpype/modules/ftrack/event_handlers_user/action_delivery.py index 7f2d9bb43a..f8553b2eac 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delivery.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delivery.py @@ -13,8 +13,7 @@ from openpype.lib.delivery import ( get_format_dict, check_destination_path, process_single_file, - process_sequence, - report + process_sequence ) from avalon.api import AvalonMongoDB @@ -498,7 +497,46 @@ class Delivery(BaseAction): else: process_sequence(*args) - return report(report_items) + return self.report(report_items) + + def report(self, report_items): + """Returns dict with final status of delivery (succes, fail etc.).""" + items = [] + title = "Delivery report" + for msg, _items in report_items.items(): + if not _items: + continue + + if items: + items.append({"type": "label", "value": "---"}) + + items.append({ + "type": "label", + "value": "# {}".format(msg) + }) + if not isinstance(_items, (list, tuple)): + _items = [_items] + __items = [] + for item in _items: + __items.append(str(item)) + + items.append({ + "type": "label", + "value": '

{}

'.format("
".join(__items)) + }) + + if not items: + return { + "success": True, + "message": "Delivery Finished" + } + + return { + "items": items, + "title": title, + "success": False, + "message": "Delivery Finished" + } def register(session): diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index 53f8033c32..a905bf02c2 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -1,12 +1,13 @@ import collections import copy +from Qt import QtWidgets, QtCore, QtGui + from avalon import api, style -from avalon.vendor.Qt import QtWidgets, QtCore, QtGui from avalon.api import AvalonMongoDB + from openpype.api import Anatomy, config from openpype import resources -from openpype.api import get_anatomy_settings from openpype.lib.delivery import ( sizeof_fmt, @@ -14,8 +15,7 @@ from openpype.lib.delivery import ( get_format_dict, check_destination_path, process_single_file, - process_sequence, - report + process_sequence ) @@ -53,19 +53,18 @@ class Delivery(api.SubsetLoader): class DeliveryOptionsDialog(QtWidgets.QDialog): """Dialog to select template where to deliver selected representations.""" - SIZE_W = 950 - SIZE_H = 350 def __init__(self, contexts, log=None, parent=None): super(DeliveryOptionsDialog, self).__init__(parent=parent) - self.project = contexts[0]["project"]["name"] + project = contexts[0]["project"]["name"] + self.anatomy = Anatomy(project) self._representations = None self.log = log self.currently_uploaded = 0 self.dbcon = AvalonMongoDB() - self.dbcon.Session["AVALON_PROJECT"] = self.project + self.dbcon.Session["AVALON_PROJECT"] = project self.dbcon.install() self._set_representations(contexts) @@ -79,15 +78,9 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): QtCore.Qt.WindowMinimizeButtonHint ) self.setStyleSheet(style.load_stylesheet()) - self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H)) - - layout = QtWidgets.QVBoxLayout() - - input_layout = QtWidgets.QFormLayout() - input_layout.setContentsMargins(10, 15, 5, 5) dropdown = QtWidgets.QComboBox() - self.templates = self._get_templates(self.project) + self.templates = self._get_templates(self.anatomy) for name, _ in self.templates.items(): dropdown.addItem(name) @@ -98,12 +91,12 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): root_line_edit = QtWidgets.QLineEdit() repre_checkboxes_layout = QtWidgets.QFormLayout() - repre_checkboxes_layout.setContentsMargins(10, 5, 5, 20) + repre_checkboxes_layout.setContentsMargins(10, 5, 5, 10) self._representation_checkboxes = {} for repre in self._get_representation_names(): checkbox = QtWidgets.QCheckBox() - checkbox.setChecked(True) + checkbox.setChecked(False) self._representation_checkboxes[repre] = checkbox checkbox.stateChanged.connect(self._update_selected_label) @@ -111,6 +104,10 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): selected_label = QtWidgets.QLabel() + input_widget = QtWidgets.QWidget(self) + input_layout = QtWidgets.QFormLayout(input_widget) + input_layout.setContentsMargins(10, 15, 5, 5) + input_layout.addRow("Selected representations", selected_label) input_layout.addRow("Delivery template", dropdown) input_layout.addRow("Template value", template_label) @@ -123,20 +120,21 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): progress_bar = QtWidgets.QProgressBar(self) progress_bar.setMinimum = 0 progress_bar.setMaximum = 100 - progress_bar.hide() + progress_bar.setVisible(False) text_area = QtWidgets.QTextEdit() text_area.setReadOnly(True) - text_area.hide() + text_area.setVisible(False) text_area.setMinimumHeight(100) - layout.addLayout(input_layout) + layout = QtWidgets.QVBoxLayout(self) + + layout.addWidget(input_widget) + layout.addStretch(1) layout.addWidget(btn_delivery) layout.addWidget(progress_bar) layout.addWidget(text_area) - self.setLayout(layout) - self.selected_label = selected_label self.template_label = template_label self.dropdown = dropdown @@ -156,26 +154,26 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): def deliver(self): """Main method to loop through all selected representations""" - self.progress_bar.show() + self.progress_bar.setVisible(True) self.btn_delivery.setEnabled(False) - # self.resize(self.width(), self.height() + 50) + QtWidgets.QApplication.processEvents() report_items = collections.defaultdict(list) selected_repres = self._get_selected_repres() - anatomy = Anatomy(self.project) + datetime_data = config.get_datetime_data() template_name = self.dropdown.currentText() - format_dict = get_format_dict(anatomy, self.root_line_edit.text()) + format_dict = get_format_dict(self.anatomy, self.root_line_edit.text()) for repre in self._representations: if repre["name"] not in selected_repres: continue - repre_path = path_from_represenation(repre, anatomy) + repre_path = path_from_represenation(repre, self.anatomy) anatomy_data = copy.deepcopy(repre["context"]) new_report_items = check_destination_path(str(repre["_id"]), - anatomy, + self.anatomy, anatomy_data, datetime_data, template_name) @@ -187,7 +185,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): args = [ repre_path, repre, - anatomy, + self.anatomy, template_name, anatomy_data, format_dict, @@ -197,7 +195,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): if repre.get("files"): for repre_file in repre["files"]: - src_path = anatomy.fill_root(repre_file["path"]) + src_path = self.anatomy.fill_root(repre_file["path"]) args[0] = src_path new_report_items, uploaded = process_single_file(*args) report_items.update(new_report_items) @@ -214,21 +212,20 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): report_items.update(new_report_items) self._update_progress(uploaded) - self.text_area.setText(self._format_report(report(report_items), - report_items)) - self.text_area.show() - - self.resize(self.width(), self.height() + 125) + self.text_area.setText(self._format_report(report_items)) + self.text_area.setVisible(True) def _get_representation_names(self): """Get set of representation names for checkbox filtering.""" return set([repre["name"] for repre in self._representations]) - def _get_templates(self, project_name): + def _get_templates(self, anatomy): """Adds list of delivery templates from Anatomy to dropdown.""" - settings = get_anatomy_settings(project_name) templates = {} - for template_name, value in settings["templates"]["delivery"].items(): + for template_name, value in anatomy.templates["delivery"].items(): + if not isinstance(value, str) or not value.startswith('{root'): + continue + templates[template_name] = value return templates @@ -297,9 +294,14 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): ratio = self.currently_uploaded / self.files_selected self.progress_bar.setValue(ratio * self.progress_bar.maximum()) - def _format_report(self, result, report_items): + def _format_report(self, report_items): """Format final result and error details as html.""" - txt = "

{}

".format(result["message"]) + msg = "Delivery finished" + if not report_items: + msg += " successfully" + else: + msg += " with errors" + txt = "

{}

".format(msg) for header, data in report_items.items(): txt += "

{}

".format(header) for item in data: From 5a5e40400c9af55bda0687b5088e45525ca7e8bb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 24 May 2021 19:06:30 +0200 Subject: [PATCH 074/106] create AvalonMongoDB on object creation --- .../event_handlers_user/action_delete_asset.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py index ff39db4383..cf658a3eea 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py @@ -11,23 +11,28 @@ from avalon.api import AvalonMongoDB class DeleteAssetSubset(BaseAction): '''Edit meta data action.''' - #: Action identifier. + # Action identifier. identifier = "delete.asset.subset" - #: Action label. + # Action label. label = "Delete Asset/Subsets" - #: Action description. + # Action description. description = "Removes from Avalon with all childs and asset from Ftrack" icon = statics_icon("ftrack", "action_icons", "DeleteAsset.svg") settings_key = "delete_asset_subset" - #: Db connection - dbcon = AvalonMongoDB() + # Db connection + dbcon = None splitter = {"type": "label", "value": "---"} action_data_by_id = {} asset_prefix = "asset:" subset_prefix = "subset:" + def __init__(self, *args, **kwargs): + self.dbcon = AvalonMongoDB() + + super(DeleteAssetSubset, self).__init__(*args, **kwargs) + def discover(self, session, entities, event): """ Validation """ task_ids = [] From e7eeb6fc57b6e58cacfd06c2a76b09f72452d943 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 24 May 2021 19:07:06 +0200 Subject: [PATCH 075/106] faster asset doc query --- .../ftrack/event_handlers_user/action_delete_asset.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py index cf658a3eea..ecb5b1e041 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py @@ -451,7 +451,14 @@ class DeleteAssetSubset(BaseAction): if len(assets_to_delete) > 0: map_av_ftrack_id = spec_data["without_ftrack_id"] # Prepare data when deleting whole avalon asset - avalon_assets = self.dbcon.find({"type": "asset"}) + avalon_assets = self.dbcon.find( + {"type": "asset"}, + { + "_id": 1, + "data.visualParent": 1, + "data.ftrackId": 1 + } + ) avalon_assets_by_parent = collections.defaultdict(list) for asset in avalon_assets: asset_id = asset["_id"] From ca5405abccad0b78a46d741632be382d4eae0f70 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 24 May 2021 19:07:44 +0200 Subject: [PATCH 076/106] entities are deleted by link length (higher length earlier removement) --- .../action_delete_asset.py | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py index ecb5b1e041..c20491349f 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py @@ -549,11 +549,13 @@ class DeleteAssetSubset(BaseAction): ftrack_proc_txt, ", ".join(ftrack_ids_to_delete) )) - ftrack_ents_to_delete = ( + entities_by_link_len = ( self._filter_entities_to_delete(ftrack_ids_to_delete, session) ) - for entity in ftrack_ents_to_delete: - session.delete(entity) + for link_len in sorted(entities_by_link_len.keys(), reverse=True): + for entity in entities_by_link_len[link_len]: + session.delete(entity) + try: session.commit() except Exception: @@ -612,29 +614,11 @@ class DeleteAssetSubset(BaseAction): joined_ids_to_delete ) ).all() - filtered = to_delete_entities[:] - while True: - changed = False - _filtered = filtered[:] - for entity in filtered: - entity_id = entity["id"] + entities_by_link_len = collections.defaultdict(list) + for entity in to_delete_entities: + entities_by_link_len[len(entity["link"])].append(entity) - for _entity in tuple(_filtered): - if entity_id == _entity["id"]: - continue - - for _link in _entity["link"]: - if entity_id == _link["id"] and _entity in _filtered: - _filtered.remove(_entity) - changed = True - break - - filtered = _filtered - - if not changed: - break - - return filtered + return entities_by_link_len def report_handle(self, report_messages, project_name, event): if not report_messages: From 1e1209c2025b5c1a34259140b5e4affbf04f0d63 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 08:13:58 +0000 Subject: [PATCH 077/106] Create draft PR for #1575 From f3cbc1550afd6fd7d5054127f6b172a480da60fd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 10:15:31 +0200 Subject: [PATCH 078/106] added global prelaunch hook for mac prepending `open -an` arguments --- openpype/hooks/pre_mac_launch.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 openpype/hooks/pre_mac_launch.py diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py new file mode 100644 index 0000000000..be4aa9839c --- /dev/null +++ b/openpype/hooks/pre_mac_launch.py @@ -0,0 +1,18 @@ +from openpype.lib import PreLaunchHook + + +class LaunchWithTerminal(PreLaunchHook): + """Mac specific pre arguments for application. + + Mac applications should be launched using "open" argument which is internal + callbacks to open executable. We also add argument "-an" to create new + process. This is used only for executables ending with ".app". It is + expected that these executables lead to app packages. + """ + order = 1000 + + platforms = ["darwin"] + + def execute(self): + if self.launch_context.executable.endswith(".app"): + self.launch_context.launch_args.insert(0, ["open", "-an"]) From e433f17c29dd786d97798afa85f36808f3c3ad53 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 10:21:14 +0200 Subject: [PATCH 079/106] added more specific logic --- openpype/hooks/pre_mac_launch.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index be4aa9839c..63ebcbfa43 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -14,5 +14,14 @@ class LaunchWithTerminal(PreLaunchHook): platforms = ["darwin"] def execute(self): - if self.launch_context.executable.endswith(".app"): + executable = self.launch_context.executable + # Skip executables not starting with ".app" + if not executable.endswith(".app"): + return + + # Check if first argument match executable path + # - Few applications are not executed directly but through OpenPype + # process (Photoshop, AfterEffects, Harmony, ...). These should not + # use `open -an`. + if self.launch_context.launch_args[0] == executable: self.launch_context.launch_args.insert(0, ["open", "-an"]) From 805f7e0c96d200058688662600813b92f6986dd6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 10:34:50 +0200 Subject: [PATCH 080/106] use new color entity instead of template_rgba_color --- .../schemas/schema_global_publish.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index b68a1a68b1..37ec54a1b1 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -198,14 +198,9 @@ "label": "Background color is used only when input have transparency and Alpha is higher than 0." }, { - "type": "schema_template", - "name": "template_rgba_color", - "template_data": [ - { - "label": "Background color", - "name": "bg_color" - } - ] + "type": "color", + "label": "Background color", + "key": "bg_color" }, { "key": "letter_box", From 7b737f0c94381f34b02b35203d21b86ec81066ed Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 10:40:46 +0200 Subject: [PATCH 081/106] add color entity for colors in extract burnin --- .../schemas/schema_global_publish.json | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 37ec54a1b1..11b95862fa 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -289,24 +289,14 @@ "minimum": 0 }, { - "type": "schema_template", - "name": "template_rgba_color", - "template_data": [ - { - "label": "Font Color", - "name": "font_color" - } - ] + "type": "color", + "key": "font_color", + "label": "Font Color" }, { - "type": "schema_template", - "name": "template_rgba_color", - "template_data": [ - { - "label": "Background Color", - "name": "bg_color" - } - ] + "type": "color", + "key": "bg_color", + "label": "Background Color" }, { "type": "number", From a559068abf4e5fc1f4256ec33f75f6a827d4b4a5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 10:41:07 +0200 Subject: [PATCH 082/106] removed unused template_rgba_color --- .../schemas/template_rgba_color.json | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 openpype/settings/entities/schemas/projects_schema/schemas/template_rgba_color.json diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/template_rgba_color.json b/openpype/settings/entities/schemas/projects_schema/schemas/template_rgba_color.json deleted file mode 100644 index ffe530175a..0000000000 --- a/openpype/settings/entities/schemas/projects_schema/schemas/template_rgba_color.json +++ /dev/null @@ -1,33 +0,0 @@ -[ - { - "type": "list-strict", - "key": "{name}", - "label": "{label}", - "object_types": [ - { - "label": "R", - "type": "number", - "minimum": 0, - "maximum": 255 - }, - { - "label": "G", - "type": "number", - "minimum": 0, - "maximum": 255 - }, - { - "label": "B", - "type": "number", - "minimum": 0, - "maximum": 255 - }, - { - "label": "A", - "type": "number", - "minimum": 0, - "maximum": 255 - } - ] - } -] From 7ea0e8210395dec4bf893e13e9e66340134823bd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 11:15:57 +0200 Subject: [PATCH 083/106] added isdir check --- openpype/hooks/pre_mac_launch.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index 63ebcbfa43..3c00177680 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -1,3 +1,4 @@ +import os from openpype.lib import PreLaunchHook @@ -15,8 +16,8 @@ class LaunchWithTerminal(PreLaunchHook): def execute(self): executable = self.launch_context.executable - # Skip executables not starting with ".app" - if not executable.endswith(".app"): + # Skip executables not ending with ".app" or that are not folder + if not executable.endswith(".app") or not os.path.isdir(executable): return # Check if first argument match executable path From 81ab14b02ca0c7d5523c5c00eb33927625e2bee5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 11:41:13 +0200 Subject: [PATCH 084/106] sync to avalon do not store hierarchy key --- .../ftrack/event_handlers_server/event_sync_to_avalon.py | 9 --------- openpype/modules/ftrack/lib/avalon_sync.py | 7 ------- 2 files changed, 16 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 410e51e2a4..e60045bd50 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -1101,9 +1101,6 @@ class SyncToAvalonEvent(BaseEvent): # Parents, Hierarchy ent_path_items = [ent["name"] for ent in ftrack_ent["link"]] parents = ent_path_items[1:len(ent_path_items)-1:] - hierarchy = "" - if len(parents) > 0: - hierarchy = os.path.sep.join(parents) # TODO logging self.log.debug( @@ -1132,7 +1129,6 @@ class SyncToAvalonEvent(BaseEvent): "ftrackId": ftrack_ent["id"], "entityType": ftrack_ent.entity_type, "parents": parents, - "hierarchy": hierarchy, "tasks": {}, "visualParent": vis_par } @@ -1975,14 +1971,9 @@ class SyncToAvalonEvent(BaseEvent): if cur_par == parents: continue - hierarchy = "" - if len(parents) > 0: - hierarchy = os.path.sep.join(parents) - if "data" not in self.updates[mongo_id]: self.updates[mongo_id]["data"] = {} self.updates[mongo_id]["data"]["parents"] = parents - self.updates[mongo_id]["data"]["hierarchy"] = hierarchy # Skip custom attributes if didn't change if not hier_cust_attrs_ids: diff --git a/openpype/modules/ftrack/lib/avalon_sync.py b/openpype/modules/ftrack/lib/avalon_sync.py index a3b926464e..5d1da005dc 100644 --- a/openpype/modules/ftrack/lib/avalon_sync.py +++ b/openpype/modules/ftrack/lib/avalon_sync.py @@ -1237,12 +1237,8 @@ class SyncEntitiesFactory: ent_path_items = [ent["name"] for ent in entity["link"]] parents = ent_path_items[1:len(ent_path_items) - 1:] - hierarchy = "" - if len(parents) > 0: - hierarchy = os.path.sep.join(parents) data["parents"] = parents - data["hierarchy"] = hierarchy data["tasks"] = self.entities_dict[id].pop("tasks", {}) self.entities_dict[id]["final_entity"]["data"] = data self.entities_dict[id]["final_entity"]["type"] = "asset" @@ -2169,8 +2165,6 @@ class SyncEntitiesFactory: hierarchy = "/".join(parents) self.entities_dict[ftrack_id][ "final_entity"]["data"]["parents"] = parents - self.entities_dict[ftrack_id][ - "final_entity"]["data"]["hierarchy"] = hierarchy _parents.append(self.entities_dict[ftrack_id]["name"]) for child_id in self.entities_dict[ftrack_id]["children"]: @@ -2181,7 +2175,6 @@ class SyncEntitiesFactory: if "data" not in self.updates[mongo_id]: self.updates[mongo_id]["data"] = {} self.updates[mongo_id]["data"]["parents"] = parents - self.updates[mongo_id]["data"]["hierarchy"] = hierarchy def prepare_project_changes(self): ftrack_ent_dict = self.entities_dict[self.ft_project_id] From 7498650cf2fe93c58e99c398eceaa59cdf5847d1 Mon Sep 17 00:00:00 2001 From: antirotor Date: Tue, 25 May 2021 10:24:23 +0000 Subject: [PATCH 085/106] Create draft PR for #1583 From e2ca35b881bd7e58ba5426bf31135d45d088ddf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 25 May 2021 12:54:38 +0200 Subject: [PATCH 086/106] set specific version from env OPENPYPE_VERSION if present. --- start.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/start.py b/start.py index 660d0c9006..768ef9d1c8 100644 --- a/start.py +++ b/start.py @@ -6,10 +6,11 @@ Bootstrapping process of OpenPype is as follows: `OPENPYPE_PATH` is checked for existence - either one from environment or from user settings. Precedence takes the one set by environment. -On this path we try to find OpenPype in directories version string in their names. -For example: `openpype-v3.0.1-foo` is valid name, or even `foo_3.0.2` - as long -as version can be determined from its name _AND_ file `openpype/openpype/version.py` -can be found inside, it is considered OpenPype installation. +On this path we try to find OpenPype in directories version string in their +names. For example: `openpype-v3.0.1-foo` is valid name, or +even `foo_3.0.2` - as long as version can be determined from its name +_AND_ file `openpype/openpype/version.py` can be found inside, it is +considered OpenPype installation. If no OpenPype repositories are found in `OPENPYPE_PATH` (user data dir) then **Igniter** (OpenPype setup tool) will launch its GUI. @@ -20,19 +21,19 @@ appdata dir in user home and extract it there. Version will be determined by version specified in OpenPype module. If OpenPype repository directories are found in default install location -(user data dir) or in `OPENPYPE_PATH`, it will get list of those dirs there and -use latest one or the one specified with optional `--use-version` command -line argument. If the one specified doesn't exist then latest available -version will be used. All repositories in that dir will be added +(user data dir) or in `OPENPYPE_PATH`, it will get list of those dirs +there and use latest one or the one specified with optional `--use-version` +command line argument. If the one specified doesn't exist then latest +available version will be used. All repositories in that dir will be added to `sys.path` and `PYTHONPATH`. -If OpenPype is live (not frozen) then current version of OpenPype module will be -used. All directories under `repos` will be added to `sys.path` and +If OpenPype is live (not frozen) then current version of OpenPype module +will be used. All directories under `repos` will be added to `sys.path` and `PYTHONPATH`. -OpenPype depends on connection to `MongoDB`_. You can specify MongoDB connection -string via `OPENPYPE_MONGO` set in environment or it can be set in user -settings or via **Igniter** GUI. +OpenPype depends on connection to `MongoDB`_. You can specify MongoDB +connection string via `OPENPYPE_MONGO` set in environment or it can be set +in user settings or via **Igniter** GUI. So, bootstrapping OpenPype looks like this:: @@ -624,6 +625,10 @@ def boot(): use_version, use_staging = _process_arguments() + if os.getenv("OPENPYPE_VERSION"): + use_staging = "staging" in os.getenv("OPENPYPE_VERSION") + use_version = os.getenv("OPENPYPE_VERSION") + # ------------------------------------------------------------------------ # Determine mongodb connection # ------------------------------------------------------------------------ From e380100dfcb2c0b6f741fe32ddab3673164c1c82 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 15:10:28 +0200 Subject: [PATCH 087/106] add filter into quotation marks to fix issue happening in bash on linux --- openpype/plugins/publish/extract_review.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 048d16fabb..49caf4e40c 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -547,10 +547,12 @@ class ExtractReview(pyblish.api.InstancePlugin): all_args.append("\"{}\"".format(self.ffmpeg_path)) all_args.extend(input_args) if video_filters: - all_args.append("-filter:v {}".format(",".join(video_filters))) + all_args.append("-filter:v") + all_args.append("\"{}\"".format(",".join(video_filters))) if audio_filters: - all_args.append("-filter:a {}".format(",".join(audio_filters))) + all_args.append("-filter:a") + all_args.append("\"{}\"".format(",".join(audio_filters))) all_args.extend(output_args) From b8ef1abca007fdd5619254c630c284776456208c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 16:53:53 +0200 Subject: [PATCH 088/106] fix executable type --- openpype/hooks/pre_mac_launch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index 3c00177680..db4c7858c7 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -15,7 +15,7 @@ class LaunchWithTerminal(PreLaunchHook): platforms = ["darwin"] def execute(self): - executable = self.launch_context.executable + executable = str(self.launch_context.executable) # Skip executables not ending with ".app" or that are not folder if not executable.endswith(".app") or not os.path.isdir(executable): return From fe701ab0bdb86141dfde6bcc29a21e0c174ec908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 25 May 2021 17:03:59 +0200 Subject: [PATCH 089/106] fix use of specific version --- start.py | 86 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/start.py b/start.py index 768ef9d1c8..8a375a868d 100644 --- a/start.py +++ b/start.py @@ -283,7 +283,8 @@ def _process_arguments() -> tuple: print(" --use-version=3.0.0") sys.exit(1) - m = re.search(r"--use-version=(?P\d+\.\d+\.\d*.+?)", arg) + m = re.search( + r"--use-version=(?P\d+\.\d+\.\d+(?:\S*)?)", arg) if m and m.group('version'): use_version = m.group('version') sys.argv.remove(arg) @@ -415,6 +416,7 @@ def _find_frozen_openpype(use_version: str = None, (if requested). """ + version_path = None openpype_version = None openpype_versions = bootstrap.find_openpype(include_zips=True, staging=use_staging) @@ -481,17 +483,24 @@ def _find_frozen_openpype(use_version: str = None, return version_path # get path of version specified in `--use-version` - version_path = BootstrapRepos.get_version_path_from_list( - use_version, openpype_versions) - - if not version_path: - if use_version is not None and openpype_version: - print(("!!! Specified version was not found, using " - "latest available")) - # specified version was not found so use latest detected. - version_path = openpype_version.path - print(f">>> Using version [ {openpype_version} ]") - print(f" From {version_path}") + local_version = bootstrap.get_version(OPENPYPE_ROOT) + if use_version and use_version != local_version: + openpype_versions = bootstrap.find_openpype(include_zips=True) + v: OpenPypeVersion + for v in openpype_versions: + if str(v) == use_version: + openpype_version = v + version_path = openpype_version.path + if not openpype_version: + print(f"!!! requested version {use_version} was not found.") + if openpype_versions: + print(" - found: ") + for v in openpype_versions: + print(f" - {v}") + print(f" - {local_version}") + else: + print(f" - local version {local_version}") + sys.exit(1) # test if latest detected is installed (in user data dir) is_inside = False @@ -522,7 +531,7 @@ def _find_frozen_openpype(use_version: str = None, openpype_version.path = version_path _initialize_environment(openpype_version) - return version_path + return openpype_version.path def _bootstrap_from_code(use_version): @@ -537,36 +546,53 @@ def _bootstrap_from_code(use_version): """ # run through repos and add them to `sys.path` and `PYTHONPATH` # set root + _openpype_root = OPENPYPE_ROOT if getattr(sys, 'frozen', False): - local_version = bootstrap.get_version(Path(OPENPYPE_ROOT)) + local_version = bootstrap.get_version(Path(_openpype_root)) print(f" - running version: {local_version}") assert local_version else: # get current version of OpenPype local_version = bootstrap.get_local_live_version() - os.environ["OPENPYPE_VERSION"] = local_version if use_version and use_version != local_version: + version_to_use = None openpype_versions = bootstrap.find_openpype(include_zips=True) - version_path = BootstrapRepos.get_version_path_from_list( - use_version, openpype_versions) - if version_path: + v: OpenPypeVersion + for v in openpype_versions: + if str(v) == use_version: + version_to_use = v + if version_to_use: # use specified - bootstrap.add_paths_from_directory(version_path) + if version_to_use.path.is_file(): + version_to_use.path = bootstrap.extract_openpype( + version_to_use) + bootstrap.add_paths_from_directory(version_to_use.path) os.environ["OPENPYPE_VERSION"] = use_version + version_path = version_to_use.path + os.environ["OPENPYPE_REPOS_ROOT"] = (version_path / "openpype").as_posix() # noqa: E501 + _openpype_root = version_to_use.path.as_posix() + else: + print(f"!!! requested version {use_version} was not found.") + if openpype_versions: + print(" - found: ") + for v in openpype_versions: + print(f" - {v}") + print(f" - {local_version}") + else: + print(f" - local version {local_version}") + sys.exit(1) else: - version_path = OPENPYPE_ROOT + os.environ["OPENPYPE_VERSION"] = local_version + version_path = Path(_openpype_root) + os.environ["OPENPYPE_REPOS_ROOT"] = _openpype_root - repos = os.listdir(os.path.join(OPENPYPE_ROOT, "repos")) - repos = [os.path.join(OPENPYPE_ROOT, "repos", repo) for repo in repos] + repos = os.listdir(os.path.join(_openpype_root, "repos")) + repos = [os.path.join(_openpype_root, "repos", repo) for repo in repos] # add self to python paths - repos.insert(0, OPENPYPE_ROOT) + repos.insert(0, _openpype_root) for repo in repos: sys.path.insert(0, repo) - - # Set OPENPYPE_REPOS_ROOT to code root - os.environ["OPENPYPE_REPOS_ROOT"] = OPENPYPE_ROOT - # add venv 'site-packages' to PYTHONPATH python_path = os.getenv("PYTHONPATH", "") split_paths = python_path.split(os.pathsep) @@ -581,11 +607,11 @@ def _bootstrap_from_code(use_version): # point to same hierarchy from code and from frozen OpenPype additional_paths = [ # add OpenPype tools - os.path.join(OPENPYPE_ROOT, "openpype", "tools"), + os.path.join(_openpype_root, "openpype", "tools"), # add common OpenPype vendor # (common for multiple Python interpreter versions) os.path.join( - OPENPYPE_ROOT, + _openpype_root, "openpype", "vendor", "python", @@ -598,7 +624,7 @@ def _bootstrap_from_code(use_version): os.environ["PYTHONPATH"] = os.pathsep.join(split_paths) - return Path(version_path) + return version_path def boot(): From 53ef81dc0ee1c114d0bc17cd0c2cf7fe885b9ad2 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 25 May 2021 17:57:36 +0200 Subject: [PATCH 090/106] Delivery in LibraryLoader - fix broken sequence delivery --- openpype/lib/delivery.py | 30 +++++++++++++++++++++++++++++- openpype/plugins/load/delivery.py | 14 +++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/openpype/lib/delivery.py b/openpype/lib/delivery.py index 411ae42e80..b7f8e0e252 100644 --- a/openpype/lib/delivery.py +++ b/openpype/lib/delivery.py @@ -4,6 +4,35 @@ import shutil import clique import collections +def collect_frames(files): + """ + Returns dict of source path and its frame, if from sequence + + Uses clique as most precise solution + + Args: + files(list): list of source paths + Returns: + (dict): {'/asset/subset_v001.0001.png': '0001', ....} + """ + collections, remainder = clique.assemble(files) + + sources_and_frames = {} + if collections: + for collection in collections: + src_head = collection.head + src_tail = collection.tail + + for index in collection.indexes: + src_frame = collection.format("{padding}") % index + src_file_name = "{}{}{}".format(src_head, src_frame, + src_tail) + sources_and_frames[src_file_name] = src_frame + else: + sources_and_frames[remainder.pop()] = None + + return sources_and_frames + def sizeof_fmt(num, suffix='B'): """Returns formatted string with size in appropriate unit""" @@ -166,7 +195,6 @@ def process_single_file( os.makedirs(delivery_folder) log.debug("Copying single: {} -> {}".format(src_path, delivery_path)) - print("Copying single: {} -> {}".format(src_path, delivery_path)) copy_file(src_path, delivery_path) return report_items, 1 diff --git a/openpype/plugins/load/delivery.py b/openpype/plugins/load/delivery.py index a905bf02c2..68b1f9a52a 100644 --- a/openpype/plugins/load/delivery.py +++ b/openpype/plugins/load/delivery.py @@ -1,4 +1,4 @@ -import collections +from collections import defaultdict import copy from Qt import QtWidgets, QtCore, QtGui @@ -15,7 +15,8 @@ from openpype.lib.delivery import ( get_format_dict, check_destination_path, process_single_file, - process_sequence + process_sequence, + collect_frames ) @@ -158,7 +159,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): self.btn_delivery.setEnabled(False) QtWidgets.QApplication.processEvents() - report_items = collections.defaultdict(list) + report_items = defaultdict(list) selected_repres = self._get_selected_repres() @@ -194,9 +195,16 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): ] if repre.get("files"): + src_paths = [] for repre_file in repre["files"]: src_path = self.anatomy.fill_root(repre_file["path"]) + src_paths.append(src_path) + sources_and_frames = collect_frames(src_paths) + + for src_path, frame in sources_and_frames.items(): args[0] = src_path + if frame: + anatomy_data["frame"] = frame new_report_items, uploaded = process_single_file(*args) report_items.update(new_report_items) self._update_progress(uploaded) From 2bf5bc5d581158ef36e2f6962a8e29e9fe409dee Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 16:46:39 +0000 Subject: [PATCH 091/106] Create draft PR for #1576 From 1e5af7788080440850e91b41842d929a295e5fcb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 25 May 2021 18:48:51 +0200 Subject: [PATCH 092/106] override `log_message` and use print instead of sys.stderr.write --- openpype/modules/ftrack/tray/login_tools.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openpype/modules/ftrack/tray/login_tools.py b/openpype/modules/ftrack/tray/login_tools.py index c6cf5b5f7b..95a072c352 100644 --- a/openpype/modules/ftrack/tray/login_tools.py +++ b/openpype/modules/ftrack/tray/login_tools.py @@ -16,6 +16,18 @@ class LoginServerHandler(BaseHTTPRequestHandler): self.login_callback = login_callback BaseHTTPRequestHandler.__init__(self, *args, **kw) + def log_message(self, format_str, *args): + """Override method of BaseHTTPRequestHandler. + + Goal is to use `print` instead of `sys.stderr.write` + """ + # Change + print("%s - - [%s] %s\n" % ( + self.client_address[0], + self.log_date_time_string(), + format_str % args + )) + def do_GET(self): '''Override to handle requests ourselves.''' parsed_path = parse.urlparse(self.path) From 00a0c3931e59b732bc4c1a6dd84c5041b5b02ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 25 May 2021 18:53:41 +0200 Subject: [PATCH 093/106] stop cleaning of pyc files in build dir --- tools/build.ps1 | 6 +++--- tools/build.sh | 3 ++- tools/create_env.ps1 | 12 ++++++++---- tools/create_env.sh | 2 +- tools/create_zip.ps1 | 6 +++--- tools/create_zip.sh | 17 ----------------- tools/run_tests.ps1 | 4 ++-- tools/run_tests.sh | 2 +- 8 files changed, 20 insertions(+), 32 deletions(-) diff --git a/tools/build.ps1 b/tools/build.ps1 index d9fef0f471..c8c2f392ad 100644 --- a/tools/build.ps1 +++ b/tools/build.ps1 @@ -175,9 +175,9 @@ if (-not (Test-Path -PathType Container -Path "$openpype_root\.poetry\bin")) { Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Cleaning cache files ... " -NoNewline -Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force -Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Remove-Item -Force -Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse +Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force -Recurse Write-Host "OK" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green diff --git a/tools/build.sh b/tools/build.sh index ccd97ea4c1..aa8f0121ea 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -122,7 +122,8 @@ clean_pyc () { local path path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" - find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete + find "$path" -path ./build -prune -o -regex '^.*\(__pycache__\|\.py[co]\)$' -delete + echo -e "${BIGreen}DONE${RST}" } diff --git a/tools/create_env.ps1 b/tools/create_env.ps1 index 7ada92c1e8..d690a89a2d 100644 --- a/tools/create_env.ps1 +++ b/tools/create_env.ps1 @@ -76,16 +76,20 @@ print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1])) Set-Location -Path $current_dir Exit-WithCode 1 } - # We are supporting python 3.6 and up - if(($matches[1] -lt 3) -or ($matches[2] -lt 7)) { + # We are supporting python 3.7 only + if (($matches[1] -lt 3) -or ($matches[2] -lt 7)) { Write-Host "FAILED Version [ $p ] is old and unsupported" -ForegroundColor red Set-Location -Path $current_dir Exit-WithCode 1 + } elseif (($matches[1] = 3) -or ($matches[2] -gt 7)) { + Write-Host "WARNING Version [ $p ] is unsupported, use at your own risk." -ForegroundColor yellow + Write-Host "*** " -NoNewline -ForegroundColor yellow + Write-Host "OpenPype supports only Python 3.7" -ForegroundColor white + } else { + Write-Host "OK [ $p ]" -ForegroundColor green } - Write-Host "OK [ $p ]" -ForegroundColor green } - $current_dir = Get-Location $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent $openpype_root = (Get-Item $script_dir).parent.FullName diff --git a/tools/create_env.sh b/tools/create_env.sh index d6a6828718..226a26e199 100755 --- a/tools/create_env.sh +++ b/tools/create_env.sh @@ -126,7 +126,7 @@ clean_pyc () { local path path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" - find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete + find "$path" -path ./build -prune -o -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" } diff --git a/tools/create_zip.ps1 b/tools/create_zip.ps1 index a34af89159..1a7520eb11 100644 --- a/tools/create_zip.ps1 +++ b/tools/create_zip.ps1 @@ -98,9 +98,9 @@ if (-not (Test-Path -PathType Container -Path "$openpype_root\.poetry\bin")) { Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Cleaning cache files ... " -NoNewline -Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force -Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Remove-Item -Force -Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse +Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse| Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force -Recurse Write-Host "OK" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green diff --git a/tools/create_zip.sh b/tools/create_zip.sh index adaf9431a7..ec0276b040 100755 --- a/tools/create_zip.sh +++ b/tools/create_zip.sh @@ -89,23 +89,6 @@ detect_python () { fi } -############################################################################## -# Clean pyc files in specified directory -# Globals: -# None -# Arguments: -# Optional path to clean -# Returns: -# None -############################################################################### -clean_pyc () { - local path - path=$openpype_root - echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" - find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete - echo -e "${BIGreen}DONE${RST}" -} - ############################################################################## # Return absolute path # Globals: diff --git a/tools/run_tests.ps1 b/tools/run_tests.ps1 index 30e1f29e59..a6882e2a09 100644 --- a/tools/run_tests.ps1 +++ b/tools/run_tests.ps1 @@ -94,8 +94,8 @@ if (-not (Test-Path -PathType Container -Path "$openpype_root\.poetry\bin")) { Write-Host ">>> " -NoNewline -ForegroundColor green Write-Host "Cleaning cache files ... " -NoNewline -Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Remove-Item -Force -Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Remove-Item -Force -Recurse +Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force +Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force -Recurse Write-Host "OK" -ForegroundColor green Write-Host ">>> " -NoNewline -ForegroundColor green diff --git a/tools/run_tests.sh b/tools/run_tests.sh index 3620ebc0e5..90977edc83 100755 --- a/tools/run_tests.sh +++ b/tools/run_tests.sh @@ -70,7 +70,7 @@ clean_pyc () { local path path=$openpype_root echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c" - find "$path" -regex '^.*\(__pycache__\|\.py[co]\)$' -delete + find "$path" -path ./build -prune -o -regex '^.*\(__pycache__\|\.py[co]\)$' -delete echo -e "${BIGreen}DONE${RST}" } From 5f2332c3fc26a60e50ee645047fb8631a3eb9068 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 May 2021 22:02:30 +0000 Subject: [PATCH 094/106] Bump postcss from 8.2.8 to 8.3.0 in /website Bumps [postcss](https://github.com/postcss/postcss) from 8.2.8 to 8.3.0. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.2.8...8.3.0) Signed-off-by: dependabot[bot] --- website/yarn.lock | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/website/yarn.lock b/website/yarn.lock index 7d3a5284c4..e5dadd4e80 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -5744,11 +5744,6 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== -nanoid@^3.1.20: - version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== - nanoid@^3.1.23: version "3.1.23" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" @@ -6587,23 +6582,14 @@ postcss-zindex@^5.0.0: has "^1.0.3" uniqs "^2.0.0" -postcss@^8.2.10, postcss@^8.2.4, postcss@^8.2.9: - version "8.2.15" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" - integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== +postcss@^8.2.10, postcss@^8.2.4, postcss@^8.2.8, postcss@^8.2.9: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== dependencies: colorette "^1.2.2" nanoid "^3.1.23" - source-map "^0.6.1" - -postcss@^8.2.8: - version "8.2.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" - integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.20" - source-map "^0.6.1" + source-map-js "^0.6.2" prepend-http@^2.0.0: version "2.0.0" @@ -7685,6 +7671,11 @@ source-list-map@^2.0.0, source-list-map@^2.0.1: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" From d571487fcd6efb9c8c98bc33e6a14de105968582 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 10:54:21 +0200 Subject: [PATCH 095/106] reversed condition logic --- openpype/hooks/pre_mac_launch.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index db4c7858c7..e0c3133556 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -23,6 +23,9 @@ class LaunchWithTerminal(PreLaunchHook): # Check if first argument match executable path # - Few applications are not executed directly but through OpenPype # process (Photoshop, AfterEffects, Harmony, ...). These should not - # use `open -an`. - if self.launch_context.launch_args[0] == executable: - self.launch_context.launch_args.insert(0, ["open", "-an"]) + # use `open`. + if self.launch_context.launch_args[0] != executable: + return + + # Prepend open arguments + self.launch_context.launch_args.insert(0, ["open", "-a"]) From 221f60bb23364f46a2bb9e2a6443c449e57d9831 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 10:54:39 +0200 Subject: [PATCH 096/106] pass --args to tell which ards should be passed --- openpype/hooks/pre_mac_launch.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index e0c3133556..9fd3e94aa8 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -27,5 +27,8 @@ class LaunchWithTerminal(PreLaunchHook): if self.launch_context.launch_args[0] != executable: return + # Tell `open` to pass arguments if there are any + if len(self.launch_context.launch_args) > 1: + self.launch_context.launch_args.insert(1, "--args") # Prepend open arguments self.launch_context.launch_args.insert(0, ["open", "-a"]) From 61e10a4fc498691ac5e65c04bca0cf251d38823a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 10:54:54 +0200 Subject: [PATCH 097/106] modified docstring to match changes --- openpype/hooks/pre_mac_launch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index 9fd3e94aa8..3f07ae07db 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -6,9 +6,9 @@ class LaunchWithTerminal(PreLaunchHook): """Mac specific pre arguments for application. Mac applications should be launched using "open" argument which is internal - callbacks to open executable. We also add argument "-an" to create new - process. This is used only for executables ending with ".app". It is - expected that these executables lead to app packages. + callbacks to open executable. We also add argument "-a" to tell it's + application open. This is used only for executables ending with ".app". It + is expected that these executables lead to app packages. """ order = 1000 From a6d7e89d97a1a5a510a2e5fe023eae78b40d4347 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 10:55:35 +0200 Subject: [PATCH 098/106] ApplicationExecutable check if there is .app in passed path if does not exists on mac --- openpype/lib/applications.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index a44c43102f..d7674d64ad 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -440,7 +440,20 @@ class EnvironmentTool: class ApplicationExecutable: + """Representation of executable loaded from settings.""" + def __init__(self, executable): + # On MacOS check if exists path to executable when ends with `.app` + # - it is common that path will lead to "/Applications/Blender" but + # real path is "/Applications/Blender.app" + if ( + platform.system().lower() == "darwin" + and not os.path.exists(executable) + ): + _executable = executable + ".app" + if os.path.exists(_executable): + executable = _executable + self.executable_path = executable def __str__(self): From 77830ecb006616b1d46fc3826ee7248e3714d9fb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 13:06:47 +0200 Subject: [PATCH 099/106] separated catch error of filling workdir template and creating workdir on disk --- openpype/lib/applications.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index d7674d64ad..d82b7cd847 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1190,17 +1190,23 @@ def prepare_context_environments(data): try: workdir = get_workdir_with_workdir_data(workdir_data, anatomy) - if not os.path.exists(workdir): - log.debug( - "Creating workdir folder: \"{}\"".format(workdir) - ) - os.makedirs(workdir) except Exception as exc: raise ApplicationLaunchFailed( "Error in anatomy.format: {}".format(str(exc)) ) + if not os.path.exists(workdir): + log.debug( + "Creating workdir folder: \"{}\"".format(workdir) + ) + try: + os.makedirs(workdir) + except Exception as exc: + raise ApplicationLaunchFailed( + "Couldn't create workdir because: {}".format(str(exc)) + ) + context_env = { "AVALON_PROJECT": project_doc["name"], "AVALON_ASSET": asset_doc["name"], From 7ae8af5cd137348f00738c06403750fb99fea620 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 26 May 2021 17:47:29 +0200 Subject: [PATCH 100/106] fix python version detection --- tools/create_env.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/create_env.ps1 b/tools/create_env.ps1 index d690a89a2d..94a91ce48f 100644 --- a/tools/create_env.ps1 +++ b/tools/create_env.ps1 @@ -81,7 +81,7 @@ print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1])) Write-Host "FAILED Version [ $p ] is old and unsupported" -ForegroundColor red Set-Location -Path $current_dir Exit-WithCode 1 - } elseif (($matches[1] = 3) -or ($matches[2] -gt 7)) { + } elseif (($matches[1] -eq 3) -and ($matches[2] -gt 7)) { Write-Host "WARNING Version [ $p ] is unsupported, use at your own risk." -ForegroundColor yellow Write-Host "*** " -NoNewline -ForegroundColor yellow Write-Host "OpenPype supports only Python 3.7" -ForegroundColor white From 556975854b41ba6e9bf6d5124eddf669c4c74e44 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 26 May 2021 18:49:15 +0200 Subject: [PATCH 101/106] remove duplicate versions, print path --- igniter/bootstrap_repos.py | 9 +++++++++ start.py | 14 ++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index b44689ba89..7c4f8b4b69 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -203,6 +203,12 @@ class OpenPypeVersion(semver.VersionInfo): openpype_version.staging = True return openpype_version + def __hash__(self): + if self.path: + return hash(self.path) + else: + return hash(str(self)) + class BootstrapRepos: """Class for bootstrapping local OpenPype installation. @@ -650,6 +656,9 @@ class BootstrapRepos: v for v in openpype_versions if v.path.suffix != ".zip" ] + # remove duplicates + openpype_versions = list(set(openpype_versions)) + return openpype_versions def process_entered_location(self, location: str) -> Union[Path, None]: diff --git a/start.py b/start.py index 8a375a868d..424c6fe74b 100644 --- a/start.py +++ b/start.py @@ -496,10 +496,9 @@ def _find_frozen_openpype(use_version: str = None, if openpype_versions: print(" - found: ") for v in openpype_versions: - print(f" - {v}") - print(f" - {local_version}") - else: - print(f" - local version {local_version}") + print(f" - {v}: {v.path}") + + print(f" - local version {local_version}") sys.exit(1) # test if latest detected is installed (in user data dir) @@ -577,10 +576,9 @@ def _bootstrap_from_code(use_version): if openpype_versions: print(" - found: ") for v in openpype_versions: - print(f" - {v}") - print(f" - {local_version}") - else: - print(f" - local version {local_version}") + print(f" - {v}: {v.path}") + + print(f" - local version {local_version}") sys.exit(1) else: os.environ["OPENPYPE_VERSION"] = local_version From 955a07db465ee0019a482dfa990d3351fddfe3e9 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 26 May 2021 19:02:47 +0200 Subject: [PATCH 102/106] pref dir over zip --- start.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/start.py b/start.py index 424c6fe74b..6104882a0b 100644 --- a/start.py +++ b/start.py @@ -487,10 +487,9 @@ def _find_frozen_openpype(use_version: str = None, if use_version and use_version != local_version: openpype_versions = bootstrap.find_openpype(include_zips=True) v: OpenPypeVersion - for v in openpype_versions: - if str(v) == use_version: - openpype_version = v - version_path = openpype_version.path + found = [v for v in openpype_versions if str(v) == use_version] + if found: + openpype_version = sorted(found)[-1] if not openpype_version: print(f"!!! requested version {use_version} was not found.") if openpype_versions: @@ -558,9 +557,10 @@ def _bootstrap_from_code(use_version): version_to_use = None openpype_versions = bootstrap.find_openpype(include_zips=True) v: OpenPypeVersion - for v in openpype_versions: - if str(v) == use_version: - version_to_use = v + found = [v for v in openpype_versions if str(v) == use_version] + if found: + version_to_use = sorted(found)[-1] + if version_to_use: # use specified if version_to_use.path.is_file(): From c4ee752817c8dac92a4ed26a37faeb18d481eb8f Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 26 May 2021 19:11:58 +0200 Subject: [PATCH 103/106] missing version list sorted --- start.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/start.py b/start.py index 6104882a0b..74ee53fff7 100644 --- a/start.py +++ b/start.py @@ -494,7 +494,7 @@ def _find_frozen_openpype(use_version: str = None, print(f"!!! requested version {use_version} was not found.") if openpype_versions: print(" - found: ") - for v in openpype_versions: + for v in sorted(openpype_versions): print(f" - {v}: {v.path}") print(f" - local version {local_version}") @@ -575,7 +575,7 @@ def _bootstrap_from_code(use_version): print(f"!!! requested version {use_version} was not found.") if openpype_versions: print(" - found: ") - for v in openpype_versions: + for v in sorted(openpype_versions): print(f" - {v}: {v.path}") print(f" - local version {local_version}") From b34787a72830ee6d634e7804e6d7ba5124969e0a Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 27 May 2021 00:13:28 +0200 Subject: [PATCH 104/106] reset version in frozen code --- start.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/start.py b/start.py index 74ee53fff7..8ee9775ce8 100644 --- a/start.py +++ b/start.py @@ -436,7 +436,6 @@ def _find_frozen_openpype(use_version: str = None, if local_version == openpype_versions[-1]: os.environ["OPENPYPE_TRYOUT"] = "1" openpype_versions = [] - else: print("!!! Warning: cannot determine current running version.") @@ -485,7 +484,10 @@ def _find_frozen_openpype(use_version: str = None, # get path of version specified in `--use-version` local_version = bootstrap.get_version(OPENPYPE_ROOT) if use_version and use_version != local_version: - openpype_versions = bootstrap.find_openpype(include_zips=True) + # force the one user has selected + openpype_version = None + openpype_versions = bootstrap.find_openpype(include_zips=True, + staging=use_staging) v: OpenPypeVersion found = [v for v in openpype_versions if str(v) == use_version] if found: From 26f9a29f46897828028c669d0878deb52473c34d Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 11:35:21 +0200 Subject: [PATCH 105/106] update avalon core --- repos/avalon-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/avalon-core b/repos/avalon-core index cfd4191e36..0d9a228fdb 160000 --- a/repos/avalon-core +++ b/repos/avalon-core @@ -1 +1 @@ -Subproject commit cfd4191e364b47de7364096f45d9d9d9a901692a +Subproject commit 0d9a228fdb2eb08fe6caa30f25fe2a34fead1a03 From d58072f125720a01f689d55659e74101deb1b299 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 27 May 2021 11:37:13 +0200 Subject: [PATCH 106/106] bump rc version --- openpype/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/version.py b/openpype/version.py index a88ae329d0..202cb9348e 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.0.0-rc.5" +__version__ = "3.0.0-rc.6" diff --git a/pyproject.toml b/pyproject.toml index f7eeafd04f..7ba869e50e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenPype" -version = "3.0.0-rc.5" +version = "3.0.0-rc.6" description = "Open VFX and Animation pipeline with support." authors = ["OpenPype Team "] license = "MIT License"