From 027a642f8a22ecdbddda727c1b9e33b396f2c4a6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 9 Jan 2022 21:53:02 +0100 Subject: [PATCH 001/109] Implement get_container_members and fix #2507 - Remove special hardcoded case for "look" family where looks were still getting all nodes added to avalon container - Refactor shader assignment + mayalookassigner logic to use new `get_container_members` logic to still work as intended. --- openpype/hosts/maya/api/plugin.py | 31 +++++++------------ openpype/hosts/maya/plugins/load/load_look.py | 9 +++--- openpype/tools/mayalookassigner/commands.py | 4 +-- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index a5f03cd576..93387c073a 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -153,24 +153,15 @@ class ReferenceLoader(api.Loader): nodes = self[:] if not nodes: return - # FIXME: there is probably better way to do this for looks. - if "look" in self.families: - loaded_containers.append(containerise( - name=name, - namespace=namespace, - nodes=nodes, - context=context, - loader=self.__class__.__name__ - )) - else: - ref_node = get_reference_node(nodes, self.log) - loaded_containers.append(containerise( - name=name, - namespace=namespace, - nodes=[ref_node], - context=context, - loader=self.__class__.__name__ - )) + + ref_node = get_reference_node(nodes, self.log) + loaded_containers.append(containerise( + name=name, + namespace=namespace, + nodes=[ref_node], + context=context, + loader=self.__class__.__name__ + )) c += 1 namespace = None @@ -180,18 +171,18 @@ class ReferenceLoader(api.Loader): """To be implemented by subclass""" raise NotImplementedError("Must be implemented by subclass") - def update(self, container, representation): import os from maya import cmds + from openpype.hosts.maya.api.lib import get_container_members node = container["objectName"] path = api.get_representation_path(representation) # Get reference node from container members - members = cmds.sets(node, query=True, nodesOnly=True) + members = lib.get_container_members(node) reference_node = get_reference_node(members, self.log) file_type = { diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index fca612eff4..0a5ddee0cb 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -69,8 +69,10 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): path = api.get_representation_path(representation) # Get reference node from container members - members = cmds.sets(node, query=True, nodesOnly=True) - reference_node = self._get_reference_node(members) + members = openpype.hosts.maya.api.lib.get_container_members(container) + reference_node = openpype.hosts.maya.api.lib.get_reference_node( + members + ) shader_nodes = cmds.ls(members, type='shadingEngine') orig_nodes = set(self._get_nodes_with_shader(shader_nodes)) @@ -174,7 +176,6 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): node names """ import maya.cmds as cmds - # Get container members nodes_list = [] for shader in shader_nodes: @@ -225,5 +226,3 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): if cmds.getAttr("{}.verticesOnlySet".format(node)): self.log.info("Setting %s.verticesOnlySet to False", node) cmds.setAttr("{}.verticesOnlySet".format(node), False) - # Add new nodes of the reference to the container - cmds.sets(content, forceElement=node) diff --git a/openpype/tools/mayalookassigner/commands.py b/openpype/tools/mayalookassigner/commands.py index f7d26f9adb..54341470bc 100644 --- a/openpype/tools/mayalookassigner/commands.py +++ b/openpype/tools/mayalookassigner/commands.py @@ -88,7 +88,7 @@ def get_all_asset_nodes(): # Gather all information container_name = container["objectName"] - nodes += cmds.sets(container_name, query=True, nodesOnly=True) or [] + nodes += lib.get_container_members(container_name) return nodes @@ -199,7 +199,7 @@ def remove_unused_looks(): unused = [] for container in host.ls(): if container['loader'] == "LookLoader": - members = cmds.sets(container['objectName'], query=True) + members = lib.get_container_members(container['objectName']) look_sets = cmds.ls(members, type="objectSet") for look_set in look_sets: # If the set is used than we consider this look *in use* From 767bb4ba0eb7ed556fdcd4070300a79395e074b7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 9 Jan 2022 22:06:12 +0100 Subject: [PATCH 002/109] Refactor more relevant code to use `lib.get_container_members` --- openpype/hosts/maya/api/lib.py | 38 ++++++++++++++++++- .../tools/mayalookassigner/vray_proxies.py | 2 +- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 52ebcaff64..c62a221678 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -1314,6 +1314,40 @@ def apply_attributes(attributes, nodes_by_id): set_attribute(attr, value, node) +def get_container_members(container): + """Returns the members of a container. + This includes the nodes from any loaded references in the container. + """ + if isinstance(container, dict): + # Assume it's a container dictionary + container = container["objectName"] + + members = cmds.sets(container, query=True) or [] + members = cmds.ls(members, long=True, objectsOnly=True) or [] + members = set(members) + + # Include any referenced nodes from any reference in the container + # This is required since we've removed adding ALL nodes of a reference + # into the container set and only add the reference node now. + for ref in cmds.ls(members, exactType="reference", objectsOnly=True): + + # Ignore any `:sharedReferenceNode` + if ref.rsplit(":", 1)[-1].startswith("sharedReferenceNode"): + continue + + # Ignore _UNKNOWN_REF_NODE_ (PLN-160) + if ref.rsplit(":", 1)[-1].startswith("_UNKNOWN_REF_NODE_"): + continue + + reference_members = cmds.referenceQuery(ref, nodes=True) + reference_members = cmds.ls(reference_members, + long=True, + objectsOnly=True) + members.update(reference_members) + + return members + + # region LOOKDEV def list_looks(asset_id): """Return all look subsets for the given asset @@ -1376,7 +1410,7 @@ def assign_look_by_version(nodes, version_id): container_node = pipeline.load(Loader, look_representation) # Get container members - shader_nodes = cmds.sets(container_node, query=True) + shader_nodes = get_container_members(container_node) # Load relationships shader_relation = api.get_representation_path(json_representation) @@ -1602,7 +1636,7 @@ def get_container_transforms(container, members=None, root=False): """ if not members: - members = cmds.sets(container["objectName"], query=True) + members = get_container_members(container) results = cmds.ls(members, type="transform", long=True) if root: diff --git a/openpype/tools/mayalookassigner/vray_proxies.py b/openpype/tools/mayalookassigner/vray_proxies.py index d2f345e628..f6e98f91bf 100644 --- a/openpype/tools/mayalookassigner/vray_proxies.py +++ b/openpype/tools/mayalookassigner/vray_proxies.py @@ -202,7 +202,7 @@ def load_look(version_id): container_node = api.load(loader, look_representation) # Get container members - shader_nodes = cmds.sets(container_node, query=True) + shader_nodes = lib.get_container_members(container_node) return shader_nodes From 0f00790601c9ac69ba02e60f25b81834cdd5f4ee Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 9 Jan 2022 22:08:42 +0100 Subject: [PATCH 003/109] Fix typo: refactor so it uses the correct imported namespace --- openpype/hosts/maya/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 93387c073a..9b158dee39 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -182,7 +182,7 @@ class ReferenceLoader(api.Loader): path = api.get_representation_path(representation) # Get reference node from container members - members = lib.get_container_members(node) + members = get_container_members(node) reference_node = get_reference_node(members, self.log) file_type = { From 558b934c687c2976fb1afc220a7d37dd3eb71737 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 20 Jan 2022 22:03:09 +0100 Subject: [PATCH 004/109] flame: fix collecting files to representation in case of custom flame export preset with multiple nested structures --- .../publish/extract_subset_resources.py | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index 291e440cbe..8cc27aff06 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -129,16 +129,23 @@ class ExtractSubsetResources(openpype.api.Extractor): opfapi.export_clip( export_dir_path, duplclip, preset_path, **kwargs) + extension = preset_config["ext"] # create representation data representation_data = { "name": unique_name, "outputName": unique_name, - "ext": preset_config["ext"], + "ext": extension, "stagingDir": export_dir_path, "tags": repre_tags } files = os.listdir(export_dir_path) + n_stage_dir, n_files = self.check_if_dirs_in_paths( + export_dir_path, files, extension) + + if n_stage_dir: + representation_data["stagingDir"] = n_stage_dir + files = n_files # add files to represetation but add # imagesequence as list @@ -170,3 +177,35 @@ class ExtractSubsetResources(openpype.api.Extractor): self.log.debug("All representations: {}".format( pformat(instance.data["representations"]))) + + def check_if_dirs_in_paths(self, stage_dir, files_list, ext): + + if ( + len(files_list) == 1 + and ext in os.path.splitext(files_list[0])[-1] + ): + + return None, None + + new_stage_dir = None + new_files_list = [] + for file in files_list: + search_path = os.path.join(stage_dir, file) + if not os.path.isdir(search_path): + continue + for root, _dirs, files in os.walk(search_path): + for _file in files: + _fn, _ext = os.path.splitext(_file) + if ext.lower() != _ext[1:].lower(): + continue + new_files_list.append(_file) + if not new_stage_dir: + new_stage_dir = root + + if new_stage_dir: + return new_stage_dir, new_files_list + else: + raise IOError( + "Files in `{}` are not correct! Check `{}`".format( + files_list, stage_dir) + ) From 4f7bcceaddeef602a959dea32ed1ace2e14fdeab Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 21 Jan 2022 10:38:47 +0100 Subject: [PATCH 005/109] Flame: nested folder renamed and doc-string added --- .../publish/extract_subset_resources.py | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index 8cc27aff06..8d244b312b 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -139,10 +139,14 @@ class ExtractSubsetResources(openpype.api.Extractor): "tags": repre_tags } + # collect all available content of export dir files = os.listdir(export_dir_path) - n_stage_dir, n_files = self.check_if_dirs_in_paths( + + # make sure no nested folders inside + n_stage_dir, n_files = self._unfolds_nested_folders( export_dir_path, files, extension) + # fix representation in case of nested folders if n_stage_dir: representation_data["stagingDir"] = n_stage_dir files = n_files @@ -178,13 +182,28 @@ class ExtractSubsetResources(openpype.api.Extractor): self.log.debug("All representations: {}".format( pformat(instance.data["representations"]))) - def check_if_dirs_in_paths(self, stage_dir, files_list, ext): + def _unfolds_nested_folders(self, stage_dir, files_list, ext): + """Unfolds nested folders + Args: + stage_dir (str): path string with directory + files_list (list): list of file names + ext (str): extension (jpg)[without dot] + + Raises: + IOError: in case no files were collected form any directory + + Returns: + str, list: new staging dir path, new list of file names + or + None, None: In case single file in `files_list` + """ + # exclude single files which are having extension + # the same as input ext attr if ( len(files_list) == 1 and ext in os.path.splitext(files_list[0])[-1] ): - return None, None new_stage_dir = None From 279e7d863145ad3641c0afd43bc539480ddcfe6a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 21 Jan 2022 12:06:05 +0100 Subject: [PATCH 006/109] Flame: distribute colorspace to representations --- .../hosts/flame/plugins/publish/extract_subset_resources.py | 6 +++++- openpype/settings/defaults/project_settings/flame.json | 3 ++- .../schemas/projects_schema/schema_project_flame.json | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index 8d244b312b..a0345d5175 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -22,6 +22,7 @@ class ExtractSubsetResources(openpype.api.Extractor): "ext": "jpg", "xml_preset_file": "Jpeg (8-bit).xml", "xml_preset_dir": "", + "colorspace_out": "Output - sRGB", "representation_add_range": False, "representation_tags": ["thumbnail"] }, @@ -29,6 +30,7 @@ class ExtractSubsetResources(openpype.api.Extractor): "ext": "mov", "xml_preset_file": "Apple iPad (1920x1080).xml", "xml_preset_dir": "", + "colorspace_out": "Output - Rec.709", "representation_add_range": True, "representation_tags": [ "review", @@ -84,6 +86,7 @@ class ExtractSubsetResources(openpype.api.Extractor): preset_file = preset_config["xml_preset_file"] preset_dir = preset_config["xml_preset_dir"] repre_tags = preset_config["representation_tags"] + color_out = preset_config["colorspace_out"] # validate xml preset file is filled if preset_file == "": @@ -136,7 +139,8 @@ class ExtractSubsetResources(openpype.api.Extractor): "outputName": unique_name, "ext": extension, "stagingDir": export_dir_path, - "tags": repre_tags + "tags": repre_tags, + "colorspace": color_out } # collect all available content of export dir diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json index c81069ef5c..3caf190e37 100644 --- a/openpype/settings/defaults/project_settings/flame.json +++ b/openpype/settings/defaults/project_settings/flame.json @@ -24,8 +24,9 @@ "export_presets_mapping": { "exr16fpdwaa": { "ext": "exr", - "xml_preset_dir": "", "xml_preset_file": "OpenEXR (16-bit fp DWAA).xml", + "xml_preset_dir": "", + "colorspace_out": "ACES - ACEScg", "representation_add_range": true, "representation_tags": [] } diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json index 76576ebf73..4cb1a0bb2b 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json @@ -166,6 +166,11 @@ "label": "XML preset folder (optional)", "type": "text" }, + { + "key": "colorspace_out", + "label": "Output color (imageio)", + "type": "text" + }, { "type": "separator" }, From dc419ceaed338fe8c45f5e32d21386a4eabaa9c8 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 21 Jan 2022 12:46:35 +0100 Subject: [PATCH 007/109] flame: add colorspace to representation["data"] --- .../publish/extract_subset_resources.py | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index a0345d5175..a80366b9e4 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -47,6 +47,16 @@ class ExtractSubsetResources(openpype.api.Extractor): export_presets_mapping = {} def process(self, instance): + try: + self._process(instance) + # bring ui back + self.hide_ui_on_process = False + except Exception as msg: + self.log.error(msg) + # bring ui back + self.hide_ui_on_process = False + + def _process(self, instance): if ( self.keep_original_representation @@ -140,7 +150,9 @@ class ExtractSubsetResources(openpype.api.Extractor): "ext": extension, "stagingDir": export_dir_path, "tags": repre_tags, - "colorspace": color_out + "data": { + "colorspace": color_out + } } # collect all available content of export dir @@ -205,10 +217,23 @@ class ExtractSubsetResources(openpype.api.Extractor): # exclude single files which are having extension # the same as input ext attr if ( + # only one file in list len(files_list) == 1 + # file is having extension as input and ext in os.path.splitext(files_list[0])[-1] ): return None, None + elif ( + # more then one file in list + len(files_list) >= 1 + # extension is correct + and ext in os.path.splitext(files_list[0])[-1] + # test file exists + and os.path.exists( + os.path.join(stage_dir, files_list[0]) + ) + ): + return None, None new_stage_dir = None new_files_list = [] From 34338689802ca5b195663b46e9bb35632d35d68e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 21 Jan 2022 12:43:35 +0100 Subject: [PATCH 008/109] Use namespace directly instead of parsing from first member (cherry picked from commit 4cc7003cea27d468c847a1eb9c510160242abc9b) --- openpype/hosts/maya/api/plugin.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 9b158dee39..a4501a5f02 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -184,6 +184,7 @@ class ReferenceLoader(api.Loader): # Get reference node from container members members = get_container_members(node) reference_node = get_reference_node(members, self.log) + namespace = cmds.referenceQuery(reference_node, namespace=True) file_type = { "ma": "mayaAscii", @@ -201,18 +202,14 @@ class ReferenceLoader(api.Loader): alembic_data = {} if representation["name"] == "abc": alembic_nodes = cmds.ls( - "{}:*".format(members[0].split(":")[0]), type="AlembicNode" + "{}:*".format(namespace), type="AlembicNode" ) if alembic_nodes: for attr in alembic_attrs: node_attr = "{}.{}".format(alembic_nodes[0], attr) alembic_data[attr] = cmds.getAttr(node_attr) else: - cmds.warning( - "No alembic nodes found in {}".format( - cmds.ls("{}:*".format(members[0].split(":")[0])) - ) - ) + self.log.debug("No alembic nodes found in {}".format(members)) try: content = cmds.file(path, @@ -236,9 +233,9 @@ class ReferenceLoader(api.Loader): self.log.warning("Ignoring file read error:\n%s", exc) # Reapply alembic settings. - if representation["name"] == "abc": + if representation["name"] == "abc" and alembic_data: alembic_nodes = cmds.ls( - "{}:*".format(members[0].split(":")[0]), type="AlembicNode" + "{}:*".format(namespace), type="AlembicNode" ) if alembic_nodes: for attr, value in alembic_data.items(): From c8d7eb558b53dbfb39361d6d75d7c86d0bba1d3a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 25 Jan 2022 09:16:39 +0100 Subject: [PATCH 009/109] Refactor to using correct get_reference_node function --- openpype/hosts/maya/plugins/load/load_look.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index 0a5ddee0cb..d0061917ab 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -70,8 +70,8 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): # Get reference node from container members members = openpype.hosts.maya.api.lib.get_container_members(container) - reference_node = openpype.hosts.maya.api.lib.get_reference_node( - members + reference_node = openpype.hosts.maya.api.plugin.get_reference_node( + members, log=self.log ) shader_nodes = cmds.ls(members, type='shadingEngine') From 1736b5338fed9af89428a81220416b486c03277a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 25 Jan 2022 17:18:22 +0100 Subject: [PATCH 010/109] flame: trying export openclip wip --- openpype/hosts/flame/api/render_utils.py | 320 +++++++++++++++++++++++ 1 file changed, 320 insertions(+) diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index 1b086646cc..bc9ebb83d4 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -1,4 +1,10 @@ import os +import sys +import traceback +from xml.etree import ElementTree as ET +import shutil +import openpype.lib +import six def export_clip(export_path, clip, preset_path, **kwargs): @@ -123,3 +129,317 @@ def get_preset_path_by_xml_name(xml_preset_name): # if nothing found then return False return False + + +def get_open_clip( + openclip_file_path, feed_data, recursive=False): + + # establish media script path and test it + media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" + if not os.path.isfile(media_script_path): + raise IOError("Media Scirpt does not exist: `{}`".format( + media_script_path)) + + # new feed variables: + feed_path = feed_data["path"] + feed_basename = os.path.basename(feed_path) + feed_version_name = feed_data["version"] + + clip_uploaded = False + create_new_clip = False + + ext_whitelist = [ + "cin", "als", "jpg", "jpeg", "pict", "pct", "picio", + "sgi", "pic", "tga", "iff", "tdi", "tif", "tiff", "rla", + "cin.pxz", "tif.pxz", "tiff.pxz", "dpx", "dpx.pxz", + "hdr", "png", "exr", "exr.pxz", "psd" + ] + + feed_ext = os.path.splitext(feed_basename)[1][1:].lower() + + if feed_ext not in ext_whitelist: + print("File extension `{}` is not supported".format(feed_ext)) + return False + + if not os.path.isfile(openclip_file_path): + # openclip does not exist yet and will be created + feed_path = os.path.abspath(feed_path) + tmp_file = openclip_file_path + create_new_clip = True + clip_uploaded = True + else: + # openclip will be updated via temp.clip file + tmp_name = "tmp.clip" + feed_path = os.path.abspath(feed_path) + feed_dir = os.path.dirname(feed_path) + + # output a temp file + tmp_file = os.path.join(feed_dir, tmp_name) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + + print("Temp File: {}".format(tmp_file)) + + # Write output of getMediaScript to file + cmd_args = [media_script_path, feed_path] + if recursive: + print("recursive enabled on dl_get_media_info") + cmd_args = [media_script_path, "-r", feed_path] + + # execute creation of clip xml template data + try: + output = openpype.lib.run_subprocess(cmd_args) + except TypeError: + print("Error createing tmp_file") + six.reraise(*sys.exc_info()) + + with open(tmp_file, "w") as f: + f.write("{}".format(output)) + + # Check media type for valid extension + try: + tmp_xml = ET.parse(tmp_file) + except: + print("XML is probably empty.") + print('{}'.format(traceback.print_exc())) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + for newTrack in tmp_xml.iter('track'): + new_path_obj = newTrack.find("feeds/feed/spans/span/path") + new_path = new_path_obj.text + print("tmp_xml new_path: {}".format(new_path)) + + new_path_ext = os.path.splitext(new_path)[1][1:].strip().lower() + if new_path_ext in ext_whitelist: + print("Found media `{}`".format(new_path_ext)) + else: + print("Extension {} is not supported".format( + new_path_ext)) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + if not create_new_clip: + print("Updating openClip ..") + + try: + source_xml = ET.parse(openclip_file_path) + except: + print("XML is probably empty.") + print('%s' % traceback.print_exc()) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + try: + new_xml = ET.parse(tmp_file) + except: + print("XML is probably empty.") + print('%s' % traceback.print_exc()) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + try: + feed_exists = False + feed_added = 0 + + src_editRateNumerator = None + src_editRateDenominator = None + src_nbTicks = None + src_rate = None + src_dropMode = None + + for srcTrack in source_xml.iter('track'): + src_editRateNumeratorObj = srcTrack.find('editRate/numerator') + src_editRateNumerator = src_editRateNumeratorObj.text + src_editRateDenominatorObj = srcTrack.find( + 'editRate/denominator') + src_editRateDenominator = src_editRateDenominatorObj.text + + for srcFeed in srcTrack.iter('feed'): + src_nbTicksObj = srcFeed.find('startTimecode/nbTicks') + src_nbTicks = src_nbTicksObj.text + src_rateObj = srcFeed.find('startTimecode/rate') + src_rate = src_rateObj.text + src_dropModeObj = srcFeed.find('startTimecode/dropMode') + src_dropMode = src_dropModeObj.text + break + else: + continue + break + + print("Source editRate/numerator: %s" % src_editRateNumerator) + print("Source editRate/denominator: %s" % src_editRateDenominator) + print("Source startTimecode/nbTicks: %s" % src_nbTicks) + print("Source startTimecode/rate: %s" % src_rate) + print("Source startTimecode/dropMode: %s" % src_dropMode) + + # Get new feed from file + for newTrack in new_xml.iter('track'): + uid = newTrack.get('uid') + newFeed = newTrack.find('feeds/feed') + + feedHandler = newFeed.find("./handler") + newFeed.remove(feedHandler) + + if src_editRateNumerator: + new_editRateNumeratorObject = newTrack.find( + "feeds/feed/sampleRate/numerator") + new_editRateNumeratorObject.text = src_editRateNumerator + if src_editRateDenominator: + new_editRateDenominatorObject = newTrack.find( + "feeds/feed/sampleRate/denominator") + new_editRateDenominatorObject.text = src_editRateDenominator + if src_rate: + new_rateObject = newTrack.find( + "feeds/feed/startTimecode/rate") + new_rateObject.text = src_rate + if src_nbTicks: + new_nbTicksObject = newTrack.find( + "feeds/feed/startTimecode/nbTicks") + new_nbTicksObject.text = src_nbTicks + if src_dropMode: + new_dropModeObj = newTrack.find( + "feeds/feed/startTimecode/dropMode") + new_dropModeObj.text = src_dropMode + + new_path_obj = newTrack.find("feeds/feed/spans/span/path") + new_path = new_path_obj.text + + print(">> uid: {}".format(uid)) + print(">> new_path: {}".format(new_path)) + + # Check for path in sourceFile + # If Path exists ... skip append + for srcPath in source_xml.iter('path'): + if new_path == srcPath.text: + print("Element exists in clip... skipping append") + feed_exists = True + + if not feed_exists: + # Append new feed to source track + for srcTrack in source_xml.iter('track'): + newFeed.set('vuid', feed_version_name) + srcTrack.find('feeds').append(newFeed) + print( + "Appending new feed: {}".format(feed_version_name)) + feed_added += 1 + + if feed_added > 0: + # Append vUID to versions + newVersion = source_xml.find('versions') + newVersionElement = ET.Element( + "version", {"type": "version", "uid": feed_version_name}) + newVersion.insert(0, newVersionElement) + xmlRoot = source_xml.getroot() + + # Clean tmp_file - brute force remove errant + print("Removing Handler") + for handler in xmlRoot.findall("./handler"): + print("Handler found") + xmlRoot.remove(handler) + + resultXML = ET.tostring(xmlRoot).decode('utf-8') + + # fist create backup + create_openclip_backup_file(openclip_file_path) + + out_file = openclip_file_path + + print("Adding feed version: {}".format(feed_version_name)) + + with open(out_file, "w") as f: + f.write(resultXML) + + print("openClip Updated: {}".format(out_file)) + + clip_uploaded = True + + if os.path.isfile(tmp_file): + os.remove(tmp_file) + + except: + print("Failed reading XML") + print('%s' % traceback.print_exc()) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + else: + # New openClip + print("Building new openClip") + + # Update uid name with element_name + try: + new_xml = ET.parse(tmp_file) + except: + print("Failed reading XML") + print('%s' % traceback.print_exc()) + if os.path.isfile(tmp_file): + os.remove(tmp_file) + return False + + try: + for newFeed in new_xml.iter('feeds'): + feed = newFeed.find('feed') + feed.set('vuid', feed_basename) + + feedHandler = feed.find("./handler") + feed.remove(feedHandler) + + for newVersion in new_xml.iter('versions'): + newVersion.set('currentVersion', feed_basename) + version = newVersion.find('version') + version.set('uid', feed_basename) + version.set('type', 'version') + + xmlRoot = new_xml.getroot() + + # Clean tmp_file - brute force remove errant + print("Removing Handler") + for handler in xmlRoot.findall("./handler"): + print("Handler found") + xmlRoot.remove(handler) + + resultXML = ET.tostring(xmlRoot).decode('utf-8') + + print("Adding feed version: %s" % feed_basename) + + with open(tmp_file, "w") as f: + f.write(resultXML) + + print("openClip Updated: %s" % tmp_file) + + clip_uploaded = True + + except: + print("Failed to update openClip: %s" % tmp_file) + print('%s' % traceback.print_exc()) + + return clip_uploaded + + +def create_openclip_backup_file(file): + bck_file = "{}.bak".format(file) + # if backup does not exist + if not os.path.isfile(bck_file): + shutil.copy2(file, bck_file) + else: + # in case it exists and is already multiplied + created = False + for _i in range(1, 99): + bck_file = "{name}.bak.{idx:0>2}".format( + name=file, + idx=_i) + # create numbered backup file + if not os.path.isfile(bck_file): + shutil.copy2(file, bck_file) + created = True + break + # in case numbered does not exists + if not created: + bck_file = "{}.bak.last".format(file) + shutil.copy2(file, bck_file) From 447b3f835feba2ef72dfcf14ed9e1b84effa2e8a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 25 Jan 2022 17:57:36 +0100 Subject: [PATCH 011/109] flame: loading with openclip wip --- openpype/hosts/flame/api/render_utils.py | 195 +++++++++++------------ 1 file changed, 90 insertions(+), 105 deletions(-) diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index bc9ebb83d4..e6283b725a 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -199,6 +199,7 @@ def get_open_clip( # Check media type for valid extension try: tmp_xml = ET.parse(tmp_file) + print(tmp_xml) except: print("XML is probably empty.") print('{}'.format(traceback.print_exc())) @@ -224,34 +225,23 @@ def get_open_clip( if not create_new_clip: print("Updating openClip ..") - try: - source_xml = ET.parse(openclip_file_path) - except: - print("XML is probably empty.") - print('%s' % traceback.print_exc()) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False + source_xml = ET.parse(openclip_file_path) + new_xml = ET.parse(tmp_file) + + print(">> source_xml: {}".format(source_xml)) + print(">> new_xml: {}".format(new_xml)) + + + feed_exists = False + feed_added = 0 + + src_editRateNumerator = None + src_editRateDenominator = None + src_nbTicks = None + src_rate = None + src_dropMode = None try: - new_xml = ET.parse(tmp_file) - except: - print("XML is probably empty.") - print('%s' % traceback.print_exc()) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False - - try: - feed_exists = False - feed_added = 0 - - src_editRateNumerator = None - src_editRateDenominator = None - src_nbTicks = None - src_rate = None - src_dropMode = None - for srcTrack in source_xml.iter('track'): src_editRateNumeratorObj = srcTrack.find('editRate/numerator') src_editRateNumerator = src_editRateNumeratorObj.text @@ -270,103 +260,98 @@ def get_open_clip( else: continue break + except Exception as msg: + print(msg) - print("Source editRate/numerator: %s" % src_editRateNumerator) - print("Source editRate/denominator: %s" % src_editRateDenominator) - print("Source startTimecode/nbTicks: %s" % src_nbTicks) - print("Source startTimecode/rate: %s" % src_rate) - print("Source startTimecode/dropMode: %s" % src_dropMode) + print("Source editRate/numerator: %s" % src_editRateNumerator) + print("Source editRate/denominator: %s" % src_editRateDenominator) + print("Source startTimecode/nbTicks: %s" % src_nbTicks) + print("Source startTimecode/rate: %s" % src_rate) + print("Source startTimecode/dropMode: %s" % src_dropMode) - # Get new feed from file - for newTrack in new_xml.iter('track'): - uid = newTrack.get('uid') - newFeed = newTrack.find('feeds/feed') + # Get new feed from file + for newTrack in new_xml.iter('track'): + uid = newTrack.get('uid') + newFeed = newTrack.find('feeds/feed') - feedHandler = newFeed.find("./handler") - newFeed.remove(feedHandler) + feedHandler = newFeed.find("./handler") + newFeed.remove(feedHandler) - if src_editRateNumerator: - new_editRateNumeratorObject = newTrack.find( - "feeds/feed/sampleRate/numerator") - new_editRateNumeratorObject.text = src_editRateNumerator - if src_editRateDenominator: - new_editRateDenominatorObject = newTrack.find( - "feeds/feed/sampleRate/denominator") - new_editRateDenominatorObject.text = src_editRateDenominator - if src_rate: - new_rateObject = newTrack.find( - "feeds/feed/startTimecode/rate") - new_rateObject.text = src_rate - if src_nbTicks: - new_nbTicksObject = newTrack.find( - "feeds/feed/startTimecode/nbTicks") - new_nbTicksObject.text = src_nbTicks - if src_dropMode: - new_dropModeObj = newTrack.find( - "feeds/feed/startTimecode/dropMode") - new_dropModeObj.text = src_dropMode + if src_editRateNumerator: + new_editRateNumeratorObject = newTrack.find( + "feeds/feed/sampleRate/numerator") + new_editRateNumeratorObject.text = src_editRateNumerator + if src_editRateDenominator: + new_editRateDenominatorObject = newTrack.find( + "feeds/feed/sampleRate/denominator") + new_editRateDenominatorObject.text = src_editRateDenominator + if src_rate: + new_rateObject = newTrack.find( + "feeds/feed/startTimecode/rate") + new_rateObject.text = src_rate + if src_nbTicks: + new_nbTicksObject = newTrack.find( + "feeds/feed/startTimecode/nbTicks") + new_nbTicksObject.text = src_nbTicks + if src_dropMode: + new_dropModeObj = newTrack.find( + "feeds/feed/startTimecode/dropMode") + new_dropModeObj.text = src_dropMode - new_path_obj = newTrack.find("feeds/feed/spans/span/path") - new_path = new_path_obj.text + new_path_obj = newTrack.find("feeds/feed/spans/span/path") + new_path = new_path_obj.text - print(">> uid: {}".format(uid)) - print(">> new_path: {}".format(new_path)) + print(">> uid: {}".format(uid)) + print(">> new_path: {}".format(new_path)) - # Check for path in sourceFile - # If Path exists ... skip append - for srcPath in source_xml.iter('path'): - if new_path == srcPath.text: - print("Element exists in clip... skipping append") - feed_exists = True + # Check for path in sourceFile + # If Path exists ... skip append + for srcPath in source_xml.iter('path'): + if new_path == srcPath.text: + print("Element exists in clip... skipping append") + feed_exists = True - if not feed_exists: - # Append new feed to source track - for srcTrack in source_xml.iter('track'): - newFeed.set('vuid', feed_version_name) - srcTrack.find('feeds').append(newFeed) - print( - "Appending new feed: {}".format(feed_version_name)) - feed_added += 1 + if not feed_exists: + # Append new feed to source track + for srcTrack in source_xml.iter('track'): + newFeed.set('vuid', feed_version_name) + srcTrack.find('feeds').append(newFeed) + print( + "Appending new feed: {}".format(feed_version_name)) + feed_added += 1 - if feed_added > 0: - # Append vUID to versions - newVersion = source_xml.find('versions') - newVersionElement = ET.Element( - "version", {"type": "version", "uid": feed_version_name}) - newVersion.insert(0, newVersionElement) - xmlRoot = source_xml.getroot() + if feed_added > 0: + # Append vUID to versions + newVersion = source_xml.find('versions') + newVersionElement = ET.Element( + "version", {"type": "version", "uid": feed_version_name}) + newVersion.insert(0, newVersionElement) + xmlRoot = source_xml.getroot() - # Clean tmp_file - brute force remove errant - print("Removing Handler") - for handler in xmlRoot.findall("./handler"): - print("Handler found") - xmlRoot.remove(handler) + # Clean tmp_file - brute force remove errant + print("Removing Handler") + for handler in xmlRoot.findall("./handler"): + print("Handler found") + xmlRoot.remove(handler) - resultXML = ET.tostring(xmlRoot).decode('utf-8') + resultXML = ET.tostring(xmlRoot).decode('utf-8') - # fist create backup - create_openclip_backup_file(openclip_file_path) + # fist create backup + create_openclip_backup_file(openclip_file_path) - out_file = openclip_file_path + out_file = openclip_file_path - print("Adding feed version: {}".format(feed_version_name)) + print("Adding feed version: {}".format(feed_version_name)) - with open(out_file, "w") as f: - f.write(resultXML) + with open(out_file, "w") as f: + f.write(resultXML) - print("openClip Updated: {}".format(out_file)) + print("openClip Updated: {}".format(out_file)) - clip_uploaded = True + clip_uploaded = True - if os.path.isfile(tmp_file): - os.remove(tmp_file) - - except: - print("Failed reading XML") - print('%s' % traceback.print_exc()) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False + if os.path.isfile(tmp_file): + os.remove(tmp_file) else: # New openClip From 5399478cf54c461e6e4ea97fafa80749a6f00626 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Jan 2022 16:43:52 +0100 Subject: [PATCH 012/109] Remove obsolete code that failed to work --- openpype/hosts/maya/plugins/load/load_look.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index 845869b774..fb4a0b4217 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -113,22 +113,6 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): with open(shader_relation, "r") as f: json_data = json.load(f) - for rel, data in json_data["relationships"].items(): - # process only non-shading nodes - current_node = "{}:{}".format(container["namespace"], rel) - if current_node in shader_nodes: - continue - print("processing {}".format(rel)) - current_members = set(cmds.ls( - cmds.sets(current_node, query=True) or [], long=True)) - new_members = {"{}".format( - m["name"]) for m in data["members"] or []} - dif = new_members.difference(current_members) - - # add to set - cmds.sets( - dif, forceElement="{}:{}".format(container["namespace"], rel)) - # update of reference could result in failed edits - material is not # present because of renaming etc. failed_edits = cmds.referenceQuery(reference_node, From 58a559fc2c84b40483bc76a5e93e49bb3ce70568 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Jan 2022 17:06:55 +0100 Subject: [PATCH 013/109] Rely more on update logic from parent ReferenceLoader class - reduce duplicated code --- openpype/hosts/maya/plugins/load/load_look.py | 75 +------------------ 1 file changed, 4 insertions(+), 71 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index fb4a0b4217..c121cb8f56 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -65,38 +65,18 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): Returns: None """ - import os from maya import cmds - node = container["objectName"] - path = api.get_representation_path(representation) # Get reference node from container members members = openpype.hosts.maya.api.lib.get_container_members(container) reference_node = openpype.hosts.maya.api.plugin.get_reference_node( members, log=self.log ) - shader_nodes = cmds.ls(members, type='shadingEngine') orig_nodes = set(self._get_nodes_with_shader(shader_nodes)) - file_type = { - "ma": "mayaAscii", - "mb": "mayaBinary", - "abc": "Alembic" - }.get(representation["name"]) - - assert file_type, "Unsupported representation: %s" % representation - - assert os.path.exists(path), "%s does not exist." % path - - self._load_reference(file_type, node, path, reference_node) - - # Remove any placeHolderList attribute entries from the set that - # are remaining from nodes being removed from the referenced file. - members = cmds.sets(node, query=True) - invalid = [x for x in members if ".placeHolderList" in x] - if invalid: - cmds.sets(invalid, remove=node) + # Trigger the regular reference update on the ReferenceLoader + super(LookLoader, self).update(container, representation) # get new applied shaders and nodes from new version shader_nodes = cmds.ls(members, type='shadingEngine') @@ -114,13 +94,11 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): json_data = json.load(f) # update of reference could result in failed edits - material is not - # present because of renaming etc. + # present because of renaming etc. If so highlight failed edits to user failed_edits = cmds.referenceQuery(reference_node, editStrings=True, failedEdits=True, successfulEdits=False) - - # highlight failed edits to user if failed_edits: # clean references - removes failed reference edits cmds.file(cr=reference_node) # cleanReference @@ -148,11 +126,6 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): nodes_by_id[openpype.hosts.maya.api.lib.get_id(n)].append(n) openpype.hosts.maya.api.lib.apply_attributes(attributes, nodes_by_id) - # Update metadata - cmds.setAttr("{}.representation".format(node), - str(representation["_id"]), - type="string") - def _get_nodes_with_shader(self, shader_nodes): """ Returns list of nodes belonging to specific shaders @@ -171,44 +144,4 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): for connection in connections: nodes_list.extend(cmds.listRelatives(connection, shapes=True)) - return nodes_list - - def _load_reference(self, file_type, node, path, reference_node): - """ - Load reference from 'path' on 'reference_node'. Used when change - of look (version/update) is triggered. - Args: - file_type: extension of referenced file - node: - path: (string) location of referenced file - reference_node: (string) - name of node that should be applied - on - Returns: - None - """ - import maya.cmds as cmds - try: - content = cmds.file(path, - loadReference=reference_node, - type=file_type, - returnNewNodes=True) - except RuntimeError as exc: - # When changing a reference to a file that has load errors the - # command will raise an error even if the file is still loaded - # correctly (e.g. when raising errors on Arnold attributes) - # When the file is loaded and has content, we consider it's fine. - if not cmds.referenceQuery(reference_node, isLoaded=True): - raise - - content = cmds.referenceQuery(reference_node, - nodes=True, - dagPath=True) - if not content: - raise - - self.log.warning("Ignoring file read error:\n%s", exc) - # Fix PLN-40 for older containers created with Avalon that had the - # `.verticesOnlySet` set to True. - if cmds.getAttr("{}.verticesOnlySet".format(node)): - self.log.info("Setting %s.verticesOnlySet to False", node) - cmds.setAttr("{}.verticesOnlySet".format(node), False) + return nodes_list \ No newline at end of file From 9dc0e266d2dbbb23f8f16f96ed42344c668cca1b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Jan 2022 17:07:36 +0100 Subject: [PATCH 014/109] Shush the hound - add newline at end of file --- openpype/hosts/maya/plugins/load/load_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index c121cb8f56..f0406186ae 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -144,4 +144,4 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): for connection in connections: nodes_list.extend(cmds.listRelatives(connection, shapes=True)) - return nodes_list \ No newline at end of file + return nodes_list From 5d208d2ac1f50df00f99cd4de77a0b3e2c3bd520 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Jan 2022 17:10:02 +0100 Subject: [PATCH 015/109] Remove docstring that was incorrect - code wasn't actually doing that --- openpype/hosts/maya/plugins/load/load_look.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index f0406186ae..8345253968 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -23,18 +23,6 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): color = "orange" def process_reference(self, context, name, namespace, options): - """ - Load and try to assign Lookdev to nodes based on relationship data. - - Args: - name: - namespace: - context: - options: - - Returns: - - """ import maya.cmds as cmds from avalon import maya From 8527e4691fa12d0b47fefd3a117d0f1a4c0e3c28 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 26 Jan 2022 17:15:58 +0100 Subject: [PATCH 016/109] flame: openclip creator --- openpype/hosts/flame/api/render_utils.py | 255 ++++++++++------------- 1 file changed, 112 insertions(+), 143 deletions(-) diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index e6283b725a..dac69c5405 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -132,7 +132,7 @@ def get_preset_path_by_xml_name(xml_preset_name): def get_open_clip( - openclip_file_path, feed_data, recursive=False): + name, openclip_file_path, feed_data): # establish media script path and test it media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" @@ -140,27 +140,23 @@ def get_open_clip( raise IOError("Media Scirpt does not exist: `{}`".format( media_script_path)) + # openclip will be updated via temp.clip file + tmp_name = "_tmp.clip" + # new feed variables: feed_path = feed_data["path"] - feed_basename = os.path.basename(feed_path) feed_version_name = feed_data["version"] + feed_colorspace = feed_data.get("colorspace") + + # derivate other feed variables + feed_basename = os.path.basename(feed_path) + feed_dir = os.path.dirname(feed_path) clip_uploaded = False create_new_clip = False - ext_whitelist = [ - "cin", "als", "jpg", "jpeg", "pict", "pct", "picio", - "sgi", "pic", "tga", "iff", "tdi", "tif", "tiff", "rla", - "cin.pxz", "tif.pxz", "tiff.pxz", "dpx", "dpx.pxz", - "hdr", "png", "exr", "exr.pxz", "psd" - ] - feed_ext = os.path.splitext(feed_basename)[1][1:].lower() - if feed_ext not in ext_whitelist: - print("File extension `{}` is not supported".format(feed_ext)) - return False - if not os.path.isfile(openclip_file_path): # openclip does not exist yet and will be created feed_path = os.path.abspath(feed_path) @@ -168,11 +164,6 @@ def get_open_clip( create_new_clip = True clip_uploaded = True else: - # openclip will be updated via temp.clip file - tmp_name = "tmp.clip" - feed_path = os.path.abspath(feed_path) - feed_dir = os.path.dirname(feed_path) - # output a temp file tmp_file = os.path.join(feed_dir, tmp_name) if os.path.isfile(tmp_file): @@ -180,22 +171,21 @@ def get_open_clip( print("Temp File: {}".format(tmp_file)) - # Write output of getMediaScript to file - cmd_args = [media_script_path, feed_path] - if recursive: - print("recursive enabled on dl_get_media_info") - cmd_args = [media_script_path, "-r", feed_path] + # Create cmd arguments for gettig xml file info file + cmd_args = [ + media_script_path, + "-e", feed_ext, + "-o", tmp_file, + feed_dir + ] # execute creation of clip xml template data try: - output = openpype.lib.run_subprocess(cmd_args) + openpype.lib.run_subprocess(cmd_args) except TypeError: print("Error createing tmp_file") six.reraise(*sys.exc_info()) - with open(tmp_file, "w") as f: - f.write("{}".format(output)) - # Check media type for valid extension try: tmp_xml = ET.parse(tmp_file) @@ -212,17 +202,49 @@ def get_open_clip( new_path = new_path_obj.text print("tmp_xml new_path: {}".format(new_path)) - new_path_ext = os.path.splitext(new_path)[1][1:].strip().lower() - if new_path_ext in ext_whitelist: - print("Found media `{}`".format(new_path_ext)) - else: - print("Extension {} is not supported".format( - new_path_ext)) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False + if create_new_clip: + # New openClip + print("Building new openClip") - if not create_new_clip: + new_xml = ET.parse(tmp_file) + + for new_feed in new_xml.iter('feeds'): + feed = new_feed.find('feed') + feed.set('vuid', feed_basename) + + # add colorspace if any is set + if feed_colorspace: + _add_colorspace(feed, feed_colorspace) + + feedHandler = feed.find("./handler") + feed.remove(feedHandler) + + for newVersion in new_xml.iter('versions'): + newVersion.set('currentVersion', feed_basename) + version = newVersion.find('version') + version.set('uid', feed_basename) + version.set('type', 'version') + + xmlRoot = new_xml.getroot() + + # Clean tmp_file - brute force remove errant + print("Removing Handler") + for handler in xmlRoot.findall("./handler"): + print("Handler found") + xmlRoot.remove(handler) + + resultXML = ET.tostring(xmlRoot).decode('utf-8') + + print("Adding feed version: {}".format(feed_basename)) + + with open(tmp_file, "w") as f: + f.write(resultXML) + + print("openClip Updated: %s" % tmp_file) + + clip_uploaded = True + + else: print("Updating openClip ..") source_xml = ET.parse(openclip_file_path) @@ -231,31 +253,25 @@ def get_open_clip( print(">> source_xml: {}".format(source_xml)) print(">> new_xml: {}".format(new_xml)) - feed_exists = False feed_added = 0 - src_editRateNumerator = None - src_editRateDenominator = None - src_nbTicks = None - src_rate = None - src_dropMode = None + feed_src_nb_ticks = None + feed_src_fps = None + feed_src_drop_mode = None try: - for srcTrack in source_xml.iter('track'): - src_editRateNumeratorObj = srcTrack.find('editRate/numerator') - src_editRateNumerator = src_editRateNumeratorObj.text - src_editRateDenominatorObj = srcTrack.find( - 'editRate/denominator') - src_editRateDenominator = src_editRateDenominatorObj.text - - for srcFeed in srcTrack.iter('feed'): - src_nbTicksObj = srcFeed.find('startTimecode/nbTicks') - src_nbTicks = src_nbTicksObj.text - src_rateObj = srcFeed.find('startTimecode/rate') - src_rate = src_rateObj.text - src_dropModeObj = srcFeed.find('startTimecode/dropMode') - src_dropMode = src_dropModeObj.text + for src_track in source_xml.iter('track'): + for srcFeed in src_track.iter('feed'): + feed_src_nb_ticksObj = srcFeed.find( + 'startTimecode/nbTicks') + feed_src_nb_ticks = feed_src_nb_ticksObj.text + feed_src_fpsObj = srcFeed.find( + 'startTimecode/rate') + feed_src_fps = feed_src_fpsObj.text + feed_src_drop_modeObj = srcFeed.find( + 'startTimecode/dropMode') + feed_src_drop_mode = feed_src_drop_modeObj.text break else: continue @@ -263,59 +279,52 @@ def get_open_clip( except Exception as msg: print(msg) - print("Source editRate/numerator: %s" % src_editRateNumerator) - print("Source editRate/denominator: %s" % src_editRateDenominator) - print("Source startTimecode/nbTicks: %s" % src_nbTicks) - print("Source startTimecode/rate: %s" % src_rate) - print("Source startTimecode/dropMode: %s" % src_dropMode) + print("Source startTimecode/nbTicks: %s" % feed_src_nb_ticks) + print("Source startTimecode/rate: %s" % feed_src_fps) + print("Source startTimecode/dropMode: %s" % feed_src_drop_mode) # Get new feed from file for newTrack in new_xml.iter('track'): uid = newTrack.get('uid') - newFeed = newTrack.find('feeds/feed') + new_feed = newTrack.find('feeds/feed') - feedHandler = newFeed.find("./handler") - newFeed.remove(feedHandler) + feedHandler = new_feed.find("./handler") + new_feed.remove(feedHandler) - if src_editRateNumerator: - new_editRateNumeratorObject = newTrack.find( - "feeds/feed/sampleRate/numerator") - new_editRateNumeratorObject.text = src_editRateNumerator - if src_editRateDenominator: - new_editRateDenominatorObject = newTrack.find( - "feeds/feed/sampleRate/denominator") - new_editRateDenominatorObject.text = src_editRateDenominator - if src_rate: + if feed_src_fps: new_rateObject = newTrack.find( "feeds/feed/startTimecode/rate") - new_rateObject.text = src_rate - if src_nbTicks: + new_rateObject.text = feed_src_fps + if feed_src_nb_ticks: new_nbTicksObject = newTrack.find( "feeds/feed/startTimecode/nbTicks") - new_nbTicksObject.text = src_nbTicks - if src_dropMode: + new_nbTicksObject.text = feed_src_nb_ticks + if feed_src_drop_mode: new_dropModeObj = newTrack.find( "feeds/feed/startTimecode/dropMode") - new_dropModeObj.text = src_dropMode + new_dropModeObj.text = feed_src_drop_mode - new_path_obj = newTrack.find("feeds/feed/spans/span/path") + new_path_obj = newTrack.find( + "feeds/feed/spans/span/path") new_path = new_path_obj.text - print(">> uid: {}".format(uid)) - print(">> new_path: {}".format(new_path)) - - # Check for path in sourceFile - # If Path exists ... skip append - for srcPath in source_xml.iter('path'): - if new_path == srcPath.text: - print("Element exists in clip... skipping append") + # loop all available feed paths and check if + # the path is not already in file + for src_path in source_xml.iter('path'): + if new_path == src_path.text: + print("Not appending file as it already is in .clip file") feed_exists = True if not feed_exists: - # Append new feed to source track - for srcTrack in source_xml.iter('track'): - newFeed.set('vuid', feed_version_name) - srcTrack.find('feeds').append(newFeed) + # Append new temp file feed to .clip source xml tree + for src_track in source_xml.iter('track'): + new_feed.set('vuid', feed_version_name) + + # add colorspace if any is set + if feed_colorspace: + _add_colorspace(new_feed, feed_colorspace) + + src_track.find('feeds').append(new_feed) print( "Appending new feed: {}".format(feed_version_name)) feed_added += 1 @@ -353,57 +362,6 @@ def get_open_clip( if os.path.isfile(tmp_file): os.remove(tmp_file) - else: - # New openClip - print("Building new openClip") - - # Update uid name with element_name - try: - new_xml = ET.parse(tmp_file) - except: - print("Failed reading XML") - print('%s' % traceback.print_exc()) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False - - try: - for newFeed in new_xml.iter('feeds'): - feed = newFeed.find('feed') - feed.set('vuid', feed_basename) - - feedHandler = feed.find("./handler") - feed.remove(feedHandler) - - for newVersion in new_xml.iter('versions'): - newVersion.set('currentVersion', feed_basename) - version = newVersion.find('version') - version.set('uid', feed_basename) - version.set('type', 'version') - - xmlRoot = new_xml.getroot() - - # Clean tmp_file - brute force remove errant - print("Removing Handler") - for handler in xmlRoot.findall("./handler"): - print("Handler found") - xmlRoot.remove(handler) - - resultXML = ET.tostring(xmlRoot).decode('utf-8') - - print("Adding feed version: %s" % feed_basename) - - with open(tmp_file, "w") as f: - f.write(resultXML) - - print("openClip Updated: %s" % tmp_file) - - clip_uploaded = True - - except: - print("Failed to update openClip: %s" % tmp_file) - print('%s' % traceback.print_exc()) - return clip_uploaded @@ -428,3 +386,14 @@ def create_openclip_backup_file(file): if not created: bck_file = "{}.bak.last".format(file) shutil.copy2(file, bck_file) + + +def _add_colorspace(feed_obj, profile_name): + feed_storage_obj = feed_obj.find("storageFormat") + feed_clr_obj = feed_storage_obj.find("colourSpace") + if not feed_clr_obj: + feed_clr_obj = ET.Element( + "colourSpace", {"type": "string"}) + feed_storage_obj.append(feed_clr_obj) + + feed_clr_obj.text = profile_name From 88ba3f59b27e1477b7164676fcff85553ce85294 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Jan 2022 17:33:26 +0100 Subject: [PATCH 017/109] Cosmetics + cleanup unused import --- openpype/hosts/maya/plugins/load/load_look.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_look.py b/openpype/hosts/maya/plugins/load/load_look.py index 8345253968..3398e844ea 100644 --- a/openpype/hosts/maya/plugins/load/load_look.py +++ b/openpype/hosts/maya/plugins/load/load_look.py @@ -1,15 +1,13 @@ # -*- coding: utf-8 -*- """Look loader.""" -import openpype.hosts.maya.api.plugin from avalon import api, io import json +import openpype.hosts.maya.api.plugin import openpype.hosts.maya.api.lib from collections import defaultdict from openpype.widgets.message_window import ScrollMessageBox from Qt import QtWidgets -from openpype.hosts.maya.api.plugin import get_reference_node - class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): """Specific loader for lookdev""" From a17e4628911aef24442057f729e16af136f17f36 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jan 2022 00:39:20 +0100 Subject: [PATCH 018/109] Get OpenPype executable directly from Event Plug-in Config --- vendor/deadline/custom/plugins/GlobalJobPreLoad.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py index ba1e5f6c6a..9fdcc1e4ad 100644 --- a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py +++ b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py @@ -8,6 +8,12 @@ import platform from Deadline.Scripting import RepositoryUtils, FileUtils +def get_openpype_executable(): + """Return OpenPype Executable from Event Plug-in Settings""" + config = RepositoryUtils.GetEventPluginConfig("OpenPype") + return config.GetConfigEntryWithDefault("OpenPypeExecutable", "") + + def inject_openpype_environment(deadlinePlugin): """ Pull env vars from OpenPype and push them to rendering process. @@ -19,7 +25,7 @@ def inject_openpype_environment(deadlinePlugin): print(">>> Injecting OpenPype environments ...") try: print(">>> Getting OpenPype executable ...") - exe_list = job.GetJobExtraInfoKeyValue("openpype_executables") + exe_list = get_openpype_executable() openpype_app = FileUtils.SearchFileList(exe_list) if openpype_app == "": raise RuntimeError( From cc4f5eb45aa123667103c706f4524965516b904c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jan 2022 00:39:48 +0100 Subject: [PATCH 019/109] Remove Job invalidate cache --- vendor/deadline/custom/plugins/GlobalJobPreLoad.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py index 9fdcc1e4ad..6f33454146 100644 --- a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py +++ b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py @@ -20,7 +20,6 @@ def inject_openpype_environment(deadlinePlugin): Used for correct paths, configuration from OpenPype etc. """ job = deadlinePlugin.GetJob() - job = RepositoryUtils.GetJob(job.JobId, True) # invalidates cache print(">>> Injecting OpenPype environments ...") try: @@ -102,7 +101,6 @@ def inject_render_job_id(deadlinePlugin): """Inject dependency ids to publish process as env var for validation.""" print(">>> Injecting render job id ...") job = deadlinePlugin.GetJob() - job = RepositoryUtils.GetJob(job.JobId, True) # invalidates cache dependency_ids = job.JobDependencyIDs print(">>> Dependency IDs: {}".format(dependency_ids)) @@ -189,7 +187,6 @@ def __main__(deadlinePlugin): print("*** GlobalJobPreload start ...") print(">>> Getting job ...") job = deadlinePlugin.GetJob() - job = RepositoryUtils.GetJob(job.JobId, True) # invalidates cache openpype_render_job = \ job.GetJobEnvironmentKeyValue('OPENPYPE_RENDER_JOB') or '0' From 5c92038792c7ded1fd5ff91dc58a52ba9355afec Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jan 2022 00:40:56 +0100 Subject: [PATCH 020/109] Remove saving OpenPype executable path into Jobs from Deadline Event plugin --- .../custom/events/OpenPype/OpenPype.py | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/vendor/deadline/custom/events/OpenPype/OpenPype.py b/vendor/deadline/custom/events/OpenPype/OpenPype.py index e5e2cf52a8..5a179b2dcc 100644 --- a/vendor/deadline/custom/events/OpenPype/OpenPype.py +++ b/vendor/deadline/custom/events/OpenPype/OpenPype.py @@ -85,57 +85,33 @@ class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): del self.OnThermalShutdownCallback del self.OnMachineRestartCallback - def set_openpype_executable_path(self, job): - """ - Sets configurable OpenPypeExecutable value to job extra infos. - - GlobalJobPreLoad takes this value, pulls env vars for each task - from specific worker itself. GlobalJobPreLoad is not easily - configured, so we are configuring Event itself. - """ - openpype_execs = self.GetConfigEntryWithDefault("OpenPypeExecutable", - "") - job.SetJobExtraInfoKeyValue("openpype_executables", openpype_execs) - - Deadline.Scripting.RepositoryUtils.SaveJob(job) - def updateFtrackStatus(self, job, statusName, createIfMissing=False): """Updates version status on ftrack""" pass def OnJobSubmitted(self, job): - # self.LogInfo("OnJobSubmitted LOGGING") # for 1st time submit - self.set_openpype_executable_path(job) self.updateFtrackStatus(job, "Render Queued") def OnJobStarted(self, job): # self.LogInfo("OnJobStarted") - self.set_openpype_executable_path(job) self.updateFtrackStatus(job, "Rendering") def OnJobFinished(self, job): - # self.LogInfo("OnJobFinished") self.updateFtrackStatus(job, "Artist Review") def OnJobRequeued(self, job): - # self.LogInfo("OnJobRequeued LOGGING") - self.set_openpype_executable_path(job) def OnJobFailed(self, job): pass def OnJobSuspended(self, job): - # self.LogInfo("OnJobSuspended LOGGING") self.updateFtrackStatus(job, "Render Queued") def OnJobResumed(self, job): - # self.LogInfo("OnJobResumed LOGGING") - self.set_openpype_executable_path(job) self.updateFtrackStatus(job, "Rendering") def OnJobPended(self, job): - # self.LogInfo("OnJobPended LOGGING") pass def OnJobReleased(self, job): @@ -145,7 +121,6 @@ class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): pass def OnJobError(self, job, task, report): - # self.LogInfo("OnJobError LOGGING") pass def OnJobPurged(self, job): @@ -158,7 +133,6 @@ class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): pass def OnSlaveStarted(self, job): - # self.LogInfo("OnSlaveStarted LOGGING") pass def OnSlaveStopped(self, job): @@ -168,12 +142,10 @@ class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): pass def OnSlaveRendering(self, host_name, job): - # self.LogInfo("OnSlaveRendering LOGGING") pass def OnSlaveStartingJob(self, host_name, job): - # self.LogInfo("OnSlaveStartingJob LOGGING") - self.set_openpype_executable_path(job) + pass def OnSlaveStalled(self, job): pass From 6507ebb17be083592a132637d622fcfb2d0ccbe0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jan 2022 00:41:47 +0100 Subject: [PATCH 021/109] Don't register the Event callbacks since they weren't doing anything anyway --- .../custom/events/OpenPype/OpenPype.py | 110 +++++++++--------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/vendor/deadline/custom/events/OpenPype/OpenPype.py b/vendor/deadline/custom/events/OpenPype/OpenPype.py index 5a179b2dcc..8a234e831d 100644 --- a/vendor/deadline/custom/events/OpenPype/OpenPype.py +++ b/vendor/deadline/custom/events/OpenPype/OpenPype.py @@ -28,62 +28,64 @@ class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): """ def __init__(self): - self.OnJobSubmittedCallback += self.OnJobSubmitted - self.OnJobStartedCallback += self.OnJobStarted - self.OnJobFinishedCallback += self.OnJobFinished - self.OnJobRequeuedCallback += self.OnJobRequeued - self.OnJobFailedCallback += self.OnJobFailed - self.OnJobSuspendedCallback += self.OnJobSuspended - self.OnJobResumedCallback += self.OnJobResumed - self.OnJobPendedCallback += self.OnJobPended - self.OnJobReleasedCallback += self.OnJobReleased - self.OnJobDeletedCallback += self.OnJobDeleted - self.OnJobErrorCallback += self.OnJobError - self.OnJobPurgedCallback += self.OnJobPurged - - self.OnHouseCleaningCallback += self.OnHouseCleaning - self.OnRepositoryRepairCallback += self.OnRepositoryRepair - - self.OnSlaveStartedCallback += self.OnSlaveStarted - self.OnSlaveStoppedCallback += self.OnSlaveStopped - self.OnSlaveIdleCallback += self.OnSlaveIdle - self.OnSlaveRenderingCallback += self.OnSlaveRendering - self.OnSlaveStartingJobCallback += self.OnSlaveStartingJob - self.OnSlaveStalledCallback += self.OnSlaveStalled - - self.OnIdleShutdownCallback += self.OnIdleShutdown - self.OnMachineStartupCallback += self.OnMachineStartup - self.OnThermalShutdownCallback += self.OnThermalShutdown - self.OnMachineRestartCallback += self.OnMachineRestart + pass + # self.OnJobSubmittedCallback += self.OnJobSubmitted + # self.OnJobStartedCallback += self.OnJobStarted + # self.OnJobFinishedCallback += self.OnJobFinished + # self.OnJobRequeuedCallback += self.OnJobRequeued + # self.OnJobFailedCallback += self.OnJobFailed + # self.OnJobSuspendedCallback += self.OnJobSuspended + # self.OnJobResumedCallback += self.OnJobResumed + # self.OnJobPendedCallback += self.OnJobPended + # self.OnJobReleasedCallback += self.OnJobReleased + # self.OnJobDeletedCallback += self.OnJobDeleted + # self.OnJobErrorCallback += self.OnJobError + # self.OnJobPurgedCallback += self.OnJobPurged + # + # self.OnHouseCleaningCallback += self.OnHouseCleaning + # self.OnRepositoryRepairCallback += self.OnRepositoryRepair + # + # self.OnSlaveStartedCallback += self.OnSlaveStarted + # self.OnSlaveStoppedCallback += self.OnSlaveStopped + # self.OnSlaveIdleCallback += self.OnSlaveIdle + # self.OnSlaveRenderingCallback += self.OnSlaveRendering + # self.OnSlaveStartingJobCallback += self.OnSlaveStartingJob + # self.OnSlaveStalledCallback += self.OnSlaveStalled + # + # self.OnIdleShutdownCallback += self.OnIdleShutdown + # self.OnMachineStartupCallback += self.OnMachineStartup + # self.OnThermalShutdownCallback += self.OnThermalShutdown + # self.OnMachineRestartCallback += self.OnMachineRestart def Cleanup(self): - del self.OnJobSubmittedCallback - del self.OnJobStartedCallback - del self.OnJobFinishedCallback - del self.OnJobRequeuedCallback - del self.OnJobFailedCallback - del self.OnJobSuspendedCallback - del self.OnJobResumedCallback - del self.OnJobPendedCallback - del self.OnJobReleasedCallback - del self.OnJobDeletedCallback - del self.OnJobErrorCallback - del self.OnJobPurgedCallback - - del self.OnHouseCleaningCallback - del self.OnRepositoryRepairCallback - - del self.OnSlaveStartedCallback - del self.OnSlaveStoppedCallback - del self.OnSlaveIdleCallback - del self.OnSlaveRenderingCallback - del self.OnSlaveStartingJobCallback - del self.OnSlaveStalledCallback - - del self.OnIdleShutdownCallback - del self.OnMachineStartupCallback - del self.OnThermalShutdownCallback - del self.OnMachineRestartCallback + pass + # del self.OnJobSubmittedCallback + # del self.OnJobStartedCallback + # del self.OnJobFinishedCallback + # del self.OnJobRequeuedCallback + # del self.OnJobFailedCallback + # del self.OnJobSuspendedCallback + # del self.OnJobResumedCallback + # del self.OnJobPendedCallback + # del self.OnJobReleasedCallback + # del self.OnJobDeletedCallback + # del self.OnJobErrorCallback + # del self.OnJobPurgedCallback + # + # del self.OnHouseCleaningCallback + # del self.OnRepositoryRepairCallback + # + # del self.OnSlaveStartedCallback + # del self.OnSlaveStoppedCallback + # del self.OnSlaveIdleCallback + # del self.OnSlaveRenderingCallback + # del self.OnSlaveStartingJobCallback + # del self.OnSlaveStalledCallback + # + # del self.OnIdleShutdownCallback + # del self.OnMachineStartupCallback + # del self.OnThermalShutdownCallback + # del self.OnMachineRestartCallback def updateFtrackStatus(self, job, statusName, createIfMissing=False): """Updates version status on ftrack""" From 1b771160c00b2d3b9fe1bac1b173a58366264fdc Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 28 Jan 2022 16:58:16 +0100 Subject: [PATCH 022/109] flame: convert open clip to class --- openpype/hosts/flame/api/render_utils.py | 413 +++++++++++------------ 1 file changed, 195 insertions(+), 218 deletions(-) diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index dac69c5405..3b7e2cf8b2 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -131,269 +131,246 @@ def get_preset_path_by_xml_name(xml_preset_name): return False -def get_open_clip( - name, openclip_file_path, feed_data): - - # establish media script path and test it +class OpenClip: media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" - if not os.path.isfile(media_script_path): - raise IOError("Media Scirpt does not exist: `{}`".format( - media_script_path)) - - # openclip will be updated via temp.clip file tmp_name = "_tmp.clip" - - # new feed variables: - feed_path = feed_data["path"] - feed_version_name = feed_data["version"] - feed_colorspace = feed_data.get("colorspace") - - # derivate other feed variables - feed_basename = os.path.basename(feed_path) - feed_dir = os.path.dirname(feed_path) - - clip_uploaded = False + tmp_file = None create_new_clip = False - feed_ext = os.path.splitext(feed_basename)[1][1:].lower() + out_feed_nb_ticks = None + out_feed_fps = None + out_feed_drop_mode = None - if not os.path.isfile(openclip_file_path): - # openclip does not exist yet and will be created - feed_path = os.path.abspath(feed_path) - tmp_file = openclip_file_path - create_new_clip = True - clip_uploaded = True - else: - # output a temp file - tmp_file = os.path.join(feed_dir, tmp_name) - if os.path.isfile(tmp_file): - os.remove(tmp_file) + def __init__(self, name, openclip_file_path, feed_data): + # test if media script paht exists + self._validate_media_script_path() - print("Temp File: {}".format(tmp_file)) - # Create cmd arguments for gettig xml file info file - cmd_args = [ - media_script_path, - "-e", feed_ext, - "-o", tmp_file, - feed_dir - ] + # new feed variables: + feed_path = feed_data["path"] + self.feed_version_name = feed_data["version"] + self.feed_colorspace = feed_data.get("colorspace") - # execute creation of clip xml template data - try: - openpype.lib.run_subprocess(cmd_args) - except TypeError: - print("Error createing tmp_file") - six.reraise(*sys.exc_info()) + # derivate other feed variables + self.feed_basename = os.path.basename(feed_path) + self.feed_dir = os.path.dirname(feed_path) + self.feed_ext = os.path.splitext(self.feed_basename)[1][1:].lower() - # Check media type for valid extension - try: - tmp_xml = ET.parse(tmp_file) - print(tmp_xml) - except: - print("XML is probably empty.") - print('{}'.format(traceback.print_exc())) - if os.path.isfile(tmp_file): - os.remove(tmp_file) - return False + if not os.path.isfile(openclip_file_path): + # openclip does not exist yet and will be created + self.tmp_file = self.out_file = openclip_file_path + self.create_new_clip = True - for newTrack in tmp_xml.iter('track'): - new_path_obj = newTrack.find("feeds/feed/spans/span/path") - new_path = new_path_obj.text - print("tmp_xml new_path: {}".format(new_path)) + else: + # output a temp file + self.out_file = openclip_file_path + self.tmp_file = os.path.join(self.feed_dir, self.tmp_name) + self._clear_tmp_file() - if create_new_clip: - # New openClip + print("Temp File: {}".format(self.tmp_file)) + + def _validate_media_script_path(self): + if not os.path.isfile(self.media_script_path): + raise IOError("Media Scirpt does not exist: `{}`".format( + self.media_script_path)) + + def _get_media_info_args(self): + # Create cmd arguments for gettig xml file info file + cmd_args = [ + self.media_script_path, + "-e", self.feed_ext, + "-o", self.tmp_file, + self.feed_dir + ] + + # execute creation of clip xml template data + try: + openpype.lib.run_subprocess(cmd_args) + except TypeError: + print("Error createing self.tmp_file") + six.reraise(*sys.exc_info()) + + def _clear_tmp_file(self): + if os.path.isfile(self.tmp_file): + os.remove(self.tmp_file) + + def _clear_handler(self, xml_object): + for handler in xml_object.findall("./handler"): + print("Handler found") + xml_object.remove(handler) + + def _create_new_open_clip(self): print("Building new openClip") - new_xml = ET.parse(tmp_file) + tmp_xml = ET.parse(self.tmp_file) - for new_feed in new_xml.iter('feeds'): - feed = new_feed.find('feed') - feed.set('vuid', feed_basename) + for tmp_xml_feed in tmp_xml.iter('feeds'): + feed = tmp_xml_feed.find('feed') + feed.set('vuid', self.feed_basename) # add colorspace if any is set - if feed_colorspace: - _add_colorspace(feed, feed_colorspace) + if self.feed_colorspace: + self._add_colorspace(feed, self.feed_colorspace) - feedHandler = feed.find("./handler") - feed.remove(feedHandler) + self._clear_handler(feed) - for newVersion in new_xml.iter('versions'): - newVersion.set('currentVersion', feed_basename) - version = newVersion.find('version') - version.set('uid', feed_basename) + tmp_xml_versions_obj = tmp_xml.find('versions') + tmp_xml_versions_obj.set('currentVersion', self.feed_version_name) + for xml_new_version in tmp_xml_versions_obj: + version = xml_new_version.find('version') + version.set('uid', self.feed_version_name) version.set('type', 'version') - xmlRoot = new_xml.getroot() + xml_data = self._fix_xml_data(tmp_xml) + print("Adding feed version: {}".format(self.feed_basename)) - # Clean tmp_file - brute force remove errant - print("Removing Handler") - for handler in xmlRoot.findall("./handler"): - print("Handler found") - xmlRoot.remove(handler) + self._write_result_xml_to_file(xml_data) - resultXML = ET.tostring(xmlRoot).decode('utf-8') + print("openClip Updated: %s" % self.tmp_file) - print("Adding feed version: {}".format(feed_basename)) - - with open(tmp_file, "w") as f: - f.write(resultXML) - - print("openClip Updated: %s" % tmp_file) - - clip_uploaded = True - - else: + def _update_open_clip(self): print("Updating openClip ..") - source_xml = ET.parse(openclip_file_path) - new_xml = ET.parse(tmp_file) + out_xml = ET.parse(self.out_file) + tmp_xml = ET.parse(self.tmp_file) - print(">> source_xml: {}".format(source_xml)) - print(">> new_xml: {}".format(new_xml)) + print(">> out_xml: {}".format(out_xml)) + print(">> tmp_xml: {}".format(tmp_xml)) - feed_exists = False - feed_added = 0 + # Get new feed from tmp file + tmp_xml_feed = tmp_xml.find('tracks/track/feeds/feed') - feed_src_nb_ticks = None - feed_src_fps = None - feed_src_drop_mode = None + self._clear_handler(tmp_xml_feed) + self._get_time_info_from_origin(out_xml) + if self.out_feed_fps: + tmp_feed_fps_obj = tmp_xml_feed.find( + "startTimecode/rate") + tmp_feed_fps_obj.text = self.out_feed_fps + if self.out_feed_nb_ticks: + tmp_feed_nb_ticks_obj = tmp_xml_feed.find( + "startTimecode/nbTicks") + tmp_feed_nb_ticks_obj.text = self.out_feed_nb_ticks + if self.out_feed_drop_mode: + tmp_feed_drop_mode_obj = tmp_xml_feed.find( + "startTimecode/dropMode") + tmp_feed_drop_mode_obj.text = self.out_feed_drop_mode + + new_path_obj = tmp_xml_feed.find( + "spans/span/path") + new_path = new_path_obj.text + + feed_added = False + if not self._feed_exists(out_xml, new_path): + tmp_xml_feed.set('vuid', self.feed_version_name) + # Append new temp file feed to .clip source out xml + out_track = out_xml.find("tracks/track") + # add colorspace if any is set + if self.feed_colorspace: + self._add_colorspace(tmp_xml_feed, self.feed_colorspace) + + out_track.find('feeds').append(tmp_xml_feed) + print( + "Appending new feed: {}".format( + self.feed_version_name)) + feed_added = True + + if feed_added: + # Append vUID to versions + out_xml_versions_obj = out_xml.find('versions') + out_xml_versions_obj.set( + 'currentVersion', self.feed_version_name) + new_version_obj = ET.Element( + "version", {"type": "version", "uid": self.feed_version_name}) + out_xml_versions_obj.insert(0, new_version_obj) + + xml_data = self._fix_xml_data(out_xml) + + # fist create backup + self._create_openclip_backup_file(self.out_file) + + print("Adding feed version: {}".format(self.feed_version_name)) + + self._write_result_xml_to_file(xml_data) + + print("openClip Updated: {}".format(self.out_file)) + + self._clear_tmp_file() + + def _get_time_info_from_origin(self, xml_data): try: - for src_track in source_xml.iter('track'): - for srcFeed in src_track.iter('feed'): - feed_src_nb_ticksObj = srcFeed.find( + for out_track in xml_data.iter('track'): + for out_feed in out_track.iter('feed'): + out_feed_nb_ticks_obj = out_feed.find( 'startTimecode/nbTicks') - feed_src_nb_ticks = feed_src_nb_ticksObj.text - feed_src_fpsObj = srcFeed.find( + self.out_feed_nb_ticks = out_feed_nb_ticks_obj.text + out_feed_fps_obj = out_feed.find( 'startTimecode/rate') - feed_src_fps = feed_src_fpsObj.text - feed_src_drop_modeObj = srcFeed.find( + self.out_feed_fps = out_feed_fps_obj.text + out_feed_drop_mode_obj = out_feed.find( 'startTimecode/dropMode') - feed_src_drop_mode = feed_src_drop_modeObj.text + self.out_feed_drop_mode = out_feed_drop_mode_obj.text break else: continue - break except Exception as msg: print(msg) - print("Source startTimecode/nbTicks: %s" % feed_src_nb_ticks) - print("Source startTimecode/rate: %s" % feed_src_fps) - print("Source startTimecode/dropMode: %s" % feed_src_drop_mode) + def _feed_exists(self, xml_data, path): + # loop all available feed paths and check if + # the path is not already in file + for src_path in xml_data.iter('path'): + if path == src_path.text: + print("Not appending file as it already is in .clip file") + return True - # Get new feed from file - for newTrack in new_xml.iter('track'): - uid = newTrack.get('uid') - new_feed = newTrack.find('feeds/feed') + def _fix_xml_data(self, xml_data): + xml_root = xml_data.getroot() + self._clear_handler(xml_root) + return ET.tostring(xml_root).decode('utf-8') - feedHandler = new_feed.find("./handler") - new_feed.remove(feedHandler) + def maintain_clip(self): + self._get_media_info_args() - if feed_src_fps: - new_rateObject = newTrack.find( - "feeds/feed/startTimecode/rate") - new_rateObject.text = feed_src_fps - if feed_src_nb_ticks: - new_nbTicksObject = newTrack.find( - "feeds/feed/startTimecode/nbTicks") - new_nbTicksObject.text = feed_src_nb_ticks - if feed_src_drop_mode: - new_dropModeObj = newTrack.find( - "feeds/feed/startTimecode/dropMode") - new_dropModeObj.text = feed_src_drop_mode + if self.create_new_clip: + # New openClip + self._create_new_open_clip() + else: + self._update_open_clip() - new_path_obj = newTrack.find( - "feeds/feed/spans/span/path") - new_path = new_path_obj.text + def _write_result_xml_to_file(self, xml_data): + with open(self.out_file, "w") as f: + f.write(xml_data) - # loop all available feed paths and check if - # the path is not already in file - for src_path in source_xml.iter('path'): - if new_path == src_path.text: - print("Not appending file as it already is in .clip file") - feed_exists = True - - if not feed_exists: - # Append new temp file feed to .clip source xml tree - for src_track in source_xml.iter('track'): - new_feed.set('vuid', feed_version_name) - - # add colorspace if any is set - if feed_colorspace: - _add_colorspace(new_feed, feed_colorspace) - - src_track.find('feeds').append(new_feed) - print( - "Appending new feed: {}".format(feed_version_name)) - feed_added += 1 - - if feed_added > 0: - # Append vUID to versions - newVersion = source_xml.find('versions') - newVersionElement = ET.Element( - "version", {"type": "version", "uid": feed_version_name}) - newVersion.insert(0, newVersionElement) - xmlRoot = source_xml.getroot() - - # Clean tmp_file - brute force remove errant - print("Removing Handler") - for handler in xmlRoot.findall("./handler"): - print("Handler found") - xmlRoot.remove(handler) - - resultXML = ET.tostring(xmlRoot).decode('utf-8') - - # fist create backup - create_openclip_backup_file(openclip_file_path) - - out_file = openclip_file_path - - print("Adding feed version: {}".format(feed_version_name)) - - with open(out_file, "w") as f: - f.write(resultXML) - - print("openClip Updated: {}".format(out_file)) - - clip_uploaded = True - - if os.path.isfile(tmp_file): - os.remove(tmp_file) - - return clip_uploaded - - -def create_openclip_backup_file(file): - bck_file = "{}.bak".format(file) - # if backup does not exist - if not os.path.isfile(bck_file): - shutil.copy2(file, bck_file) - else: - # in case it exists and is already multiplied - created = False - for _i in range(1, 99): - bck_file = "{name}.bak.{idx:0>2}".format( - name=file, - idx=_i) - # create numbered backup file - if not os.path.isfile(bck_file): - shutil.copy2(file, bck_file) - created = True - break - # in case numbered does not exists - if not created: - bck_file = "{}.bak.last".format(file) + def _create_openclip_backup_file(self, file): + bck_file = "{}.bak".format(file) + # if backup does not exist + if not os.path.isfile(bck_file): shutil.copy2(file, bck_file) + else: + # in case it exists and is already multiplied + created = False + for _i in range(1, 99): + bck_file = "{name}.bak.{idx:0>2}".format( + name=file, + idx=_i) + # create numbered backup file + if not os.path.isfile(bck_file): + shutil.copy2(file, bck_file) + created = True + break + # in case numbered does not exists + if not created: + bck_file = "{}.bak.last".format(file) + shutil.copy2(file, bck_file) -def _add_colorspace(feed_obj, profile_name): - feed_storage_obj = feed_obj.find("storageFormat") - feed_clr_obj = feed_storage_obj.find("colourSpace") - if not feed_clr_obj: - feed_clr_obj = ET.Element( - "colourSpace", {"type": "string"}) - feed_storage_obj.append(feed_clr_obj) + def _add_colorspace(self, feed_obj, profile_name): + feed_storage_obj = feed_obj.find("storageFormat") + feed_clr_obj = feed_storage_obj.find("colourSpace") + if not feed_clr_obj: + feed_clr_obj = ET.Element( + "colourSpace", {"type": "string"}) + feed_storage_obj.append(feed_clr_obj) - feed_clr_obj.text = profile_name + feed_clr_obj.text = profile_name From 95a80df3e4e54c75dd7e9a0e868296a061379154 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jan 2022 20:14:39 +0100 Subject: [PATCH 023/109] Remove OpenPype Deadline Event Plug-in OpenPypeExecutable setting is now retrieved from the OpenPype Plug-in instead. --- .../custom/events/OpenPype/OpenPype.param | 37 ---- .../custom/events/OpenPype/OpenPype.py | 165 ------------------ .../custom/plugins/GlobalJobPreLoad.py | 2 +- 3 files changed, 1 insertion(+), 203 deletions(-) delete mode 100644 vendor/deadline/custom/events/OpenPype/OpenPype.param delete mode 100644 vendor/deadline/custom/events/OpenPype/OpenPype.py diff --git a/vendor/deadline/custom/events/OpenPype/OpenPype.param b/vendor/deadline/custom/events/OpenPype/OpenPype.param deleted file mode 100644 index 871ce47467..0000000000 --- a/vendor/deadline/custom/events/OpenPype/OpenPype.param +++ /dev/null @@ -1,37 +0,0 @@ -[State] -Type=Enum -Items=Global Enabled;Opt-In;Disabled -Category=Options -CategoryOrder=0 -CategoryIndex=0 -Label=State -Default=Global Enabled -Description=How this event plug-in should respond to events. If Global, all jobs and slaves will trigger the events for this plugin. If Opt-In, jobs and slaves can choose to trigger the events for this plugin. If Disabled, no events are triggered for this plugin. - -[PythonSearchPaths] -Type=MultiLineMultiFolder -Label=Additional Python Search Paths -Category=Options -CategoryOrder=0 -CategoryIndex=1 -Default= -Description=The list of paths to append to the PYTHONPATH environment variable. This allows the Python job to find custom modules in non-standard locations. - -[LoggingLevel] -Type=Enum -Label=Logging Level -Category=Options -CategoryOrder=0 -CategoryIndex=2 -Items=DEBUG;INFO;WARNING;ERROR -Default=DEBUG -Description=Logging level where printing will start. - -[OpenPypeExecutable] -Type=multilinemultifilename -Label=Path to OpenPype executable -Category=Job Plugins -CategoryOrder=1 -CategoryIndex=1 -Default= -Description= \ No newline at end of file diff --git a/vendor/deadline/custom/events/OpenPype/OpenPype.py b/vendor/deadline/custom/events/OpenPype/OpenPype.py deleted file mode 100644 index 8a234e831d..0000000000 --- a/vendor/deadline/custom/events/OpenPype/OpenPype.py +++ /dev/null @@ -1,165 +0,0 @@ -import Deadline.Events -import Deadline.Scripting - - -def GetDeadlineEventListener(): - return OpenPypeEventListener() - - -def CleanupDeadlineEventListener(eventListener): - eventListener.Cleanup() - - -class OpenPypeEventListener(Deadline.Events.DeadlineEventListener): - """ - Called on every Deadline plugin event, used for injecting OpenPype - environment variables into rendering process. - - Expects that job already contains env vars: - AVALON_PROJECT - AVALON_ASSET - AVALON_TASK - AVALON_APP_NAME - Without these only global environment would be pulled from OpenPype - - Configure 'Path to OpenPype executable dir' in Deadlines - 'Tools > Configure Events > openpype ' - Only directory path is needed. - - """ - def __init__(self): - pass - # self.OnJobSubmittedCallback += self.OnJobSubmitted - # self.OnJobStartedCallback += self.OnJobStarted - # self.OnJobFinishedCallback += self.OnJobFinished - # self.OnJobRequeuedCallback += self.OnJobRequeued - # self.OnJobFailedCallback += self.OnJobFailed - # self.OnJobSuspendedCallback += self.OnJobSuspended - # self.OnJobResumedCallback += self.OnJobResumed - # self.OnJobPendedCallback += self.OnJobPended - # self.OnJobReleasedCallback += self.OnJobReleased - # self.OnJobDeletedCallback += self.OnJobDeleted - # self.OnJobErrorCallback += self.OnJobError - # self.OnJobPurgedCallback += self.OnJobPurged - # - # self.OnHouseCleaningCallback += self.OnHouseCleaning - # self.OnRepositoryRepairCallback += self.OnRepositoryRepair - # - # self.OnSlaveStartedCallback += self.OnSlaveStarted - # self.OnSlaveStoppedCallback += self.OnSlaveStopped - # self.OnSlaveIdleCallback += self.OnSlaveIdle - # self.OnSlaveRenderingCallback += self.OnSlaveRendering - # self.OnSlaveStartingJobCallback += self.OnSlaveStartingJob - # self.OnSlaveStalledCallback += self.OnSlaveStalled - # - # self.OnIdleShutdownCallback += self.OnIdleShutdown - # self.OnMachineStartupCallback += self.OnMachineStartup - # self.OnThermalShutdownCallback += self.OnThermalShutdown - # self.OnMachineRestartCallback += self.OnMachineRestart - - def Cleanup(self): - pass - # del self.OnJobSubmittedCallback - # del self.OnJobStartedCallback - # del self.OnJobFinishedCallback - # del self.OnJobRequeuedCallback - # del self.OnJobFailedCallback - # del self.OnJobSuspendedCallback - # del self.OnJobResumedCallback - # del self.OnJobPendedCallback - # del self.OnJobReleasedCallback - # del self.OnJobDeletedCallback - # del self.OnJobErrorCallback - # del self.OnJobPurgedCallback - # - # del self.OnHouseCleaningCallback - # del self.OnRepositoryRepairCallback - # - # del self.OnSlaveStartedCallback - # del self.OnSlaveStoppedCallback - # del self.OnSlaveIdleCallback - # del self.OnSlaveRenderingCallback - # del self.OnSlaveStartingJobCallback - # del self.OnSlaveStalledCallback - # - # del self.OnIdleShutdownCallback - # del self.OnMachineStartupCallback - # del self.OnThermalShutdownCallback - # del self.OnMachineRestartCallback - - def updateFtrackStatus(self, job, statusName, createIfMissing=False): - """Updates version status on ftrack""" - pass - - def OnJobSubmitted(self, job): - # for 1st time submit - self.updateFtrackStatus(job, "Render Queued") - - def OnJobStarted(self, job): - # self.LogInfo("OnJobStarted") - self.updateFtrackStatus(job, "Rendering") - - def OnJobFinished(self, job): - self.updateFtrackStatus(job, "Artist Review") - - def OnJobRequeued(self, job): - - def OnJobFailed(self, job): - pass - - def OnJobSuspended(self, job): - self.updateFtrackStatus(job, "Render Queued") - - def OnJobResumed(self, job): - self.updateFtrackStatus(job, "Rendering") - - def OnJobPended(self, job): - pass - - def OnJobReleased(self, job): - pass - - def OnJobDeleted(self, job): - pass - - def OnJobError(self, job, task, report): - pass - - def OnJobPurged(self, job): - pass - - def OnHouseCleaning(self): - pass - - def OnRepositoryRepair(self, job, *args): - pass - - def OnSlaveStarted(self, job): - pass - - def OnSlaveStopped(self, job): - pass - - def OnSlaveIdle(self, job): - pass - - def OnSlaveRendering(self, host_name, job): - pass - - def OnSlaveStartingJob(self, host_name, job): - pass - - def OnSlaveStalled(self, job): - pass - - def OnIdleShutdown(self, job): - pass - - def OnMachineStartup(self, job): - pass - - def OnThermalShutdown(self, job): - pass - - def OnMachineRestart(self, job): - pass diff --git a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py index 6f33454146..ee137a2ee3 100644 --- a/vendor/deadline/custom/plugins/GlobalJobPreLoad.py +++ b/vendor/deadline/custom/plugins/GlobalJobPreLoad.py @@ -10,7 +10,7 @@ from Deadline.Scripting import RepositoryUtils, FileUtils def get_openpype_executable(): """Return OpenPype Executable from Event Plug-in Settings""" - config = RepositoryUtils.GetEventPluginConfig("OpenPype") + config = RepositoryUtils.GetPluginConfig("OpenPype") return config.GetConfigEntryWithDefault("OpenPypeExecutable", "") From 142451f74aeb91023debde53f12bce21fbebb74f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Sat, 29 Jan 2022 19:40:18 +0100 Subject: [PATCH 024/109] flame: fixing openclip creator to add version --- openpype/hosts/flame/api/render_utils.py | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index 3b7e2cf8b2..fe406f1c94 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -141,11 +141,10 @@ class OpenClip: out_feed_fps = None out_feed_drop_mode = None - def __init__(self, name, openclip_file_path, feed_data): + def __init__(self, name, openclip_file_path, feed_data): # test if media script paht exists self._validate_media_script_path() - # new feed variables: feed_path = feed_data["path"] self.feed_version_name = feed_data["version"] @@ -204,22 +203,22 @@ class OpenClip: tmp_xml = ET.parse(self.tmp_file) - for tmp_xml_feed in tmp_xml.iter('feeds'): - feed = tmp_xml_feed.find('feed') - feed.set('vuid', self.feed_basename) + tmp_xml_feeds = tmp_xml.find('tracks/track/feeds') + tmp_xml_feeds.set('currentVersion', self.feed_version_name) + for tmp_feed in tmp_xml_feeds: + tmp_feed.set('vuid', self.feed_version_name) # add colorspace if any is set if self.feed_colorspace: - self._add_colorspace(feed, self.feed_colorspace) + self._add_colorspace(tmp_feed, self.feed_colorspace) - self._clear_handler(feed) + self._clear_handler(tmp_feed) tmp_xml_versions_obj = tmp_xml.find('versions') tmp_xml_versions_obj.set('currentVersion', self.feed_version_name) for xml_new_version in tmp_xml_versions_obj: - version = xml_new_version.find('version') - version.set('uid', self.feed_version_name) - version.set('type', 'version') + xml_new_version.set('uid', self.feed_version_name) + xml_new_version.set('type', 'version') xml_data = self._fix_xml_data(tmp_xml) print("Adding feed version: {}".format(self.feed_basename)) @@ -269,7 +268,10 @@ class OpenClip: if self.feed_colorspace: self._add_colorspace(tmp_xml_feed, self.feed_colorspace) - out_track.find('feeds').append(tmp_xml_feed) + out_feeds = out_track.find('feeds') + out_feeds.set('currentVersion', self.feed_version_name) + out_feeds.append(tmp_xml_feed) + print( "Appending new feed: {}".format( self.feed_version_name)) @@ -364,7 +366,6 @@ class OpenClip: bck_file = "{}.bak.last".format(file) shutil.copy2(file, bck_file) - def _add_colorspace(self, feed_obj, profile_name): feed_storage_obj = feed_obj.find("storageFormat") feed_clr_obj = feed_storage_obj.find("colourSpace") From 14b704fcd774547bc249c3b88ab1dd30ee2fda83 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 31 Jan 2022 12:03:58 +0100 Subject: [PATCH 025/109] flame: moving openclip solver to plugins modul - starting with loader class functionality --- openpype/hosts/flame/api/__init__.py | 7 +- openpype/hosts/flame/api/plugin.py | 291 +++++++++++++++++++++++ openpype/hosts/flame/api/render_utils.py | 252 -------------------- 3 files changed, 297 insertions(+), 253 deletions(-) diff --git a/openpype/hosts/flame/api/__init__.py b/openpype/hosts/flame/api/__init__.py index 8e5418c78b..2aeb0d9c16 100644 --- a/openpype/hosts/flame/api/__init__.py +++ b/openpype/hosts/flame/api/__init__.py @@ -52,7 +52,10 @@ from .menu import ( ) from .plugin import ( Creator, - PublishableClip + PublishableClip, + ClipLoader, + OpenClipSolver + ) from .workio import ( open_file, @@ -122,6 +125,8 @@ __all__ = [ # plugin "Creator", "PublishableClip", + "ClipLoader", + "OpenClipSolver", # workio "open_file", diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index f34999bcf3..a83f9a3b28 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -1,7 +1,15 @@ +import os import re +import shutil +import sys +from avalon.vendor import qargparse +from xml.etree import ElementTree as ET +import shutil +import six from Qt import QtWidgets, QtCore import openpype.api as openpype from openpype import style +import avalon.api as avalon from . import ( lib as flib, pipeline as fpipeline, @@ -644,3 +652,286 @@ class PublishableClip: # Publishing plugin functions # Loader plugin functions + +class ClipLoader(avalon.Loader): + """A basic clip loader for Flame + + This will implement the basic behavior for a loader to inherit from that + will containerize the reference and will implement the `remove` and + `update` logic. + + """ + + options = [ + qargparse.Boolean( + "handles", + label="Set handles", + default=0, + help="Also set handles to clip as In/Out marks" + ) + ] + + def load( + self, + context, + name=None, + namespace=None, + options=None + ): + pass + + def update(self, container, representation): + """Update an existing `container` + """ + pass + + def remove(self, container): + """Remove an existing `container` + """ + pass + + +class OpenClipSolver: + media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" + tmp_name = "_tmp.clip" + tmp_file = None + create_new_clip = False + + out_feed_nb_ticks = None + out_feed_fps = None + out_feed_drop_mode = None + + def __init__(self, name, openclip_file_path, feed_data): + # test if media script paht exists + self._validate_media_script_path() + + # new feed variables: + feed_path = feed_data["path"] + self.feed_version_name = feed_data["version"] + self.feed_colorspace = feed_data.get("colorspace") + + # derivate other feed variables + self.feed_basename = os.path.basename(feed_path) + self.feed_dir = os.path.dirname(feed_path) + self.feed_ext = os.path.splitext(self.feed_basename)[1][1:].lower() + + if not os.path.isfile(openclip_file_path): + # openclip does not exist yet and will be created + self.tmp_file = self.out_file = openclip_file_path + self.create_new_clip = True + + else: + # output a temp file + self.out_file = openclip_file_path + self.tmp_file = os.path.join(self.feed_dir, self.tmp_name) + self._clear_tmp_file() + + print("Temp File: {}".format(self.tmp_file)) + + def _validate_media_script_path(self): + if not os.path.isfile(self.media_script_path): + raise IOError("Media Scirpt does not exist: `{}`".format( + self.media_script_path)) + + def _get_media_info_args(self): + # Create cmd arguments for gettig xml file info file + cmd_args = [ + self.media_script_path, + "-e", self.feed_ext, + "-o", self.tmp_file, + self.feed_dir + ] + + # execute creation of clip xml template data + try: + flib.run_subprocess(cmd_args) + except TypeError: + print("Error createing self.tmp_file") + six.reraise(*sys.exc_info()) + + def _clear_tmp_file(self): + if os.path.isfile(self.tmp_file): + os.remove(self.tmp_file) + + def _clear_handler(self, xml_object): + for handler in xml_object.findall("./handler"): + print("Handler found") + xml_object.remove(handler) + + def _create_new_open_clip(self): + print("Building new openClip") + + tmp_xml = ET.parse(self.tmp_file) + + tmp_xml_feeds = tmp_xml.find('tracks/track/feeds') + tmp_xml_feeds.set('currentVersion', self.feed_version_name) + for tmp_feed in tmp_xml_feeds: + tmp_feed.set('vuid', self.feed_version_name) + + # add colorspace if any is set + if self.feed_colorspace: + self._add_colorspace(tmp_feed, self.feed_colorspace) + + self._clear_handler(tmp_feed) + + tmp_xml_versions_obj = tmp_xml.find('versions') + tmp_xml_versions_obj.set('currentVersion', self.feed_version_name) + for xml_new_version in tmp_xml_versions_obj: + xml_new_version.set('uid', self.feed_version_name) + xml_new_version.set('type', 'version') + + xml_data = self._fix_xml_data(tmp_xml) + print("Adding feed version: {}".format(self.feed_basename)) + + self._write_result_xml_to_file(xml_data) + + print("openClip Updated: %s" % self.tmp_file) + + def _update_open_clip(self): + print("Updating openClip ..") + + out_xml = ET.parse(self.out_file) + tmp_xml = ET.parse(self.tmp_file) + + print(">> out_xml: {}".format(out_xml)) + print(">> tmp_xml: {}".format(tmp_xml)) + + # Get new feed from tmp file + tmp_xml_feed = tmp_xml.find('tracks/track/feeds/feed') + + self._clear_handler(tmp_xml_feed) + self._get_time_info_from_origin(out_xml) + + if self.out_feed_fps: + tmp_feed_fps_obj = tmp_xml_feed.find( + "startTimecode/rate") + tmp_feed_fps_obj.text = self.out_feed_fps + if self.out_feed_nb_ticks: + tmp_feed_nb_ticks_obj = tmp_xml_feed.find( + "startTimecode/nbTicks") + tmp_feed_nb_ticks_obj.text = self.out_feed_nb_ticks + if self.out_feed_drop_mode: + tmp_feed_drop_mode_obj = tmp_xml_feed.find( + "startTimecode/dropMode") + tmp_feed_drop_mode_obj.text = self.out_feed_drop_mode + + new_path_obj = tmp_xml_feed.find( + "spans/span/path") + new_path = new_path_obj.text + + feed_added = False + if not self._feed_exists(out_xml, new_path): + tmp_xml_feed.set('vuid', self.feed_version_name) + # Append new temp file feed to .clip source out xml + out_track = out_xml.find("tracks/track") + # add colorspace if any is set + if self.feed_colorspace: + self._add_colorspace(tmp_xml_feed, self.feed_colorspace) + + out_feeds = out_track.find('feeds') + out_feeds.set('currentVersion', self.feed_version_name) + out_feeds.append(tmp_xml_feed) + + print( + "Appending new feed: {}".format( + self.feed_version_name)) + feed_added = True + + if feed_added: + # Append vUID to versions + out_xml_versions_obj = out_xml.find('versions') + out_xml_versions_obj.set( + 'currentVersion', self.feed_version_name) + new_version_obj = ET.Element( + "version", {"type": "version", "uid": self.feed_version_name}) + out_xml_versions_obj.insert(0, new_version_obj) + + xml_data = self._fix_xml_data(out_xml) + + # fist create backup + self._create_openclip_backup_file(self.out_file) + + print("Adding feed version: {}".format(self.feed_version_name)) + + self._write_result_xml_to_file(xml_data) + + print("openClip Updated: {}".format(self.out_file)) + + self._clear_tmp_file() + + def _get_time_info_from_origin(self, xml_data): + try: + for out_track in xml_data.iter('track'): + for out_feed in out_track.iter('feed'): + out_feed_nb_ticks_obj = out_feed.find( + 'startTimecode/nbTicks') + self.out_feed_nb_ticks = out_feed_nb_ticks_obj.text + out_feed_fps_obj = out_feed.find( + 'startTimecode/rate') + self.out_feed_fps = out_feed_fps_obj.text + out_feed_drop_mode_obj = out_feed.find( + 'startTimecode/dropMode') + self.out_feed_drop_mode = out_feed_drop_mode_obj.text + break + else: + continue + except Exception as msg: + print(msg) + + def _feed_exists(self, xml_data, path): + # loop all available feed paths and check if + # the path is not already in file + for src_path in xml_data.iter('path'): + if path == src_path.text: + print("Not appending file as it already is in .clip file") + return True + + def _fix_xml_data(self, xml_data): + xml_root = xml_data.getroot() + self._clear_handler(xml_root) + return ET.tostring(xml_root).decode('utf-8') + + def maintain_clip(self): + self._get_media_info_args() + + if self.create_new_clip: + # New openClip + self._create_new_open_clip() + else: + self._update_open_clip() + + def _write_result_xml_to_file(self, xml_data): + with open(self.out_file, "w") as f: + f.write(xml_data) + + def _create_openclip_backup_file(self, file): + bck_file = "{}.bak".format(file) + # if backup does not exist + if not os.path.isfile(bck_file): + shutil.copy2(file, bck_file) + else: + # in case it exists and is already multiplied + created = False + for _i in range(1, 99): + bck_file = "{name}.bak.{idx:0>2}".format( + name=file, + idx=_i) + # create numbered backup file + if not os.path.isfile(bck_file): + shutil.copy2(file, bck_file) + created = True + break + # in case numbered does not exists + if not created: + bck_file = "{}.bak.last".format(file) + shutil.copy2(file, bck_file) + + def _add_colorspace(self, feed_obj, profile_name): + feed_storage_obj = feed_obj.find("storageFormat") + feed_clr_obj = feed_storage_obj.find("colourSpace") + if not feed_clr_obj: + feed_clr_obj = ET.Element( + "colourSpace", {"type": "string"}) + feed_storage_obj.append(feed_clr_obj) + + feed_clr_obj.text = profile_name diff --git a/openpype/hosts/flame/api/render_utils.py b/openpype/hosts/flame/api/render_utils.py index fe406f1c94..1b086646cc 100644 --- a/openpype/hosts/flame/api/render_utils.py +++ b/openpype/hosts/flame/api/render_utils.py @@ -1,10 +1,4 @@ import os -import sys -import traceback -from xml.etree import ElementTree as ET -import shutil -import openpype.lib -import six def export_clip(export_path, clip, preset_path, **kwargs): @@ -129,249 +123,3 @@ def get_preset_path_by_xml_name(xml_preset_name): # if nothing found then return False return False - - -class OpenClip: - media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" - tmp_name = "_tmp.clip" - tmp_file = None - create_new_clip = False - - out_feed_nb_ticks = None - out_feed_fps = None - out_feed_drop_mode = None - - def __init__(self, name, openclip_file_path, feed_data): - # test if media script paht exists - self._validate_media_script_path() - - # new feed variables: - feed_path = feed_data["path"] - self.feed_version_name = feed_data["version"] - self.feed_colorspace = feed_data.get("colorspace") - - # derivate other feed variables - self.feed_basename = os.path.basename(feed_path) - self.feed_dir = os.path.dirname(feed_path) - self.feed_ext = os.path.splitext(self.feed_basename)[1][1:].lower() - - if not os.path.isfile(openclip_file_path): - # openclip does not exist yet and will be created - self.tmp_file = self.out_file = openclip_file_path - self.create_new_clip = True - - else: - # output a temp file - self.out_file = openclip_file_path - self.tmp_file = os.path.join(self.feed_dir, self.tmp_name) - self._clear_tmp_file() - - print("Temp File: {}".format(self.tmp_file)) - - def _validate_media_script_path(self): - if not os.path.isfile(self.media_script_path): - raise IOError("Media Scirpt does not exist: `{}`".format( - self.media_script_path)) - - def _get_media_info_args(self): - # Create cmd arguments for gettig xml file info file - cmd_args = [ - self.media_script_path, - "-e", self.feed_ext, - "-o", self.tmp_file, - self.feed_dir - ] - - # execute creation of clip xml template data - try: - openpype.lib.run_subprocess(cmd_args) - except TypeError: - print("Error createing self.tmp_file") - six.reraise(*sys.exc_info()) - - def _clear_tmp_file(self): - if os.path.isfile(self.tmp_file): - os.remove(self.tmp_file) - - def _clear_handler(self, xml_object): - for handler in xml_object.findall("./handler"): - print("Handler found") - xml_object.remove(handler) - - def _create_new_open_clip(self): - print("Building new openClip") - - tmp_xml = ET.parse(self.tmp_file) - - tmp_xml_feeds = tmp_xml.find('tracks/track/feeds') - tmp_xml_feeds.set('currentVersion', self.feed_version_name) - for tmp_feed in tmp_xml_feeds: - tmp_feed.set('vuid', self.feed_version_name) - - # add colorspace if any is set - if self.feed_colorspace: - self._add_colorspace(tmp_feed, self.feed_colorspace) - - self._clear_handler(tmp_feed) - - tmp_xml_versions_obj = tmp_xml.find('versions') - tmp_xml_versions_obj.set('currentVersion', self.feed_version_name) - for xml_new_version in tmp_xml_versions_obj: - xml_new_version.set('uid', self.feed_version_name) - xml_new_version.set('type', 'version') - - xml_data = self._fix_xml_data(tmp_xml) - print("Adding feed version: {}".format(self.feed_basename)) - - self._write_result_xml_to_file(xml_data) - - print("openClip Updated: %s" % self.tmp_file) - - def _update_open_clip(self): - print("Updating openClip ..") - - out_xml = ET.parse(self.out_file) - tmp_xml = ET.parse(self.tmp_file) - - print(">> out_xml: {}".format(out_xml)) - print(">> tmp_xml: {}".format(tmp_xml)) - - # Get new feed from tmp file - tmp_xml_feed = tmp_xml.find('tracks/track/feeds/feed') - - self._clear_handler(tmp_xml_feed) - self._get_time_info_from_origin(out_xml) - - if self.out_feed_fps: - tmp_feed_fps_obj = tmp_xml_feed.find( - "startTimecode/rate") - tmp_feed_fps_obj.text = self.out_feed_fps - if self.out_feed_nb_ticks: - tmp_feed_nb_ticks_obj = tmp_xml_feed.find( - "startTimecode/nbTicks") - tmp_feed_nb_ticks_obj.text = self.out_feed_nb_ticks - if self.out_feed_drop_mode: - tmp_feed_drop_mode_obj = tmp_xml_feed.find( - "startTimecode/dropMode") - tmp_feed_drop_mode_obj.text = self.out_feed_drop_mode - - new_path_obj = tmp_xml_feed.find( - "spans/span/path") - new_path = new_path_obj.text - - feed_added = False - if not self._feed_exists(out_xml, new_path): - tmp_xml_feed.set('vuid', self.feed_version_name) - # Append new temp file feed to .clip source out xml - out_track = out_xml.find("tracks/track") - # add colorspace if any is set - if self.feed_colorspace: - self._add_colorspace(tmp_xml_feed, self.feed_colorspace) - - out_feeds = out_track.find('feeds') - out_feeds.set('currentVersion', self.feed_version_name) - out_feeds.append(tmp_xml_feed) - - print( - "Appending new feed: {}".format( - self.feed_version_name)) - feed_added = True - - if feed_added: - # Append vUID to versions - out_xml_versions_obj = out_xml.find('versions') - out_xml_versions_obj.set( - 'currentVersion', self.feed_version_name) - new_version_obj = ET.Element( - "version", {"type": "version", "uid": self.feed_version_name}) - out_xml_versions_obj.insert(0, new_version_obj) - - xml_data = self._fix_xml_data(out_xml) - - # fist create backup - self._create_openclip_backup_file(self.out_file) - - print("Adding feed version: {}".format(self.feed_version_name)) - - self._write_result_xml_to_file(xml_data) - - print("openClip Updated: {}".format(self.out_file)) - - self._clear_tmp_file() - - def _get_time_info_from_origin(self, xml_data): - try: - for out_track in xml_data.iter('track'): - for out_feed in out_track.iter('feed'): - out_feed_nb_ticks_obj = out_feed.find( - 'startTimecode/nbTicks') - self.out_feed_nb_ticks = out_feed_nb_ticks_obj.text - out_feed_fps_obj = out_feed.find( - 'startTimecode/rate') - self.out_feed_fps = out_feed_fps_obj.text - out_feed_drop_mode_obj = out_feed.find( - 'startTimecode/dropMode') - self.out_feed_drop_mode = out_feed_drop_mode_obj.text - break - else: - continue - except Exception as msg: - print(msg) - - def _feed_exists(self, xml_data, path): - # loop all available feed paths and check if - # the path is not already in file - for src_path in xml_data.iter('path'): - if path == src_path.text: - print("Not appending file as it already is in .clip file") - return True - - def _fix_xml_data(self, xml_data): - xml_root = xml_data.getroot() - self._clear_handler(xml_root) - return ET.tostring(xml_root).decode('utf-8') - - def maintain_clip(self): - self._get_media_info_args() - - if self.create_new_clip: - # New openClip - self._create_new_open_clip() - else: - self._update_open_clip() - - def _write_result_xml_to_file(self, xml_data): - with open(self.out_file, "w") as f: - f.write(xml_data) - - def _create_openclip_backup_file(self, file): - bck_file = "{}.bak".format(file) - # if backup does not exist - if not os.path.isfile(bck_file): - shutil.copy2(file, bck_file) - else: - # in case it exists and is already multiplied - created = False - for _i in range(1, 99): - bck_file = "{name}.bak.{idx:0>2}".format( - name=file, - idx=_i) - # create numbered backup file - if not os.path.isfile(bck_file): - shutil.copy2(file, bck_file) - created = True - break - # in case numbered does not exists - if not created: - bck_file = "{}.bak.last".format(file) - shutil.copy2(file, bck_file) - - def _add_colorspace(self, feed_obj, profile_name): - feed_storage_obj = feed_obj.find("storageFormat") - feed_clr_obj = feed_storage_obj.find("colourSpace") - if not feed_clr_obj: - feed_clr_obj = ET.Element( - "colourSpace", {"type": "string"}) - feed_storage_obj.append(feed_clr_obj) - - feed_clr_obj.text = profile_name From 19574980d513b296f30f52dc30fcd1aaf2681c73 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 31 Jan 2022 12:07:02 +0100 Subject: [PATCH 026/109] flame: loader clip wip --- .../hosts/flame/plugins/load/load_clip.py | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 openpype/hosts/flame/plugins/load/load_clip.py diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py new file mode 100644 index 0000000000..6594f0e284 --- /dev/null +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -0,0 +1,185 @@ +from avalon import io, api +import openpype.hosts.flame.api as opfapi + + +class LoadClip(opfapi.ClipLoader): + """Load a subset to timeline as clip + + Place clip to timeline on its asset origin timings collected + during conforming to project + """ + + families = ["render2d", "source", "plate", "render", "review"] + representations = ["exr", "dpx", "jpg", "jpeg", "png", "h264"] + + label = "Load as clip" + order = -10 + icon = "code-fork" + color = "orange" + + clip_name_template = "{asset}_{subset}_{representation}" + + def load(self, context, name, namespace, options): + + # load clip to timeline and get main variables + namespace = namespace + version = context['version'] + version_data = version.get("data", {}) + version_name = version.get("name", None) + colorspace = version_data.get("colorspace", None) + clip_name = self.clip_name_template.format( + **context["representation"]["context"]) + + # todo: settings in imageio + # convert colorspace with ocio to flame mapping + # in imageio flame section + colorspace = colorspace + + # create new workfile version in conform task for _v###.clip + # every new version is also the *_latest.clip + openclip_name = clip_name + + # prepare Reel group in actual desktop + reel_object = "prepared reel object" + + # prepare clip data from context ad send it to openClipLoader + loading_context = { + "path": self.fname.replace("\\", "/"), + "colorspace": colorspace, + "clip_name": openclip_name, + "reel_object": reel_object + + } + + # with maintained openclip as opc + opc = "loaded open pype clip " + # opc set in and out marks if handles + + # opc refresh versions + + # add additional metadata from the version to imprint Avalon knob + add_keys = [ + "frameStart", "frameEnd", "source", "author", + "fps", "handleStart", "handleEnd" + ] + + # move all version data keys to tag data + data_imprint = {} + for key in add_keys: + data_imprint.update({ + key: version_data.get(key, str(None)) + }) + + # add variables related to version context + data_imprint.update({ + "version": version_name, + "colorspace": colorspace, + "objectName": clip_name + }) + + # unwrap segment from clip + open_clip_segment = self._get_segment_from_clip(opc) + + return opfapi.containerise( + open_clip_segment, + name, namespace, context, + self.__class__.__name__, + data_imprint) + + def _get_segment_from_clip(self, clip): + # unwrapping segment from input clip + pass + + def switch(self, container, representation): + self.update(container, representation) + + def update(self, container, representation): + """ Updating previously loaded clips + """ + + # load clip to timeline and get main variables + name = container['name'] + namespace = container['namespace'] + track_item = phiero.get_track_items( + track_item_name=namespace) + version = io.find_one({ + "type": "version", + "_id": representation["parent"] + }) + version_data = version.get("data", {}) + version_name = version.get("name", None) + colorspace = version_data.get("colorspace", None) + object_name = "{}_{}".format(name, namespace) + file = api.get_representation_path(representation).replace("\\", "/") + clip = track_item.source() + + # reconnect media to new path + clip.reconnectMedia(file) + + # set colorspace + if colorspace: + clip.setSourceMediaColourTransform(colorspace) + + # add additional metadata from the version to imprint Avalon knob + add_keys = [ + "frameStart", "frameEnd", "source", "author", + "fps", "handleStart", "handleEnd" + ] + + # move all version data keys to tag data + data_imprint = {} + for key in add_keys: + data_imprint.update({ + key: version_data.get(key, str(None)) + }) + + # add variables related to version context + data_imprint.update({ + "representation": str(representation["_id"]), + "version": version_name, + "colorspace": colorspace, + "objectName": object_name + }) + + # update color of clip regarding the version order + self.set_item_color(track_item, version) + + return phiero.update_container(track_item, data_imprint) + + def remove(self, container): + """ Removing previously loaded clips + """ + # load clip to timeline and get main variables + namespace = container['namespace'] + track_item = phiero.get_track_items( + track_item_name=namespace) + track = track_item.parent() + + # remove track item from track + track.removeItem(track_item) + + @classmethod + def multiselection(cls, track_item): + if not cls.track: + cls.track = track_item.parent() + cls.sequence = cls.track.parent() + + @classmethod + def set_item_color(cls, track_item, version): + + clip = track_item.source() + # define version name + version_name = version.get("name", None) + # get all versions in list + versions = io.find({ + "type": "version", + "parent": version["parent"] + }).distinct('name') + + max_version = max(versions) + + # set clip colour + if version_name == max_version: + clip.binItem().setColor(cls.clip_color_last) + else: + clip.binItem().setColor(cls.clip_color) From 49499c82b41c24fd4b7379560e3bb682f82da9a8 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 31 Jan 2022 14:06:13 +0100 Subject: [PATCH 027/109] flame: load openclip to desktop wip --- openpype/hosts/flame/api/pipeline.py | 27 ++- openpype/hosts/flame/api/plugin.py | 20 +- .../hosts/flame/plugins/load/load_clip.py | 228 +++++++++++------- 3 files changed, 169 insertions(+), 106 deletions(-) diff --git a/openpype/hosts/flame/api/pipeline.py b/openpype/hosts/flame/api/pipeline.py index 30c70b491b..476a65e59b 100644 --- a/openpype/hosts/flame/api/pipeline.py +++ b/openpype/hosts/flame/api/pipeline.py @@ -4,7 +4,9 @@ Basic avalon integration import os import contextlib from avalon import api as avalon +from avalon.pipeline import AVALON_CONTAINER_ID from pyblish import api as pyblish +from collections import OrderedDict from openpype.api import Logger from .lib import ( set_segment_data_marker, @@ -68,14 +70,33 @@ def uninstall(): log.info("OpenPype Flame host uninstalled ...") -def containerise(tl_segment, +def containerise(flame_clip, name, namespace, context, loader=None, data=None): - # TODO: containerise - pass + + data_imprint = OrderedDict({ + "schema": "openpype:container-2.0", + "id": AVALON_CONTAINER_ID, + "name": str(name), + "namespace": str(namespace), + "loader": str(loader), + "representation": str(context["representation"]["_id"]), + }) + + if data: + for k, v in data.items(): + data_imprint.update({k: v}) + + log.debug("_ data_imprint: {}".format(data_imprint)) + + segment = flame_clip.versions[-1].tracks[-1].segments[-1] + + set_segment_data_marker(segment, data_imprint) + + return flame_clip def ls(): diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index a83f9a3b28..503971fef7 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -701,7 +701,7 @@ class OpenClipSolver: out_feed_fps = None out_feed_drop_mode = None - def __init__(self, name, openclip_file_path, feed_data): + def __init__(self, openclip_file_path, feed_data): # test if media script paht exists self._validate_media_script_path() @@ -728,6 +728,15 @@ class OpenClipSolver: print("Temp File: {}".format(self.tmp_file)) + def make(self): + self._get_media_info_args() + + if self.create_new_clip: + # New openClip + self._create_new_open_clip() + else: + self._update_open_clip() + def _validate_media_script_path(self): if not os.path.isfile(self.media_script_path): raise IOError("Media Scirpt does not exist: `{}`".format( @@ -891,15 +900,6 @@ class OpenClipSolver: self._clear_handler(xml_root) return ET.tostring(xml_root).decode('utf-8') - def maintain_clip(self): - self._get_media_info_args() - - if self.create_new_clip: - # New openClip - self._create_new_open_clip() - else: - self._update_open_clip() - def _write_result_xml_to_file(self, xml_data): with open(self.out_file, "w") as f: f.write(xml_data) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index 6594f0e284..dd34bc8adb 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -1,3 +1,5 @@ +import os +import flame from avalon import io, api import openpype.hosts.flame.api as opfapi @@ -17,10 +19,18 @@ class LoadClip(opfapi.ClipLoader): icon = "code-fork" color = "orange" + # settings + reel_group_name = "OpenPype_Reels" + reel_name = "Loaded" clip_name_template = "{asset}_{subset}_{representation}" + def load(self, context, name, namespace, options): + # get flame objects + fproject = flame.project.current_project + self.fpd = fproject.current_workspace.desktop + # load clip to timeline and get main variables namespace = namespace version = context['version'] @@ -35,27 +45,28 @@ class LoadClip(opfapi.ClipLoader): # in imageio flame section colorspace = colorspace - # create new workfile version in conform task for _v###.clip - # every new version is also the *_latest.clip - openclip_name = clip_name - - # prepare Reel group in actual desktop - reel_object = "prepared reel object" + # create workfile path + workfile_dir = os.environ["AVALON_WORKDIR"] + openclip_path = os.path.join( + workfile_dir, clip_name, clip_name + ".clip" + ) # prepare clip data from context ad send it to openClipLoader loading_context = { "path": self.fname.replace("\\", "/"), "colorspace": colorspace, - "clip_name": openclip_name, - "reel_object": reel_object + "version": version_name } - # with maintained openclip as opc - opc = "loaded open pype clip " - # opc set in and out marks if handles + # make openpype clip file + opfapi.OpenClipSolver(openclip_path, loading_context).make() - # opc refresh versions + # prepare Reel group in actual desktop + opc = self._get_clip( + clip_name, + openclip_path + ) # add additional metadata from the version to imprint Avalon knob add_keys = [ @@ -77,109 +88,140 @@ class LoadClip(opfapi.ClipLoader): "objectName": clip_name }) - # unwrap segment from clip - open_clip_segment = self._get_segment_from_clip(opc) - return opfapi.containerise( - open_clip_segment, + opc, name, namespace, context, self.__class__.__name__, data_imprint) + def _get_clip(self, name, clip_path): + reel = self._get_reel() + # with maintained openclip as opc + matching_clip = [cl for cl in reel.clips + if cl.name.get_value() == name] + if matching_clip: + return matching_clip.pop() + else: + return flame.import_clips(clip_path, reel) + + def _get_reel(self): + + matching_rgroup = [ + rg for rg in self.fpd.reel_groups + if rg.name.get_value() == self.reel_group_name + ] + + if not matching_rgroup: + reel_group = self.fpd.create_reel_group(self.reel_group_name) + else: + reel_group = matching_rgroup.pop() + + matching_reel = [ + re for re in reel_group.reels + if re.name.get_value() == self.reel_name + ] + + if not matching_reel: + reel_group = reel_group.create_reel(self.reel_name) + else: + reel_group = matching_reel.pop() + + return reel_group + def _get_segment_from_clip(self, clip): # unwrapping segment from input clip pass - def switch(self, container, representation): - self.update(container, representation) + # def switch(self, container, representation): + # self.update(container, representation) - def update(self, container, representation): - """ Updating previously loaded clips - """ + # def update(self, container, representation): + # """ Updating previously loaded clips + # """ - # load clip to timeline and get main variables - name = container['name'] - namespace = container['namespace'] - track_item = phiero.get_track_items( - track_item_name=namespace) - version = io.find_one({ - "type": "version", - "_id": representation["parent"] - }) - version_data = version.get("data", {}) - version_name = version.get("name", None) - colorspace = version_data.get("colorspace", None) - object_name = "{}_{}".format(name, namespace) - file = api.get_representation_path(representation).replace("\\", "/") - clip = track_item.source() + # # load clip to timeline and get main variables + # name = container['name'] + # namespace = container['namespace'] + # track_item = phiero.get_track_items( + # track_item_name=namespace) + # version = io.find_one({ + # "type": "version", + # "_id": representation["parent"] + # }) + # version_data = version.get("data", {}) + # version_name = version.get("name", None) + # colorspace = version_data.get("colorspace", None) + # object_name = "{}_{}".format(name, namespace) + # file = api.get_representation_path(representation).replace("\\", "/") + # clip = track_item.source() - # reconnect media to new path - clip.reconnectMedia(file) + # # reconnect media to new path + # clip.reconnectMedia(file) - # set colorspace - if colorspace: - clip.setSourceMediaColourTransform(colorspace) + # # set colorspace + # if colorspace: + # clip.setSourceMediaColourTransform(colorspace) - # add additional metadata from the version to imprint Avalon knob - add_keys = [ - "frameStart", "frameEnd", "source", "author", - "fps", "handleStart", "handleEnd" - ] + # # add additional metadata from the version to imprint Avalon knob + # add_keys = [ + # "frameStart", "frameEnd", "source", "author", + # "fps", "handleStart", "handleEnd" + # ] - # move all version data keys to tag data - data_imprint = {} - for key in add_keys: - data_imprint.update({ - key: version_data.get(key, str(None)) - }) + # # move all version data keys to tag data + # data_imprint = {} + # for key in add_keys: + # data_imprint.update({ + # key: version_data.get(key, str(None)) + # }) - # add variables related to version context - data_imprint.update({ - "representation": str(representation["_id"]), - "version": version_name, - "colorspace": colorspace, - "objectName": object_name - }) + # # add variables related to version context + # data_imprint.update({ + # "representation": str(representation["_id"]), + # "version": version_name, + # "colorspace": colorspace, + # "objectName": object_name + # }) - # update color of clip regarding the version order - self.set_item_color(track_item, version) + # # update color of clip regarding the version order + # self.set_item_color(track_item, version) - return phiero.update_container(track_item, data_imprint) + # return phiero.update_container(track_item, data_imprint) - def remove(self, container): - """ Removing previously loaded clips - """ - # load clip to timeline and get main variables - namespace = container['namespace'] - track_item = phiero.get_track_items( - track_item_name=namespace) - track = track_item.parent() + # def remove(self, container): + # """ Removing previously loaded clips + # """ + # # load clip to timeline and get main variables + # namespace = container['namespace'] + # track_item = phiero.get_track_items( + # track_item_name=namespace) + # track = track_item.parent() - # remove track item from track - track.removeItem(track_item) + # # remove track item from track + # track.removeItem(track_item) - @classmethod - def multiselection(cls, track_item): - if not cls.track: - cls.track = track_item.parent() - cls.sequence = cls.track.parent() + # @classmethod + # def multiselection(cls, track_item): + # if not cls.track: + # cls.track = track_item.parent() + # cls.sequence = cls.track.parent() - @classmethod - def set_item_color(cls, track_item, version): + # @classmethod + # def set_item_color(cls, track_item, version): - clip = track_item.source() - # define version name - version_name = version.get("name", None) - # get all versions in list - versions = io.find({ - "type": "version", - "parent": version["parent"] - }).distinct('name') + # clip = track_item.source() + # # define version name + # version_name = version.get("name", None) + # # get all versions in list + # versions = io.find({ + # "type": "version", + # "parent": version["parent"] + # }).distinct('name') - max_version = max(versions) + # max_version = max(versions) - # set clip colour - if version_name == max_version: - clip.binItem().setColor(cls.clip_color_last) - else: - clip.binItem().setColor(cls.clip_color) + # # set clip colour + # if version_name == max_version: + # clip.binItem().setColor(cls.clip_color_last) + # else: + # clip.binItem().setColor(cls.clip_color) From a7c1815760687291e6cce3666665cb64b5ce40e9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 31 Jan 2022 14:22:40 +0100 Subject: [PATCH 028/109] flame: adding settings for loader --- .../defaults/project_settings/flame.json | 25 +++++++++ .../projects_schema/schema_project_flame.json | 55 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json index 3caf190e37..b601f9bcba 100644 --- a/openpype/settings/defaults/project_settings/flame.json +++ b/openpype/settings/defaults/project_settings/flame.json @@ -32,5 +32,30 @@ } } } + }, + "load": { + "LoadClip": { + "enabled": true, + "families": [ + "render2d", + "source", + "plate", + "render", + "review" + ], + "representations": [ + "exr", + "dpx", + "jpg", + "jpeg", + "png", + "h264", + "mov", + "mp4" + ], + "reel_group_name": "OpenPype_Reels", + "reel_name": "Loaded", + "clip_name_template": "{asset}_{subset}_{representation}" + } } } \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json index 4cb1a0bb2b..9ef05fa832 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json @@ -194,6 +194,61 @@ ] } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "load", + "label": "Loader plugins", + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "LoadClip", + "label": "Load Clip", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "list", + "key": "families", + "label": "Families", + "object_type": "text" + }, + { + "type": "list", + "key": "representations", + "label": "Representations", + "object_type": "text" + }, + { + "type": "separator" + }, + { + "type": "text", + "key": "reel_group_name", + "label": "Reel group name" + }, + { + "type": "text", + "key": "reel_name", + "label": "Reel name" + }, + { + "type": "separator" + }, + { + "type": "text", + "key": "clip_name_template", + "label": "Clip name template" + } + ] + } + ] } ] } From 1a624b99a7172ea9f0be4c760d62e00171dc4339 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 31 Jan 2022 21:00:39 +0100 Subject: [PATCH 029/109] flame: finalization clip loader --- openpype/hosts/flame/api/plugin.py | 39 +++++++++++-------- .../hosts/flame/plugins/load/load_clip.py | 31 +++++++++++---- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index 503971fef7..c28ab0f556 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -701,6 +701,8 @@ class OpenClipSolver: out_feed_fps = None out_feed_drop_mode = None + log = log + def __init__(self, openclip_file_path, feed_data): # test if media script paht exists self._validate_media_script_path() @@ -710,6 +712,9 @@ class OpenClipSolver: self.feed_version_name = feed_data["version"] self.feed_colorspace = feed_data.get("colorspace") + if feed_data.get("logger"): + self.log = feed_data["logger"] + # derivate other feed variables self.feed_basename = os.path.basename(feed_path) self.feed_dir = os.path.dirname(feed_path) @@ -726,7 +731,7 @@ class OpenClipSolver: self.tmp_file = os.path.join(self.feed_dir, self.tmp_name) self._clear_tmp_file() - print("Temp File: {}".format(self.tmp_file)) + self.log.info("Temp File: {}".format(self.tmp_file)) def make(self): self._get_media_info_args() @@ -753,9 +758,9 @@ class OpenClipSolver: # execute creation of clip xml template data try: - flib.run_subprocess(cmd_args) + openpype.run_subprocess(cmd_args) except TypeError: - print("Error createing self.tmp_file") + self.log.error("Error createing self.tmp_file") six.reraise(*sys.exc_info()) def _clear_tmp_file(self): @@ -764,11 +769,11 @@ class OpenClipSolver: def _clear_handler(self, xml_object): for handler in xml_object.findall("./handler"): - print("Handler found") + self.log.debug("Handler found") xml_object.remove(handler) def _create_new_open_clip(self): - print("Building new openClip") + self.log.info("Building new openClip") tmp_xml = ET.parse(self.tmp_file) @@ -790,20 +795,20 @@ class OpenClipSolver: xml_new_version.set('type', 'version') xml_data = self._fix_xml_data(tmp_xml) - print("Adding feed version: {}".format(self.feed_basename)) + self.log.info("Adding feed version: {}".format(self.feed_basename)) self._write_result_xml_to_file(xml_data) - print("openClip Updated: %s" % self.tmp_file) + self.log.info("openClip Updated: {}".format(self.tmp_file)) def _update_open_clip(self): - print("Updating openClip ..") + self.log.info("Updating openClip ..") out_xml = ET.parse(self.out_file) tmp_xml = ET.parse(self.tmp_file) - print(">> out_xml: {}".format(out_xml)) - print(">> tmp_xml: {}".format(tmp_xml)) + self.log.debug(">> out_xml: {}".format(out_xml)) + self.log.debug(">> tmp_xml: {}".format(tmp_xml)) # Get new feed from tmp file tmp_xml_feed = tmp_xml.find('tracks/track/feeds/feed') @@ -841,7 +846,7 @@ class OpenClipSolver: out_feeds.set('currentVersion', self.feed_version_name) out_feeds.append(tmp_xml_feed) - print( + self.log.info( "Appending new feed: {}".format( self.feed_version_name)) feed_added = True @@ -860,11 +865,12 @@ class OpenClipSolver: # fist create backup self._create_openclip_backup_file(self.out_file) - print("Adding feed version: {}".format(self.feed_version_name)) + self.log.info("Adding feed version: {}".format( + self.feed_version_name)) self._write_result_xml_to_file(xml_data) - print("openClip Updated: {}".format(self.out_file)) + self.log.info("openClip Updated: {}".format(self.out_file)) self._clear_tmp_file() @@ -885,14 +891,15 @@ class OpenClipSolver: else: continue except Exception as msg: - print(msg) + self.log.warning(msg) def _feed_exists(self, xml_data, path): # loop all available feed paths and check if # the path is not already in file for src_path in xml_data.iter('path'): if path == src_path.text: - print("Not appending file as it already is in .clip file") + self.log.warning( + "Not appending file as it already is in .clip file") return True def _fix_xml_data(self, xml_data): @@ -929,7 +936,7 @@ class OpenClipSolver: def _add_colorspace(self, feed_obj, profile_name): feed_storage_obj = feed_obj.find("storageFormat") feed_clr_obj = feed_storage_obj.find("colourSpace") - if not feed_clr_obj: + if feed_clr_obj is not None: feed_clr_obj = ET.Element( "colourSpace", {"type": "string"}) feed_storage_obj.append(feed_clr_obj) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index dd34bc8adb..112571bf09 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -1,6 +1,6 @@ import os import flame -from avalon import io, api +from pprint import pformat import openpype.hosts.flame.api as opfapi @@ -24,7 +24,6 @@ class LoadClip(opfapi.ClipLoader): reel_name = "Loaded" clip_name_template = "{asset}_{subset}_{representation}" - def load(self, context, name, namespace, options): # get flame objects @@ -47,17 +46,27 @@ class LoadClip(opfapi.ClipLoader): # create workfile path workfile_dir = os.environ["AVALON_WORKDIR"] - openclip_path = os.path.join( - workfile_dir, clip_name, clip_name + ".clip" + openclip_dir = os.path.join( + workfile_dir, clip_name ) + openclip_path = os.path.join( + openclip_dir, clip_name + ".clip" + ) + if not os.path.exists(openclip_dir): + os.makedirs(openclip_dir) # prepare clip data from context ad send it to openClipLoader loading_context = { "path": self.fname.replace("\\", "/"), "colorspace": colorspace, - "version": version_name + "version": "v{:0>3}".format(version_name), + "logger": self.log } + self.log.debug(pformat( + loading_context + )) + self.log.debug(openclip_path) # make openpype clip file opfapi.OpenClipSolver(openclip_path, loading_context).make() @@ -102,7 +111,8 @@ class LoadClip(opfapi.ClipLoader): if matching_clip: return matching_clip.pop() else: - return flame.import_clips(clip_path, reel) + created_clips = flame.import_clips(str(clip_path), reel) + return created_clips.pop() def _get_reel(self): @@ -112,7 +122,12 @@ class LoadClip(opfapi.ClipLoader): ] if not matching_rgroup: - reel_group = self.fpd.create_reel_group(self.reel_group_name) + reel_group = self.fpd.create_reel_group(str(self.reel_group_name)) + for _r in reel_group.reels: + if "reel" not in _r.name.get_value().lower(): + continue + self.log.debug("Removing: {}".format(_r.name)) + flame.delete(_r) else: reel_group = matching_rgroup.pop() @@ -122,7 +137,7 @@ class LoadClip(opfapi.ClipLoader): ] if not matching_reel: - reel_group = reel_group.create_reel(self.reel_name) + reel_group = reel_group.create_reel(str(self.reel_name)) else: reel_group = matching_reel.pop() From 4fb92b6fcab6401b110ab3cdb1be8ab6440e0856 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 2 Feb 2022 10:25:33 +0100 Subject: [PATCH 030/109] Default to "Main" subset name across all hosts - 'testhost' is not refactored to default to "Main" --- openpype/hosts/aftereffects/plugins/create/create_render.py | 1 + openpype/hosts/blender/api/plugin.py | 2 ++ openpype/hosts/fusion/plugins/create/create_exr_saver.py | 1 + openpype/hosts/harmony/api/plugin.py | 2 +- openpype/hosts/houdini/api/plugin.py | 2 ++ openpype/hosts/maya/api/plugin.py | 1 + openpype/hosts/maya/plugins/create/create_animation.py | 1 - openpype/hosts/maya/plugins/create/create_ass.py | 1 - openpype/hosts/maya/plugins/create/create_assembly.py | 1 - openpype/hosts/maya/plugins/create/create_camera.py | 2 -- openpype/hosts/maya/plugins/create/create_layout.py | 1 - openpype/hosts/maya/plugins/create/create_look.py | 1 - openpype/hosts/maya/plugins/create/create_mayaascii.py | 1 - openpype/hosts/maya/plugins/create/create_pointcache.py | 1 - openpype/hosts/maya/plugins/create/create_render.py | 1 - openpype/hosts/maya/plugins/create/create_review.py | 1 - openpype/hosts/maya/plugins/create/create_rig.py | 1 - openpype/hosts/maya/plugins/create/create_xgen.py | 1 - openpype/hosts/maya/plugins/create/create_yeti_cache.py | 1 - openpype/hosts/maya/plugins/create/create_yeti_rig.py | 1 - openpype/hosts/unreal/api/plugin.py | 2 +- 21 files changed, 9 insertions(+), 17 deletions(-) diff --git a/openpype/hosts/aftereffects/plugins/create/create_render.py b/openpype/hosts/aftereffects/plugins/create/create_render.py index 5fe72d4f53..8dfc85cdc8 100644 --- a/openpype/hosts/aftereffects/plugins/create/create_render.py +++ b/openpype/hosts/aftereffects/plugins/create/create_render.py @@ -19,6 +19,7 @@ class CreateRender(openpype.api.Creator): name = "renderDefault" label = "Render on Farm" family = "render" + defaults = ["Main"] def process(self): stub = get_stub() # only after After Effects is up diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 1f0b142ef6..8c9ab9a27f 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -131,6 +131,8 @@ def deselect_all(): class Creator(PypeCreatorMixin, avalon.api.Creator): """Base class for Creator plug-ins.""" + defaults = ['Main'] + def process(self): collection = bpy.data.collections.new(name=self.data["subset"]) bpy.context.scene.collection.children.link(collection) diff --git a/openpype/hosts/fusion/plugins/create/create_exr_saver.py b/openpype/hosts/fusion/plugins/create/create_exr_saver.py index 077e77c059..2990ce23b8 100644 --- a/openpype/hosts/fusion/plugins/create/create_exr_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_exr_saver.py @@ -10,6 +10,7 @@ class CreateOpenEXRSaver(openpype.api.Creator): label = "Create OpenEXR Saver" hosts = ["fusion"] family = "render" + defaults = ["Main"] def process(self): diff --git a/openpype/hosts/harmony/api/plugin.py b/openpype/hosts/harmony/api/plugin.py index 7ac7fe510c..a50fbccc35 100644 --- a/openpype/hosts/harmony/api/plugin.py +++ b/openpype/hosts/harmony/api/plugin.py @@ -3,4 +3,4 @@ from openpype.api import PypeCreatorMixin class Creator(PypeCreatorMixin, harmony.Creator): - pass + defaults = ["Main"] diff --git a/openpype/hosts/houdini/api/plugin.py b/openpype/hosts/houdini/api/plugin.py index 63d9bba470..e9e6d6c6d7 100644 --- a/openpype/hosts/houdini/api/plugin.py +++ b/openpype/hosts/houdini/api/plugin.py @@ -14,6 +14,8 @@ class OpenPypeCreatorError(CreatorError): class Creator(PypeCreatorMixin, houdini.Creator): + defaults = ['Main'] + def process(self): try: # re-raise as standard Python exception so diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index a5f03cd576..4c4d4afc2d 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -76,6 +76,7 @@ def get_reference_node_parents(ref): class Creator(PypeCreatorMixin, avalon.maya.Creator): + defaults = ['Main'] pass diff --git a/openpype/hosts/maya/plugins/create/create_animation.py b/openpype/hosts/maya/plugins/create/create_animation.py index 7ce96166f7..11a668cfc8 100644 --- a/openpype/hosts/maya/plugins/create/create_animation.py +++ b/openpype/hosts/maya/plugins/create/create_animation.py @@ -11,7 +11,6 @@ class CreateAnimation(plugin.Creator): label = "Animation" family = "animation" icon = "male" - defaults = ['Main'] def __init__(self, *args, **kwargs): super(CreateAnimation, self).__init__(*args, **kwargs) diff --git a/openpype/hosts/maya/plugins/create/create_ass.py b/openpype/hosts/maya/plugins/create/create_ass.py index 7f1cb55821..39f226900a 100644 --- a/openpype/hosts/maya/plugins/create/create_ass.py +++ b/openpype/hosts/maya/plugins/create/create_ass.py @@ -15,7 +15,6 @@ class CreateAss(plugin.Creator): label = "Ass StandIn" family = "ass" icon = "cube" - defaults = ['Main'] def __init__(self, *args, **kwargs): super(CreateAss, self).__init__(*args, **kwargs) diff --git a/openpype/hosts/maya/plugins/create/create_assembly.py b/openpype/hosts/maya/plugins/create/create_assembly.py index fa9d692792..ff5e1d45c4 100644 --- a/openpype/hosts/maya/plugins/create/create_assembly.py +++ b/openpype/hosts/maya/plugins/create/create_assembly.py @@ -8,4 +8,3 @@ class CreateAssembly(plugin.Creator): label = "Assembly" family = "assembly" icon = "cubes" - defaults = ['Main'] diff --git a/openpype/hosts/maya/plugins/create/create_camera.py b/openpype/hosts/maya/plugins/create/create_camera.py index 09f41914e4..8b2c881036 100644 --- a/openpype/hosts/maya/plugins/create/create_camera.py +++ b/openpype/hosts/maya/plugins/create/create_camera.py @@ -11,7 +11,6 @@ class CreateCamera(plugin.Creator): label = "Camera" family = "camera" icon = "video-camera" - defaults = ['Main'] def __init__(self, *args, **kwargs): super(CreateCamera, self).__init__(*args, **kwargs) @@ -33,4 +32,3 @@ class CreateCameraRig(plugin.Creator): label = "Camera Rig" family = "camerarig" icon = "video-camera" - defaults = ['Main'] diff --git a/openpype/hosts/maya/plugins/create/create_layout.py b/openpype/hosts/maya/plugins/create/create_layout.py index 8d825d23ba..6dc87430aa 100644 --- a/openpype/hosts/maya/plugins/create/create_layout.py +++ b/openpype/hosts/maya/plugins/create/create_layout.py @@ -8,4 +8,3 @@ class CreateLayout(plugin.Creator): label = "Layout" family = "layout" icon = "cubes" - defaults = ["Main"] diff --git a/openpype/hosts/maya/plugins/create/create_look.py b/openpype/hosts/maya/plugins/create/create_look.py index 36a3120a9a..56e2640919 100644 --- a/openpype/hosts/maya/plugins/create/create_look.py +++ b/openpype/hosts/maya/plugins/create/create_look.py @@ -11,7 +11,6 @@ class CreateLook(plugin.Creator): label = "Look" family = "look" icon = "paint-brush" - defaults = ['Main'] make_tx = True def __init__(self, *args, **kwargs): diff --git a/openpype/hosts/maya/plugins/create/create_mayaascii.py b/openpype/hosts/maya/plugins/create/create_mayaascii.py index 8bbdf107c6..f54f2df812 100644 --- a/openpype/hosts/maya/plugins/create/create_mayaascii.py +++ b/openpype/hosts/maya/plugins/create/create_mayaascii.py @@ -8,4 +8,3 @@ class CreateMayaScene(plugin.Creator): label = "Maya Scene" family = "mayaScene" icon = "file-archive-o" - defaults = ['Main'] diff --git a/openpype/hosts/maya/plugins/create/create_pointcache.py b/openpype/hosts/maya/plugins/create/create_pointcache.py index d8e5fd43a7..ede152f1ef 100644 --- a/openpype/hosts/maya/plugins/create/create_pointcache.py +++ b/openpype/hosts/maya/plugins/create/create_pointcache.py @@ -11,7 +11,6 @@ class CreatePointCache(plugin.Creator): label = "Point Cache" family = "pointcache" icon = "gears" - defaults = ['Main'] def __init__(self, *args, **kwargs): super(CreatePointCache, self).__init__(*args, **kwargs) diff --git a/openpype/hosts/maya/plugins/create/create_render.py b/openpype/hosts/maya/plugins/create/create_render.py index fa5e73f3ed..b01d5a1184 100644 --- a/openpype/hosts/maya/plugins/create/create_render.py +++ b/openpype/hosts/maya/plugins/create/create_render.py @@ -64,7 +64,6 @@ class CreateRender(plugin.Creator): label = "Render" family = "rendering" icon = "eye" - defaults = ["Main"] _token = None _user = None diff --git a/openpype/hosts/maya/plugins/create/create_review.py b/openpype/hosts/maya/plugins/create/create_review.py index ae636ec691..14a21d28ca 100644 --- a/openpype/hosts/maya/plugins/create/create_review.py +++ b/openpype/hosts/maya/plugins/create/create_review.py @@ -12,7 +12,6 @@ class CreateReview(plugin.Creator): label = "Review" family = "review" icon = "video-camera" - defaults = ['Main'] keepImages = False isolate = False imagePlane = True diff --git a/openpype/hosts/maya/plugins/create/create_rig.py b/openpype/hosts/maya/plugins/create/create_rig.py index ae1670961f..8032e5fbbd 100644 --- a/openpype/hosts/maya/plugins/create/create_rig.py +++ b/openpype/hosts/maya/plugins/create/create_rig.py @@ -13,7 +13,6 @@ class CreateRig(plugin.Creator): label = "Rig" family = "rig" icon = "wheelchair" - defaults = ['Main'] def process(self): diff --git a/openpype/hosts/maya/plugins/create/create_xgen.py b/openpype/hosts/maya/plugins/create/create_xgen.py index 3953972952..8672c06a1e 100644 --- a/openpype/hosts/maya/plugins/create/create_xgen.py +++ b/openpype/hosts/maya/plugins/create/create_xgen.py @@ -8,4 +8,3 @@ class CreateXgen(plugin.Creator): label = "Xgen Interactive" family = "xgen" icon = "pagelines" - defaults = ['Main'] diff --git a/openpype/hosts/maya/plugins/create/create_yeti_cache.py b/openpype/hosts/maya/plugins/create/create_yeti_cache.py index a37d8082db..86e13b95b2 100644 --- a/openpype/hosts/maya/plugins/create/create_yeti_cache.py +++ b/openpype/hosts/maya/plugins/create/create_yeti_cache.py @@ -13,7 +13,6 @@ class CreateYetiCache(plugin.Creator): label = "Yeti Cache" family = "yeticache" icon = "pagelines" - defaults = ["Main"] def __init__(self, *args, **kwargs): super(CreateYetiCache, self).__init__(*args, **kwargs) diff --git a/openpype/hosts/maya/plugins/create/create_yeti_rig.py b/openpype/hosts/maya/plugins/create/create_yeti_rig.py index 2326958963..7abe2988cd 100644 --- a/openpype/hosts/maya/plugins/create/create_yeti_rig.py +++ b/openpype/hosts/maya/plugins/create/create_yeti_rig.py @@ -12,7 +12,6 @@ class CreateYetiRig(plugin.Creator): label = "Yeti Rig" family = "yetiRig" icon = "usb" - defaults = ["Main"] def process(self): diff --git a/openpype/hosts/unreal/api/plugin.py b/openpype/hosts/unreal/api/plugin.py index a69b12d6f5..5a6b236730 100644 --- a/openpype/hosts/unreal/api/plugin.py +++ b/openpype/hosts/unreal/api/plugin.py @@ -4,7 +4,7 @@ import openpype.api class Creator(openpype.api.Creator): """This serves as skeleton for future OpenPype specific functionality""" - pass + defaults = ['Main'] class Loader(api.Loader): From 2f3ff799b1b0944f4b054929d7a97d8c59591f53 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 2 Feb 2022 13:23:27 +0100 Subject: [PATCH 031/109] OP-2551 - cleaned up wrong settings Added multiprocess setting for AE2022 --- .../project_settings/aftereffects.json | 7 ---- .../defaults/project_settings/deadline.json | 3 +- .../schema_project_aftereffects.json | 33 ------------------- .../schema_project_deadline.json | 5 +++ 4 files changed, 7 insertions(+), 41 deletions(-) diff --git a/openpype/settings/defaults/project_settings/aftereffects.json b/openpype/settings/defaults/project_settings/aftereffects.json index 698b3b35a9..6a9a399069 100644 --- a/openpype/settings/defaults/project_settings/aftereffects.json +++ b/openpype/settings/defaults/project_settings/aftereffects.json @@ -10,13 +10,6 @@ "skip_timelines_check": [ ".*" ] - }, - "AfterEffectsSubmitDeadline": { - "use_published": true, - "priority": 50, - "primary_pool": "", - "secondary_pool": "", - "chunk_size": 1000000 } }, "workfile_builder": { diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index 9fb964b494..1a3d273021 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -87,7 +87,8 @@ "primary_pool": "", "secondary_pool": "", "group": "", - "department": "" + "department": "", + "multiprocess": true } } } \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_aftereffects.json b/openpype/settings/entities/schemas/projects_schema/schema_project_aftereffects.json index 8024de6d45..4c4cd225ab 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_aftereffects.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_aftereffects.json @@ -50,39 +50,6 @@ "label": "Skip Timeline Check for Tasks" } ] - }, - { - "type": "dict", - "collapsible": true, - "key": "AfterEffectsSubmitDeadline", - "label": "AfterEffects Submit to Deadline", - "children": [ - { - "type": "boolean", - "key": "use_published", - "label": "Use Published scene" - }, - { - "type": "number", - "key": "priority", - "label": "Priority" - }, - { - "type": "text", - "key": "primary_pool", - "label": "Primary Pool" - }, - { - "type": "text", - "key": "secondary_pool", - "label": "Secondary Pool" - }, - { - "type": "number", - "key": "chunk_size", - "label": "Frames Per Task" - } - ] } ] }, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index eb9eeb5448..f8b3e521c1 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -449,6 +449,11 @@ "type": "text", "key": "department", "label": "Department" + }, + { + "type": "boolean", + "key": "multiprocess", + "label": "Multiprocess" } ] } From 1760ae892f90766a87b24f15ec6b78727e98e906 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 2 Feb 2022 13:25:24 +0100 Subject: [PATCH 032/109] OP-2551 - added properties from Settings --- .../publish/submit_aftereffects_deadline.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py index 69159fda1a..d5346ad9b3 100644 --- a/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -29,7 +29,13 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline families = ["render.farm"] # cannot be "render' as that is integrated use_published = True + priority = 50 chunk_size = 1000000 + primary_pool = None + secondary_pool = None + group = None + department = None + multiprocess = True def get_job_info(self): dln_job_info = DeadlineJobInfo(Plugin="AfterEffects") @@ -49,6 +55,11 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline int(round(self._instance.data["frameEnd"]))) dln_job_info.Frames = frame_range + dln_job_info.Priority = self.priority + dln_job_info.Pool = self.primary_pool + dln_job_info.SecondaryPool = self.secondary_pool + dln_job_info.Group = self.group + dln_job_info.Department = self.department dln_job_info.ChunkSize = self.chunk_size dln_job_info.OutputFilename = \ os.path.basename(self._instance.data["expectedFiles"][0]) @@ -102,9 +113,10 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline '{}.{}.{}'.format(arr[0], hashed, arr[2])) - deadline_plugin_info.MultiProcess = True deadline_plugin_info.Comp = self._instance.data["comp_name"] - deadline_plugin_info.Version = "17.5" + deadline_plugin_info.Version = self._instance.data["app_version"] + # must be here because of DL AE plugin + deadline_plugin_info.MultiProcess = self.multiprocess deadline_plugin_info.SceneFile = self.scene_path deadline_plugin_info.Output = render_path.replace("\\", "/") From 986a83c93d651784ea3eda1141562d504d188316 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 2 Feb 2022 13:28:44 +0100 Subject: [PATCH 033/109] OP-2551 - added app version method Used to properly propagate major.minor version from the app to allow DL configure proper executables --- openpype/hosts/aftereffects/api/extension.zxp | Bin 100915 -> 100982 bytes .../api/extension/CSXS/manifest.xml | 2 +- .../aftereffects/api/extension/js/main.js | 9 +++++++++ .../api/extension/jsx/hostscript.jsx | 9 ++++++++- openpype/hosts/aftereffects/api/ws_stub.py | 7 +++++++ .../plugins/publish/collect_render.py | 7 ++++++- 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/aftereffects/api/extension.zxp b/openpype/hosts/aftereffects/api/extension.zxp index 35b0c0fc42a731150521187312ef21243882f300..389d74505dfc45ecba6313435056634a64b27c20 100644 GIT binary patch delta 12141 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 SmFVYt`==7qI{@_a+y4W51~sby delta 12102 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 diff --git a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml index 2480089825..668cb3fc24 100644 --- a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml +++ b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml @@ -1,5 +1,5 @@ - diff --git a/openpype/hosts/aftereffects/api/extension/js/main.js b/openpype/hosts/aftereffects/api/extension/js/main.js index 7736a07a5e..2105ea82dc 100644 --- a/openpype/hosts/aftereffects/api/extension/js/main.js +++ b/openpype/hosts/aftereffects/api/extension/js/main.js @@ -301,6 +301,15 @@ function main(websocket_url){ return get_extension_version(); }); + RPC.addRoute('AfterEffects.get_app_version', function (data) { + log.warn('Server called client route "get_app_version":', data); + return runEvalScript("getAppVersion()") + .then(function(result){ + log.warn("get_app_version: " + result); + return result; + }); + }); + RPC.addRoute('AfterEffects.close', function (data) { log.warn('Server called client route "close":', data); return runEvalScript("close()"); diff --git a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx index d3b5700920..8f82c9709d 100644 --- a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx +++ b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx @@ -438,7 +438,10 @@ function getAudioUrlForComp(comp_id){ for (i = 1; i <= item.numLayers; ++i){ var layer = item.layers[i]; if (layer instanceof AVLayer){ - return layer.source.file.fsName.toString(); + if (layer.hasAudio){ + source_url = layer.source.file.fsName.toString() + return _prepareSingleValue(source_url); + } } } @@ -715,6 +718,10 @@ function close(){ app.quit(); } +function getAppVersion(){ + return _prepareSingleValue(app.version); +} + function _prepareSingleValue(value){ return JSON.stringify({"result": value}) } diff --git a/openpype/hosts/aftereffects/api/ws_stub.py b/openpype/hosts/aftereffects/api/ws_stub.py index 48f31f1f4e..5a0600e92e 100644 --- a/openpype/hosts/aftereffects/api/ws_stub.py +++ b/openpype/hosts/aftereffects/api/ws_stub.py @@ -537,6 +537,13 @@ class AfterEffectsServerStub(): return self._handle_return(res) + def get_app_version(self): + """Returns version number of installed application (17.5...).""" + res = self.websocketserver.call(self.client.call( + 'AfterEffects.get_app_version')) + + return self._handle_return(res) + def close(self): res = self.websocketserver.call(self.client.call('AfterEffects.close')) diff --git a/openpype/hosts/aftereffects/plugins/publish/collect_render.py b/openpype/hosts/aftereffects/plugins/publish/collect_render.py index 74d38751e1..02b95be138 100644 --- a/openpype/hosts/aftereffects/plugins/publish/collect_render.py +++ b/openpype/hosts/aftereffects/plugins/publish/collect_render.py @@ -20,6 +20,7 @@ class AERenderInstance(RenderInstance): fps = attr.ib(default=None) projectEntity = attr.ib(default=None) stagingDir = attr.ib(default=None) + app_version = attr.ib(default=None) class CollectAERender(abstract_collect_render.AbstractCollectRender): @@ -41,6 +42,9 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender): def get_instances(self, context): instances = [] + app_version = self.stub.get_app_version() + app_version = app_version[0:4] + current_file = context.data["currentFile"] version = context.data["version"] asset_entity = context.data["assetEntity"] @@ -105,7 +109,8 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender): frameEnd=frameEnd, frameStep=1, toBeRenderedOn='deadline', - fps=fps + fps=fps, + app_version=app_version ) comp = compositions_by_id.get(int(item_id)) From a7c4c04596c1a9decd7e9fcb480eb4150011c57b Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 2 Feb 2022 17:47:46 +0100 Subject: [PATCH 034/109] fix usd family this is fixing usd family in loaders and integrator --- openpype/hosts/houdini/plugins/load/load_usd_layer.py | 5 +---- openpype/hosts/houdini/plugins/load/load_usd_reference.py | 5 +---- openpype/plugins/publish/integrate_new.py | 3 ++- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/houdini/plugins/load/load_usd_layer.py b/openpype/hosts/houdini/plugins/load/load_usd_layer.py index 7483101409..b4f9124567 100644 --- a/openpype/hosts/houdini/plugins/load/load_usd_layer.py +++ b/openpype/hosts/houdini/plugins/load/load_usd_layer.py @@ -6,10 +6,7 @@ class USDSublayerLoader(api.Loader): """Sublayer USD file in Solaris""" families = [ - "colorbleed.usd", - "colorbleed.pointcache", - "colorbleed.animation", - "colorbleed.camera", + "usd", "usdCamera", ] label = "Sublayer USD" diff --git a/openpype/hosts/houdini/plugins/load/load_usd_reference.py b/openpype/hosts/houdini/plugins/load/load_usd_reference.py index cab3cb5269..e7a428add1 100644 --- a/openpype/hosts/houdini/plugins/load/load_usd_reference.py +++ b/openpype/hosts/houdini/plugins/load/load_usd_reference.py @@ -6,10 +6,7 @@ class USDReferenceLoader(api.Loader): """Reference USD file in Solaris""" families = [ - "colorbleed.usd", - "colorbleed.pointcache", - "colorbleed.animation", - "colorbleed.camera", + "usd", "usdCamera", ] label = "Reference USD" diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index bf214d9139..3d48fb92ee 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -100,7 +100,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "redshiftproxy", "effect", "xgen", - "hda" + "hda", + "usd" ] exclude_families = ["clip"] db_representation_context_keys = [ From 255bf9e6ea3e1b47f4ca2877ce73127113762bb6 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 3 Feb 2022 13:41:14 +0100 Subject: [PATCH 035/109] flame: adding exception to ftrack plugin --- .../openpype_flame_to_ftrack/openpype_flame_to_ftrack.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py index 688b8b6ae3..ecc16fde6e 100644 --- a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py +++ b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py @@ -3,6 +3,11 @@ from __future__ import print_function import os import sys +try: + import six +except ImportError: + raise ImportError("Cannot import this module") + SCRIPT_DIR = os.path.dirname(__file__) PACKAGE_DIR = os.path.join(SCRIPT_DIR, "modules") sys.path.append(PACKAGE_DIR) From 4501c8eaf1da1314e898480e9d1f757789d8b93f Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 8 Feb 2022 14:31:54 +0100 Subject: [PATCH 036/109] add default for ftrack, fix family name --- .../houdini/plugins/publish/collect_usd_layers.py | 2 +- .../defaults/project_settings/ftrack.json | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_usd_layers.py b/openpype/hosts/houdini/plugins/publish/collect_usd_layers.py index 8be6ead1b1..e3985e3c97 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_usd_layers.py +++ b/openpype/hosts/houdini/plugins/publish/collect_usd_layers.py @@ -48,7 +48,7 @@ class CollectUsdLayers(pyblish.api.InstancePlugin): label = "{0} -> {1}".format(instance.data["name"], name) layer_inst = context.create_instance(name) - family = "colorbleed.usdlayer" + family = "usdlayer" layer_inst.data["family"] = family layer_inst.data["families"] = [family] layer_inst.data["subset"] = "__stub__" diff --git a/openpype/settings/defaults/project_settings/ftrack.json b/openpype/settings/defaults/project_settings/ftrack.json index 1474ad103d..3d32ea0b7c 100644 --- a/openpype/settings/defaults/project_settings/ftrack.json +++ b/openpype/settings/defaults/project_settings/ftrack.json @@ -331,6 +331,18 @@ "tasks": [], "add_ftrack_family": true, "advanced_filtering": [] + }, + { + "hosts": [ + "houdini" + ], + "families": [ + "usd" + ], + "task_types": [], + "tasks": [], + "add_ftrack_family": true, + "advanced_filtering": [] } ] }, @@ -374,7 +386,8 @@ "layout": "layout", "unrealStaticMesh": "geo", "vrayproxy": "cache", - "redshiftproxy": "cache" + "redshiftproxy": "cache", + "usd": "usd" } } } From 816eb713938b5b11371c148ffbfbedfe1866d3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Wed, 9 Feb 2022 14:57:25 +0100 Subject: [PATCH 037/109] add `/stage` to ls --- openpype/hosts/houdini/api/lib.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index eaaba94ed5..6e48791ce8 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -406,6 +406,7 @@ def imprint(node, data): def lsattr(attr, value=None): if value is None: nodes = list(hou.node("/obj").allNodes()) + nodes += list(hou.node("/stage").allNodes()) return [n for n in nodes if n.parm(attr)] return lsattrs({attr: value}) @@ -428,6 +429,7 @@ def lsattrs(attrs): matches = set() nodes = list(hou.node("/obj").allNodes()) # returns generator object + nodes += list(hou.node("/stage").allNodes()) for node in nodes: for attr in attrs: if not node.parm(attr): From e9b7501a1730f3bf65871a2cf0120b591d74c8cf Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 10 Feb 2022 12:58:50 +0100 Subject: [PATCH 038/109] addressing PR comments --- openpype/hosts/flame/api/pipeline.py | 7 +++---- openpype/hosts/flame/api/plugin.py | 15 ++------------- .../openpype_flame_to_ftrack.py | 6 +++--- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/openpype/hosts/flame/api/pipeline.py b/openpype/hosts/flame/api/pipeline.py index 476a65e59b..21cb7422de 100644 --- a/openpype/hosts/flame/api/pipeline.py +++ b/openpype/hosts/flame/api/pipeline.py @@ -6,7 +6,6 @@ import contextlib from avalon import api as avalon from avalon.pipeline import AVALON_CONTAINER_ID from pyblish import api as pyblish -from collections import OrderedDict from openpype.api import Logger from .lib import ( set_segment_data_marker, @@ -77,18 +76,18 @@ def containerise(flame_clip, loader=None, data=None): - data_imprint = OrderedDict({ + data_imprint = { "schema": "openpype:container-2.0", "id": AVALON_CONTAINER_ID, "name": str(name), "namespace": str(namespace), "loader": str(loader), "representation": str(context["representation"]["_id"]), - }) + } if data: for k, v in data.items(): - data_imprint.update({k: v}) + data_imprint[k] = v log.debug("_ data_imprint: {}".format(data_imprint)) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index c28ab0f556..aba83c543a 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -4,7 +4,6 @@ import shutil import sys from avalon.vendor import qargparse from xml.etree import ElementTree as ET -import shutil import six from Qt import QtWidgets, QtCore import openpype.api as openpype @@ -680,16 +679,6 @@ class ClipLoader(avalon.Loader): ): pass - def update(self, container, representation): - """Update an existing `container` - """ - pass - - def remove(self, container): - """Remove an existing `container` - """ - pass - class OpenClipSolver: media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" @@ -734,7 +723,7 @@ class OpenClipSolver: self.log.info("Temp File: {}".format(self.tmp_file)) def make(self): - self._get_media_info_args() + self._generate_media_info_file() if self.create_new_clip: # New openClip @@ -747,7 +736,7 @@ class OpenClipSolver: raise IOError("Media Scirpt does not exist: `{}`".format( self.media_script_path)) - def _get_media_info_args(self): + def _generate_media_info_file(self): # Create cmd arguments for gettig xml file info file cmd_args = [ self.media_script_path, diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py index ecc16fde6e..65c1840a72 100644 --- a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py +++ b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py @@ -4,9 +4,9 @@ import os import sys try: - import six -except ImportError: - raise ImportError("Cannot import this module") + import six # noqa +except ImportError as msg: + raise ImportError("Cannot import this module: {}".format(msg)) from msg SCRIPT_DIR = os.path.dirname(__file__) PACKAGE_DIR = os.path.join(SCRIPT_DIR, "modules") From 59106179435cdc267a1dc13a6f7d6b76ca470bc3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 10 Feb 2022 13:01:27 +0100 Subject: [PATCH 039/109] addresing comment https://github.com/pypeclub/OpenPype/pull/2622#discussion_r797535248 --- openpype/hosts/flame/api/plugin.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index aba83c543a..c39ac9108f 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -670,15 +670,6 @@ class ClipLoader(avalon.Loader): ) ] - def load( - self, - context, - name=None, - namespace=None, - options=None - ): - pass - class OpenClipSolver: media_script_path = "/opt/Autodesk/mio/current/dl_get_media_info" From 8e12ef43df359a1aeafc4abb8d78307a8c86edf0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 10 Feb 2022 15:28:19 +0100 Subject: [PATCH 040/109] flame: add clip segment unpacking method --- openpype/hosts/flame/api/__init__.py | 4 +++- openpype/hosts/flame/api/lib.py | 15 +++++++++++++++ openpype/hosts/flame/api/pipeline.py | 8 +++----- openpype/hosts/flame/plugins/load/load_clip.py | 4 +++- yarn.lock | 4 ++++ 5 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 yarn.lock diff --git a/openpype/hosts/flame/api/__init__.py b/openpype/hosts/flame/api/__init__.py index 2aeb0d9c16..56bbadd2fc 100644 --- a/openpype/hosts/flame/api/__init__.py +++ b/openpype/hosts/flame/api/__init__.py @@ -28,7 +28,8 @@ from .lib import ( get_reformated_filename, get_frame_from_filename, get_padding_from_filename, - maintained_object_duplication + maintained_object_duplication, + get_clip_segment ) from .utils import ( setup, @@ -99,6 +100,7 @@ __all__ = [ "get_frame_from_filename", "get_padding_from_filename", "maintained_object_duplication", + "get_clip_segment", # pipeline "install", diff --git a/openpype/hosts/flame/api/lib.py b/openpype/hosts/flame/api/lib.py index f3c918caab..bbb7c38119 100644 --- a/openpype/hosts/flame/api/lib.py +++ b/openpype/hosts/flame/api/lib.py @@ -692,3 +692,18 @@ def maintained_object_duplication(item): finally: # delete the item at the end flame.delete(duplicate) + + +def get_clip_segment(flame_clip): + name = flame_clip.name.get_value() + version = flame_clip.versions[0] + track = version.tracks[0] + segments = track.segments + + if len(segments) < 1: + raise ValueError("Clip `{}` has no segments!".format(name)) + + if len(segments) > 1: + raise ValueError("Clip `{}` has too many segments!".format(name)) + + return segments[0] diff --git a/openpype/hosts/flame/api/pipeline.py b/openpype/hosts/flame/api/pipeline.py index 21cb7422de..fa007e63af 100644 --- a/openpype/hosts/flame/api/pipeline.py +++ b/openpype/hosts/flame/api/pipeline.py @@ -69,7 +69,7 @@ def uninstall(): log.info("OpenPype Flame host uninstalled ...") -def containerise(flame_clip, +def containerise(flame_clip_segment, name, namespace, context, @@ -91,11 +91,9 @@ def containerise(flame_clip, log.debug("_ data_imprint: {}".format(data_imprint)) - segment = flame_clip.versions[-1].tracks[-1].segments[-1] + set_segment_data_marker(flame_clip_segment, data_imprint) - set_segment_data_marker(segment, data_imprint) - - return flame_clip + return True def ls(): diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index 112571bf09..23598cdb27 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -97,8 +97,10 @@ class LoadClip(opfapi.ClipLoader): "objectName": clip_name }) + opc_segment = opfapi.get_clip_segment(opc) + return opfapi.containerise( - opc, + opc_segment, name, namespace, context, self.__class__.__name__, data_imprint) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..fb57ccd13a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From 390c6d15a580f18b736dbb26670effe24719d974 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 10 Feb 2022 17:31:32 +0100 Subject: [PATCH 041/109] handle permissions and root more gracefully --- openpype/hosts/houdini/api/lib.py | 33 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index 6e48791ce8..937863caba 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -403,33 +403,46 @@ def imprint(node, data): node.setParmTemplateGroup(parm_group) -def lsattr(attr, value=None): +def lsattr(attr, value=None, root="/"): + """Return nodes that have `attr` + When `value` is not None it will only return nodes matching that value + for the given attribute. + Args: + attr (str): Name of the attribute (hou.Parm) + value (object, Optional): The value to compare the attribute too. + When the default None is provided the value check is skipped. + root (str): The root path in Houdini to search in. + Returns: + list: Matching nodes that have attribute with value. + """ if value is None: - nodes = list(hou.node("/obj").allNodes()) - nodes += list(hou.node("/stage").allNodes()) + # Use allSubChildren() as allNodes() errors on nodes without + # permission to enter without a means to continue of querying + # the rest + nodes = hou.node(root).allSubChildren() return [n for n in nodes if n.parm(attr)] return lsattrs({attr: value}) -def lsattrs(attrs): +def lsattrs(attrs, root="/"): """Return nodes matching `key` and `value` - Arguments: attrs (dict): collection of attribute: value - + root (str): The root path in Houdini to search in. Example: >> lsattrs({"id": "myId"}) ["myNode"] >> lsattr("id") ["myNode", "myOtherNode"] - Returns: - list + list: Matching nodes that have attribute with value. """ matches = set() - nodes = list(hou.node("/obj").allNodes()) # returns generator object - nodes += list(hou.node("/stage").allNodes()) + # Use allSubChildren() as allNodes() errors on nodes without + # permission to enter without a means to continue of querying + # the rest + nodes = hou.node(root).allSubChildren() for node in nodes: for attr in attrs: if not node.parm(attr): From c545938e2a1d912c24a0306d01ad58b6da817629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Mon, 14 Feb 2022 12:09:51 +0100 Subject: [PATCH 042/109] Update openpype/hosts/flame/api/plugin.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/flame/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index c39ac9108f..db1793cba8 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -740,7 +740,7 @@ class OpenClipSolver: try: openpype.run_subprocess(cmd_args) except TypeError: - self.log.error("Error createing self.tmp_file") + self.log.error("Error creating self.tmp_file") six.reraise(*sys.exc_info()) def _clear_tmp_file(self): From 6664db839fa0f9516916b80cddccfc17be6b0eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Mon, 14 Feb 2022 12:10:03 +0100 Subject: [PATCH 043/109] Update openpype/hosts/flame/plugins/publish/extract_subset_resources.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../hosts/flame/plugins/publish/extract_subset_resources.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index e00f97d8ea..5abbbb4b15 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -49,10 +49,9 @@ class ExtractSubsetResources(openpype.api.Extractor): def process(self, instance): try: self._process(instance) - # bring ui back - self.hide_ui_on_process = False except Exception as msg: self.log.error(msg) + finally: # bring ui back self.hide_ui_on_process = False From 91f9d41c39a91310c1c647ce7ef32131128dedf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Mon, 14 Feb 2022 12:11:04 +0100 Subject: [PATCH 044/109] Update openpype/hosts/flame/plugins/publish/extract_subset_resources.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../flame/plugins/publish/extract_subset_resources.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index 5abbbb4b15..d774b07fca 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -249,10 +249,10 @@ class ExtractSubsetResources(openpype.api.Extractor): if not new_stage_dir: new_stage_dir = root - if new_stage_dir: - return new_stage_dir, new_files_list - else: - raise IOError( + if not new_stage_dir: + raise AssertionError( "Files in `{}` are not correct! Check `{}`".format( files_list, stage_dir) ) + + return new_stage_dir, new_files_list From c6c73de82c94880053d62cd2755b8be132726530 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 14 Feb 2022 12:22:43 +0100 Subject: [PATCH 045/109] moved init utils directly to prelaunch hook --- openpype/hosts/fusion/api/__init__.py | 7 -- openpype/hosts/fusion/api/utils.py | 86 ------------------- .../hosts/fusion/hooks/pre_fusion_setup.py | 77 ++++++++++++++--- 3 files changed, 63 insertions(+), 107 deletions(-) delete mode 100644 openpype/hosts/fusion/api/utils.py diff --git a/openpype/hosts/fusion/api/__init__.py b/openpype/hosts/fusion/api/__init__.py index 5aee978c15..4ec9177af7 100644 --- a/openpype/hosts/fusion/api/__init__.py +++ b/openpype/hosts/fusion/api/__init__.py @@ -3,11 +3,6 @@ from .pipeline import ( uninstall ) -from .utils import ( - setup -) - - from .lib import ( get_additional_data, update_frame_range @@ -21,8 +16,6 @@ __all__ = [ "install", "uninstall", - # utils - "setup", # lib "get_additional_data", diff --git a/openpype/hosts/fusion/api/utils.py b/openpype/hosts/fusion/api/utils.py deleted file mode 100644 index 5605323b1e..0000000000 --- a/openpype/hosts/fusion/api/utils.py +++ /dev/null @@ -1,86 +0,0 @@ -#! python3 - -""" -Fusion tools for setting environment -""" - -import os -import shutil - -from openpype.api import Logger -import openpype.hosts.fusion - -log = Logger().get_logger(__name__) - - -def _sync_utility_scripts(env=None): - """ Synchronizing basic utlility scripts for resolve. - - To be able to run scripts from inside `Fusion/Workspace/Scripts` menu - all scripts has to be accessible from defined folder. - """ - if not env: - env = os.environ - - # initiate inputs - scripts = {} - us_env = env.get("FUSION_UTILITY_SCRIPTS_SOURCE_DIR") - us_dir = env.get("FUSION_UTILITY_SCRIPTS_DIR", "") - us_paths = [os.path.join( - os.path.dirname(os.path.abspath(openpype.hosts.fusion.__file__)), - "utility_scripts" - )] - - # collect script dirs - if us_env: - log.info(f"Utility Scripts Env: `{us_env}`") - us_paths = us_env.split( - os.pathsep) + us_paths - - # collect scripts from dirs - for path in us_paths: - scripts.update({path: os.listdir(path)}) - - log.info(f"Utility Scripts Dir: `{us_paths}`") - log.info(f"Utility Scripts: `{scripts}`") - - # make sure no script file is in folder - if next((s for s in os.listdir(us_dir)), None): - for s in os.listdir(us_dir): - path = os.path.normpath( - os.path.join(us_dir, s)) - log.info(f"Removing `{path}`...") - - # remove file or directory if not in our folders - if not os.path.isdir(path): - os.remove(path) - else: - shutil.rmtree(path) - - # copy scripts into Resolve's utility scripts dir - for d, sl in scripts.items(): - # directory and scripts list - for s in sl: - # script in script list - src = os.path.normpath(os.path.join(d, s)) - dst = os.path.normpath(os.path.join(us_dir, s)) - - log.info(f"Copying `{src}` to `{dst}`...") - - # copy file or directory from our folders to fusion's folder - if not os.path.isdir(src): - shutil.copy2(src, dst) - else: - shutil.copytree(src, dst) - - -def setup(env=None): - """ Wrapper installer started from pype.hooks.fusion.FusionPrelaunch() - """ - if not env: - env = os.environ - - # synchronize resolve utility scripts - _sync_utility_scripts(env) - - log.info("Fusion Pype wrapper has been installed") diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index 4a9dfaec15..b104b3c081 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -1,7 +1,8 @@ import os -import importlib +import shutil + +import openpype.hosts.fusion from openpype.lib import PreLaunchHook, ApplicationLaunchFailed -from openpype.hosts.fusion.api import utils class FusionPrelaunch(PreLaunchHook): @@ -36,17 +37,65 @@ class FusionPrelaunch(PreLaunchHook): f"Fusion.\n\nFUSION_UTILITY_SCRIPTS_DIR: '{us_dir}'" ) - try: - __import__("avalon.fusion") - __import__("pyblish") + self._sync_utility_scripts(self.launch_context.env) + self.log.info("Fusion Pype wrapper has been installed") - except ImportError: - self.log.warning( - "pyblish: Could not load Fusion integration.", - exc_info=True - ) + def _sync_utility_scripts(self, env): + """ Synchronizing basic utlility scripts for resolve. - else: - # Resolve Setup integration - importlib.reload(utils) - utils.setup(self.launch_context.env) + To be able to run scripts from inside `Fusion/Workspace/Scripts` menu + all scripts has to be accessible from defined folder. + """ + if not env: + env = {k: v for k, v in os.environ.items()} + + # initiate inputs + scripts = {} + us_env = env.get("FUSION_UTILITY_SCRIPTS_SOURCE_DIR") + us_dir = env.get("FUSION_UTILITY_SCRIPTS_DIR", "") + us_paths = [os.path.join( + os.path.dirname(os.path.abspath(openpype.hosts.fusion.__file__)), + "utility_scripts" + )] + + # collect script dirs + if us_env: + self.log.info(f"Utility Scripts Env: `{us_env}`") + us_paths = us_env.split( + os.pathsep) + us_paths + + # collect scripts from dirs + for path in us_paths: + scripts.update({path: os.listdir(path)}) + + self.log.info(f"Utility Scripts Dir: `{us_paths}`") + self.log.info(f"Utility Scripts: `{scripts}`") + + # make sure no script file is in folder + if next((s for s in os.listdir(us_dir)), None): + for s in os.listdir(us_dir): + path = os.path.normpath( + os.path.join(us_dir, s)) + self.log.info(f"Removing `{path}`...") + + # remove file or directory if not in our folders + if not os.path.isdir(path): + os.remove(path) + else: + shutil.rmtree(path) + + # copy scripts into Resolve's utility scripts dir + for d, sl in scripts.items(): + # directory and scripts list + for s in sl: + # script in script list + src = os.path.normpath(os.path.join(d, s)) + dst = os.path.normpath(os.path.join(us_dir, s)) + + self.log.info(f"Copying `{src}` to `{dst}`...") + + # copy file or directory from our folders to fusion's folder + if not os.path.isdir(src): + shutil.copy2(src, dst) + else: + shutil.copytree(src, dst) From c70d0c25ec9f8b93852398e9f1cd2a5e1d1b042f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 14 Feb 2022 12:23:36 +0100 Subject: [PATCH 046/109] moved fusion implementation from avalon to openpype --- openpype/hosts/fusion/api/__init__.py | 35 +++- openpype/hosts/fusion/api/lib.py | 59 ++++++- openpype/hosts/fusion/api/menu.py | 2 +- openpype/hosts/fusion/api/pipeline.py | 165 ++++++++++++++++-- openpype/hosts/fusion/api/workio.py | 45 +++++ .../fusion/plugins/create/create_exr_saver.py | 9 +- .../plugins/inventory/select_containers.py | 10 +- .../plugins/inventory/set_tool_color.py | 12 +- .../fusion/plugins/load/load_sequence.py | 23 +-- .../fusion/plugins/publish/collect_comp.py | 4 +- .../plugins/publish/collect_instances.py | 2 +- .../fusion/plugins/publish/render_local.py | 8 +- .../fusion/plugins/publish/submit_deadline.py | 5 +- .../fusion/scripts/duplicate_with_inputs.py | 9 +- .../fusion/scripts/fusion_switch_shot.py | 30 ++-- .../hosts/fusion/scripts/set_rendermode.py | 6 +- .../32bit/backgrounds_selected_to32bit.py | 9 +- .../32bit/backgrounds_to32bit.py | 8 +- .../32bit/loaders_selected_to32bit.py | 8 +- .../utility_scripts/32bit/loaders_to32bit.py | 8 +- .../utility_scripts/__OpenPype_Menu__.py | 6 +- .../hosts/fusion/utility_scripts/switch_ui.py | 19 +- .../utility_scripts/update_loader_ranges.py | 9 +- 23 files changed, 382 insertions(+), 109 deletions(-) create mode 100644 openpype/hosts/fusion/api/workio.py diff --git a/openpype/hosts/fusion/api/__init__.py b/openpype/hosts/fusion/api/__init__.py index 4ec9177af7..19d1e092fe 100644 --- a/openpype/hosts/fusion/api/__init__.py +++ b/openpype/hosts/fusion/api/__init__.py @@ -1,9 +1,27 @@ from .pipeline import ( install, - uninstall + uninstall, + + ls, + + imprint_container, + parse_container, + + get_current_comp, + comp_lock_and_undo_chunk +) + +from .workio import ( + open_file, + save_file, + current_file, + has_unsaved_changes, + file_extensions, + work_root ) from .lib import ( + maintained_selection, get_additional_data, update_frame_range ) @@ -15,9 +33,24 @@ __all__ = [ # pipeline "install", "uninstall", + "ls", + "imprint_container", + "parse_container", + + "get_current_comp", + "comp_lock_and_undo_chunk", + + # workio + "open_file", + "save_file", + "current_file", + "has_unsaved_changes", + "file_extensions", + "work_root", # lib + "maintained_selection", "get_additional_data", "update_frame_range", diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 7afcdd82ea..5d97f83032 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -1,8 +1,13 @@ +import os import sys +import re +import contextlib from Qt import QtGui -import avalon.fusion + +import avalon.api from avalon import io +from .pipeline import get_current_comp, comp_lock_and_undo_chunk self = sys.modules[__name__] self._project = None @@ -24,7 +29,7 @@ def update_frame_range(start, end, comp=None, set_render_range=True): """ if not comp: - comp = avalon.fusion.get_current_comp() + comp = get_current_comp() attrs = { "COMPN_GlobalStart": start, @@ -37,7 +42,7 @@ def update_frame_range(start, end, comp=None, set_render_range=True): "COMPN_RenderEnd": end }) - with avalon.fusion.comp_lock_and_undo_chunk(comp): + with comp_lock_and_undo_chunk(comp): comp.SetAttrs(attrs) @@ -140,3 +145,51 @@ def switch_item(container, avalon.api.switch(container, representation) return representation + + +@contextlib.contextmanager +def maintained_selection(): + comp = get_current_comp() + previous_selection = comp.GetToolList(True).values() + try: + yield + finally: + flow = comp.CurrentFrame.FlowView + flow.Select() # No args equals clearing selection + if previous_selection: + for tool in previous_selection: + flow.Select(tool, True) + + +def get_frame_path(path): + """Get filename for the Fusion Saver with padded number as '#' + + >>> get_frame_path("C:/test.exr") + ('C:/test', 4, '.exr') + + >>> get_frame_path("filename.00.tif") + ('filename.', 2, '.tif') + + >>> get_frame_path("foobar35.tif") + ('foobar', 2, '.tif') + + Args: + path (str): The path to render to. + + Returns: + tuple: head, padding, tail (extension) + + """ + filename, ext = os.path.splitext(path) + + # Find a final number group + match = re.match('.*?([0-9]+)$', filename) + if match: + padding = len(match.group(1)) + # remove number from end since fusion + # will swap it with the frame number + filename = filename[:-padding] + else: + padding = 4 # default Fusion padding + + return filename, padding, ext diff --git a/openpype/hosts/fusion/api/menu.py b/openpype/hosts/fusion/api/menu.py index d1c01163b1..11b6c2e273 100644 --- a/openpype/hosts/fusion/api/menu.py +++ b/openpype/hosts/fusion/api/menu.py @@ -3,6 +3,7 @@ import sys from Qt import QtWidgets, QtCore +from openpype import style from openpype.tools.utils import host_tools from openpype.hosts.fusion.scripts import ( @@ -128,7 +129,6 @@ class OpenPypeMenu(QtWidgets.QWidget): host_tools.show_library_loader() def on_rendernode_clicked(self): - from avalon import style print("Clicked Set Render Mode") if self.render_mode_widget is None: window = set_rendermode.SetRenderMode() diff --git a/openpype/hosts/fusion/api/pipeline.py b/openpype/hosts/fusion/api/pipeline.py index 6b16339e53..70aac69b44 100644 --- a/openpype/hosts/fusion/api/pipeline.py +++ b/openpype/hosts/fusion/api/pipeline.py @@ -2,9 +2,14 @@ Basic avalon integration """ import os +import sys +import logging +import contextlib + +import pyblish.api +import avalon.api +from avalon.pipeline import AVALON_CONTAINER_ID -from avalon import api as avalon -from pyblish import api as pyblish from openpype.api import Logger import openpype.hosts.fusion @@ -19,6 +24,14 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create") INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") +class CompLogHandler(logging.Handler): + def emit(self, record): + entry = self.format(record) + comp = get_current_comp() + if comp: + comp.Print(entry) + + def install(): """Install fusion-specific functionality of avalon-core. @@ -30,25 +43,39 @@ def install(): See the Maya equivalent for inspiration on how to implement this. """ + # Remove all handlers associated with the root logger object, because + # that one sometimes logs as "warnings" incorrectly. + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + + # Attach default logging handler that prints to active comp + logger = logging.getLogger() + formatter = logging.Formatter(fmt="%(message)s\n") + handler = CompLogHandler() + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG) # Disable all families except for the ones we explicitly want to see family_states = ["imagesequence", "camera", "pointcache"] - avalon.data["familiesStateDefault"] = False - avalon.data["familiesStateToggled"] = family_states + avalon.api.data["familiesStateDefault"] = False + avalon.api.data["familiesStateToggled"] = family_states log.info("openpype.hosts.fusion installed") - pyblish.register_host("fusion") - pyblish.register_plugin_path(PUBLISH_PATH) + pyblish.api.register_host("fusion") + pyblish.api.register_plugin_path(PUBLISH_PATH) log.info("Registering Fusion plug-ins..") - avalon.register_plugin_path(avalon.Loader, LOAD_PATH) - avalon.register_plugin_path(avalon.Creator, CREATE_PATH) - avalon.register_plugin_path(avalon.InventoryAction, INVENTORY_PATH) + avalon.api.register_plugin_path(avalon.api.Loader, LOAD_PATH) + avalon.api.register_plugin_path(avalon.api.Creator, CREATE_PATH) + avalon.api.register_plugin_path(avalon.api.InventoryAction, INVENTORY_PATH) - pyblish.register_callback("instanceToggled", on_pyblish_instance_toggled) + pyblish.api.register_callback( + "instanceToggled", on_pyblish_instance_toggled + ) def uninstall(): @@ -62,22 +89,19 @@ def uninstall(): modifying the menu or registered families. """ - pyblish.deregister_host("fusion") - pyblish.deregister_plugin_path(PUBLISH_PATH) + pyblish.api.deregister_host("fusion") + pyblish.api.deregister_plugin_path(PUBLISH_PATH) log.info("Deregistering Fusion plug-ins..") - avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) - avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) - avalon.deregister_plugin_path(avalon.InventoryAction, INVENTORY_PATH) + avalon.api.deregister_plugin_path(avalon.api.Loader, LOAD_PATH) + avalon.api.deregister_plugin_path(avalon.api.Creator, CREATE_PATH) + avalon.api.deregister_plugin_path(avalon.api.InventoryAction, INVENTORY_PATH) - pyblish.deregister_callback("instanceToggled", on_pyblish_instance_toggled) + pyblish.api.deregister_callback("instanceToggled", on_pyblish_instance_toggled) def on_pyblish_instance_toggled(instance, new_value, old_value): """Toggle saver tool passthrough states on instance toggles.""" - - from avalon.fusion import comp_lock_and_undo_chunk - comp = instance.context.data.get("currentComp") if not comp: return @@ -97,3 +121,106 @@ def on_pyblish_instance_toggled(instance, new_value, old_value): current = attrs["TOOLB_PassThrough"] if current != passthrough: tool.SetAttrs({"TOOLB_PassThrough": passthrough}) + + +def ls(): + """List containers from active Fusion scene + + This is the host-equivalent of api.ls(), but instead of listing + assets on disk, it lists assets already loaded in Fusion; once loaded + they are called 'containers' + + Yields: + dict: container + + """ + + comp = get_current_comp() + tools = comp.GetToolList(False, "Loader").values() + + for tool in tools: + container = parse_container(tool) + if container: + yield container + + +def imprint_container(tool, + name, + namespace, + context, + loader=None): + """Imprint a Loader with metadata + + Containerisation enables a tracking of version, author and origin + for loaded assets. + + Arguments: + tool (object): The node in Fusion to imprint as container, usually a + Loader. + name (str): Name of resulting assembly + namespace (str): Namespace under which to host container + context (dict): Asset information + loader (str, optional): Name of loader used to produce this container. + + Returns: + None + + """ + + data = [ + ("schema", "openpype:container-2.0"), + ("id", AVALON_CONTAINER_ID), + ("name", str(name)), + ("namespace", str(namespace)), + ("loader", str(loader)), + ("representation", str(context["representation"]["_id"])), + ] + + for key, value in data: + tool.SetData("avalon.{}".format(key), value) + + +def parse_container(tool): + """Returns imprinted container data of a tool + + This reads the imprinted data from `imprint_container`. + + """ + + data = tool.GetData('avalon') + if not isinstance(data, dict): + return + + # If not all required data return the empty container + required = ['schema', 'id', 'name', + 'namespace', 'loader', 'representation'] + if not all(key in data for key in required): + return + + container = {key: data[key] for key in required} + + # Store the tool's name + container["objectName"] = tool.Name + + # Store reference to the tool object + container["_tool"] = tool + + return container + + +def get_current_comp(): + """Hack to get current comp in this session""" + fusion = getattr(sys.modules["__main__"], "fusion", None) + return fusion.CurrentComp if fusion else None + + +@contextlib.contextmanager +def comp_lock_and_undo_chunk(comp, undo_queue_name="Script CMD"): + """Lock comp and open an undo chunk during the context""" + try: + comp.Lock() + comp.StartUndo(undo_queue_name) + yield + finally: + comp.Unlock() + comp.EndUndo() diff --git a/openpype/hosts/fusion/api/workio.py b/openpype/hosts/fusion/api/workio.py new file mode 100644 index 0000000000..ec9ac7481a --- /dev/null +++ b/openpype/hosts/fusion/api/workio.py @@ -0,0 +1,45 @@ +"""Host API required Work Files tool""" +import sys +import os +from avalon import api +from .pipeline import get_current_comp + + +def file_extensions(): + return api.HOST_WORKFILE_EXTENSIONS["fusion"] + + +def has_unsaved_changes(): + comp = get_current_comp() + return comp.GetAttrs()["COMPB_Modified"] + + +def save_file(filepath): + comp = get_current_comp() + comp.Save(filepath) + + +def open_file(filepath): + # Hack to get fusion, see + # openpype.hosts.fusion.api.pipeline.get_current_comp() + fusion = getattr(sys.modules["__main__"], "fusion", None) + + return fusion.LoadComp(filepath) + + +def current_file(): + comp = get_current_comp() + current_filepath = comp.GetAttrs()["COMPS_FileName"] + if not current_filepath: + return None + + return current_filepath + + +def work_root(session): + work_dir = session["AVALON_WORKDIR"] + scene_dir = session.get("AVALON_SCENEDIR") + if scene_dir: + return os.path.join(work_dir, scene_dir) + else: + return work_dir diff --git a/openpype/hosts/fusion/plugins/create/create_exr_saver.py b/openpype/hosts/fusion/plugins/create/create_exr_saver.py index 077e77c059..253dac773e 100644 --- a/openpype/hosts/fusion/plugins/create/create_exr_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_exr_saver.py @@ -1,7 +1,10 @@ import os import openpype.api -from avalon import fusion +from openpype.hosts.fusion.api import ( + get_current_comp, + comp_lock_and_undo_chunk +) class CreateOpenEXRSaver(openpype.api.Creator): @@ -15,7 +18,7 @@ class CreateOpenEXRSaver(openpype.api.Creator): file_format = "OpenEXRFormat" - comp = fusion.get_current_comp() + comp = get_current_comp() # todo: improve method of getting current environment # todo: pref avalon.Session over os.environ @@ -25,7 +28,7 @@ class CreateOpenEXRSaver(openpype.api.Creator): filename = "{}..tiff".format(self.name) filepath = os.path.join(workdir, "render", filename) - with fusion.comp_lock_and_undo_chunk(comp): + with comp_lock_and_undo_chunk(comp): args = (-32768, -32768) # Magical position numbers saver = comp.AddTool("Saver", *args) saver.SetAttrs({"TOOLS_Name": self.name}) diff --git a/openpype/hosts/fusion/plugins/inventory/select_containers.py b/openpype/hosts/fusion/plugins/inventory/select_containers.py index 2f7b3e5809..294c134505 100644 --- a/openpype/hosts/fusion/plugins/inventory/select_containers.py +++ b/openpype/hosts/fusion/plugins/inventory/select_containers.py @@ -8,15 +8,17 @@ class FusionSelectContainers(api.InventoryAction): color = "#d8d8d8" def process(self, containers): - - import avalon.fusion + from openpype.hosts.fusion.api import ( + get_current_comp, + comp_lock_and_undo_chunk + ) tools = [i["_tool"] for i in containers] - comp = avalon.fusion.get_current_comp() + comp = get_current_comp() flow = comp.CurrentFrame.FlowView - with avalon.fusion.comp_lock_and_undo_chunk(comp, self.label): + with comp_lock_and_undo_chunk(comp, self.label): # Clear selection flow.Select() diff --git a/openpype/hosts/fusion/plugins/inventory/set_tool_color.py b/openpype/hosts/fusion/plugins/inventory/set_tool_color.py index 9fc7012db7..2f5ae4d241 100644 --- a/openpype/hosts/fusion/plugins/inventory/set_tool_color.py +++ b/openpype/hosts/fusion/plugins/inventory/set_tool_color.py @@ -1,7 +1,11 @@ -from avalon import api, style +from avalon import api from Qt import QtGui, QtWidgets -import avalon.fusion +from openpype import style +from openpype.hosts.fusion.api import ( + get_current_comp, + comp_lock_and_undo_chunk +) class FusionSetToolColor(api.InventoryAction): @@ -16,7 +20,7 @@ class FusionSetToolColor(api.InventoryAction): """Color all selected tools the selected colors""" result = [] - comp = avalon.fusion.get_current_comp() + comp = get_current_comp() # Get tool color first = containers[0] @@ -33,7 +37,7 @@ class FusionSetToolColor(api.InventoryAction): if not picked_color: return - with avalon.fusion.comp_lock_and_undo_chunk(comp): + with comp_lock_and_undo_chunk(comp): for container in containers: # Convert color to RGB 0-1 floats rgb_f = picked_color.getRgbF() diff --git a/openpype/hosts/fusion/plugins/load/load_sequence.py b/openpype/hosts/fusion/plugins/load/load_sequence.py index 8f5be75484..667d50ed45 100644 --- a/openpype/hosts/fusion/plugins/load/load_sequence.py +++ b/openpype/hosts/fusion/plugins/load/load_sequence.py @@ -1,12 +1,15 @@ import os import contextlib -from avalon import api -import avalon.io as io +from avalon import api, io -from avalon import fusion +from openpype.hosts.fusion.api import ( + imprint_container, + get_current_comp, + comp_lock_and_undo_chunk +) -comp = fusion.get_current_comp() +comp = get_current_comp() @contextlib.contextmanager @@ -126,13 +129,6 @@ class FusionLoadSequence(api.Loader): color = "orange" def load(self, context, name, namespace, data): - - from avalon.fusion import ( - imprint_container, - get_current_comp, - comp_lock_and_undo_chunk - ) - # Fallback to asset name when namespace is None if namespace is None: namespace = context['asset']['name'] @@ -204,8 +200,6 @@ class FusionLoadSequence(api.Loader): """ - from avalon.fusion import comp_lock_and_undo_chunk - tool = container["_tool"] assert tool.ID == "Loader", "Must be Loader" comp = tool.Comp() @@ -247,9 +241,6 @@ class FusionLoadSequence(api.Loader): tool.SetData("avalon.representation", str(representation["_id"])) def remove(self, container): - - from avalon.fusion import comp_lock_and_undo_chunk - tool = container["_tool"] assert tool.ID == "Loader", "Must be Loader" comp = tool.Comp() diff --git a/openpype/hosts/fusion/plugins/publish/collect_comp.py b/openpype/hosts/fusion/plugins/publish/collect_comp.py index 1cf182c8ca..dfa540fa7f 100644 --- a/openpype/hosts/fusion/plugins/publish/collect_comp.py +++ b/openpype/hosts/fusion/plugins/publish/collect_comp.py @@ -2,7 +2,7 @@ import os import pyblish.api -from avalon import fusion +from openpype.hosts.fusion.api import get_current_comp class CollectCurrentCompFusion(pyblish.api.ContextPlugin): @@ -15,7 +15,7 @@ class CollectCurrentCompFusion(pyblish.api.ContextPlugin): def process(self, context): """Collect all image sequence tools""" - current_comp = fusion.get_current_comp() + current_comp = get_current_comp() assert current_comp, "Must have active Fusion composition" context.data["currentComp"] = current_comp diff --git a/openpype/hosts/fusion/plugins/publish/collect_instances.py b/openpype/hosts/fusion/plugins/publish/collect_instances.py index 3c7224e65c..b2192d1dd9 100644 --- a/openpype/hosts/fusion/plugins/publish/collect_instances.py +++ b/openpype/hosts/fusion/plugins/publish/collect_instances.py @@ -34,7 +34,7 @@ class CollectInstances(pyblish.api.ContextPlugin): def process(self, context): """Collect all image sequence tools""" - from avalon.fusion.lib import get_frame_path + from openpype.hosts.fusion.api.lib import get_frame_path comp = context.data["currentComp"] diff --git a/openpype/hosts/fusion/plugins/publish/render_local.py b/openpype/hosts/fusion/plugins/publish/render_local.py index 19449ead67..601c2ffccf 100644 --- a/openpype/hosts/fusion/plugins/publish/render_local.py +++ b/openpype/hosts/fusion/plugins/publish/render_local.py @@ -1,9 +1,9 @@ import os -import pyblish.api - -import avalon.fusion as fusion from pprint import pformat +import pyblish.api +from openpype.hosts.fusion.api import comp_lock_and_undo_chunk + class Fusionlocal(pyblish.api.InstancePlugin): """Render the current Fusion composition locally. @@ -39,7 +39,7 @@ class Fusionlocal(pyblish.api.InstancePlugin): self.log.info("Start frame: {}".format(frame_start)) self.log.info("End frame: {}".format(frame_end)) - with fusion.comp_lock_and_undo_chunk(current_comp): + with comp_lock_and_undo_chunk(current_comp): result = current_comp.Render() if "representations" not in instance.data: diff --git a/openpype/hosts/fusion/plugins/publish/submit_deadline.py b/openpype/hosts/fusion/plugins/publish/submit_deadline.py index 28671295ab..9da99dd9e2 100644 --- a/openpype/hosts/fusion/plugins/publish/submit_deadline.py +++ b/openpype/hosts/fusion/plugins/publish/submit_deadline.py @@ -2,8 +2,9 @@ import os import json import getpass +import requests + from avalon import api -from avalon.vendor import requests import pyblish.api @@ -30,7 +31,7 @@ class FusionSubmitDeadline(pyblish.api.InstancePlugin): else: context.data[key] = True - from avalon.fusion.lib import get_frame_path + from openpype.hosts.fusion.api.lib import get_frame_path deadline_url = ( context.data["system_settings"] diff --git a/openpype/hosts/fusion/scripts/duplicate_with_inputs.py b/openpype/hosts/fusion/scripts/duplicate_with_inputs.py index 992dd2cd2d..21da6c24d8 100644 --- a/openpype/hosts/fusion/scripts/duplicate_with_inputs.py +++ b/openpype/hosts/fusion/scripts/duplicate_with_inputs.py @@ -1,4 +1,7 @@ -from avalon import fusion +from openpype.hosts.fusion.api import ( + comp_lock_and_undo_chunk, + get_current_comp +) def is_connected(input): @@ -9,12 +12,12 @@ def is_connected(input): def duplicate_with_input_connections(): """Duplicate selected tools with incoming connections.""" - comp = fusion.get_current_comp() + comp = get_current_comp() original_tools = comp.GetToolList(True).values() if not original_tools: return # nothing selected - with fusion.comp_lock_and_undo_chunk( + with comp_lock_and_undo_chunk( comp, "Duplicate With Input Connections"): # Generate duplicates diff --git a/openpype/hosts/fusion/scripts/fusion_switch_shot.py b/openpype/hosts/fusion/scripts/fusion_switch_shot.py index efb3cad800..041b53f6c9 100644 --- a/openpype/hosts/fusion/scripts/fusion_switch_shot.py +++ b/openpype/hosts/fusion/scripts/fusion_switch_shot.py @@ -4,12 +4,12 @@ import sys import logging # Pipeline imports -from avalon import api, io, pipeline -import avalon.fusion +import avalon.api +from avalon import io, pipeline -# Config imports -import openpype.lib as pype -import openpype.hosts.fusion.api.lib as fusion_lib +from openpype.lib import version_up +from openpype.hosts.fusion import api +from openpype.hosts.fusion.api import lib log = logging.getLogger("Update Slap Comp") @@ -87,7 +87,7 @@ def _format_filepath(session): # Create new unique filepath if os.path.exists(new_filepath): - new_filepath = pype.version_up(new_filepath) + new_filepath = version_up(new_filepath) return new_filepath @@ -119,7 +119,7 @@ def _update_savers(comp, session): comp.Print("New renders to: %s\n" % renders) - with avalon.fusion.comp_lock_and_undo_chunk(comp): + with api.comp_lock_and_undo_chunk(comp): savers = comp.GetToolList(False, "Saver").values() for saver in savers: filepath = saver.GetAttrs("TOOLST_Clip_Name")[1.0] @@ -185,7 +185,7 @@ def update_frame_range(comp, representations): start = min(v["data"]["frameStart"] for v in versions) end = max(v["data"]["frameEnd"] for v in versions) - fusion_lib.update_frame_range(start, end, comp=comp) + lib.update_frame_range(start, end, comp=comp) def switch(asset_name, filepath=None, new=True): @@ -215,11 +215,11 @@ def switch(asset_name, filepath=None, new=True): # Get current project self._project = io.find_one({"type": "project", - "name": api.Session["AVALON_PROJECT"]}) + "name": avalon.api.Session["AVALON_PROJECT"]}) # Go to comp if not filepath: - current_comp = avalon.fusion.get_current_comp() + current_comp = api.get_current_comp() assert current_comp is not None, "Could not find current comp" else: fusion = _get_fusion_instance() @@ -227,14 +227,14 @@ def switch(asset_name, filepath=None, new=True): assert current_comp is not None, ( "Fusion could not load '{}'").format(filepath) - host = api.registered_host() + host = avalon.api.registered_host() containers = list(host.ls()) assert containers, "Nothing to update" representations = [] for container in containers: try: - representation = fusion_lib.switch_item( + representation = lib.switch_item( container, asset_name=asset_name) representations.append(representation) @@ -246,7 +246,7 @@ def switch(asset_name, filepath=None, new=True): current_comp.Print(message) # Build the session to switch to - switch_to_session = api.Session.copy() + switch_to_session = avalon.api.Session.copy() switch_to_session["AVALON_ASSET"] = asset['name'] if new: @@ -255,7 +255,7 @@ def switch(asset_name, filepath=None, new=True): # Update savers output based on new session _update_savers(current_comp, switch_to_session) else: - comp_path = pype.version_up(filepath) + comp_path = version_up(filepath) current_comp.Print(comp_path) @@ -288,7 +288,7 @@ if __name__ == '__main__': args, unknown = parser.parse_args() - api.install(avalon.fusion) + avalon.api.install(api) switch(args.asset_name, args.file_path) sys.exit(0) diff --git a/openpype/hosts/fusion/scripts/set_rendermode.py b/openpype/hosts/fusion/scripts/set_rendermode.py index 73eec528a2..77a2d8e945 100644 --- a/openpype/hosts/fusion/scripts/set_rendermode.py +++ b/openpype/hosts/fusion/scripts/set_rendermode.py @@ -1,6 +1,6 @@ from Qt import QtWidgets from avalon.vendor import qtawesome -import avalon.fusion as avalon +from openpype.hosts.fusion.api import get_current_comp _help = {"local": "Render the comp on your own machine and publish " @@ -14,7 +14,7 @@ class SetRenderMode(QtWidgets.QWidget): def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) - self._comp = avalon.get_current_comp() + self._comp = get_current_comp() self._comp_name = self._get_comp_name() self.setWindowTitle("Set Render Mode") @@ -79,7 +79,7 @@ class SetRenderMode(QtWidgets.QWidget): def update(self): """Update all information in the UI""" - self._comp = avalon.get_current_comp() + self._comp = get_current_comp() self._comp_name = self._get_comp_name() self.comp_information.setText(self._comp_name) diff --git a/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_selected_to32bit.py b/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_selected_to32bit.py index 90e08c4edb..1a0a9911ea 100644 --- a/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_selected_to32bit.py +++ b/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_selected_to32bit.py @@ -1,10 +1,11 @@ -from avalon.fusion import comp_lock_and_undo_chunk - -from avalon import fusion -comp = fusion.get_current_comp() +from openpype.hosts.fusion.api import ( + comp_lock_and_undo_chunk, + get_current_comp +) def main(): + comp = get_current_comp() """Set all selected backgrounds to 32 bit""" with comp_lock_and_undo_chunk(comp, 'Selected Backgrounds to 32bit'): tools = comp.GetToolList(True, "Background").values() diff --git a/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_to32bit.py b/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_to32bit.py index 30ce36fee7..c2eea505e5 100644 --- a/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_to32bit.py +++ b/openpype/hosts/fusion/utility_scripts/32bit/backgrounds_to32bit.py @@ -1,9 +1,11 @@ -from avalon.fusion import comp_lock_and_undo_chunk -from avalon import fusion -comp = fusion.get_current_comp() +from openpype.hosts.fusion.api import ( + comp_lock_and_undo_chunk, + get_current_comp +) def main(): + comp = get_current_comp() """Set all backgrounds to 32 bit""" with comp_lock_and_undo_chunk(comp, 'Backgrounds to 32bit'): tools = comp.GetToolList(False, "Background").values() diff --git a/openpype/hosts/fusion/utility_scripts/32bit/loaders_selected_to32bit.py b/openpype/hosts/fusion/utility_scripts/32bit/loaders_selected_to32bit.py index 403febf19b..2118767f4d 100644 --- a/openpype/hosts/fusion/utility_scripts/32bit/loaders_selected_to32bit.py +++ b/openpype/hosts/fusion/utility_scripts/32bit/loaders_selected_to32bit.py @@ -1,9 +1,11 @@ -from avalon.fusion import comp_lock_and_undo_chunk -from avalon import fusion -comp = fusion.get_current_comp() +from openpype.hosts.fusion.api import ( + comp_lock_and_undo_chunk, + get_current_comp +) def main(): + comp = get_current_comp() """Set all selected loaders to 32 bit""" with comp_lock_and_undo_chunk(comp, 'Selected Loaders to 32bit'): tools = comp.GetToolList(True, "Loader").values() diff --git a/openpype/hosts/fusion/utility_scripts/32bit/loaders_to32bit.py b/openpype/hosts/fusion/utility_scripts/32bit/loaders_to32bit.py index e5670fe41b..7dd1f66a5e 100644 --- a/openpype/hosts/fusion/utility_scripts/32bit/loaders_to32bit.py +++ b/openpype/hosts/fusion/utility_scripts/32bit/loaders_to32bit.py @@ -1,9 +1,11 @@ -from avalon.fusion import comp_lock_and_undo_chunk -from avalon import fusion -comp = fusion.get_current_comp() +from openpype.hosts.fusion.api import ( + comp_lock_and_undo_chunk, + get_current_comp +) def main(): + comp = get_current_comp() """Set all loaders to 32 bit""" with comp_lock_and_undo_chunk(comp, 'Loaders to 32bit'): tools = comp.GetToolList(False, "Loader").values() diff --git a/openpype/hosts/fusion/utility_scripts/__OpenPype_Menu__.py b/openpype/hosts/fusion/utility_scripts/__OpenPype_Menu__.py index 4f804f9bce..4b5e8f91a0 100644 --- a/openpype/hosts/fusion/utility_scripts/__OpenPype_Menu__.py +++ b/openpype/hosts/fusion/utility_scripts/__OpenPype_Menu__.py @@ -8,13 +8,15 @@ log = Logger().get_logger(__name__) def main(env): + import avalon.api + from openpype.hosts.fusion import api from openpype.hosts.fusion.api import menu - import avalon.fusion + # Registers pype's Global pyblish plugins openpype.install() # activate resolve from pype - avalon.api.install(avalon.fusion) + avalon.api.install(api) log.info(f"Avalon registered hosts: {avalon.api.registered_host()}") diff --git a/openpype/hosts/fusion/utility_scripts/switch_ui.py b/openpype/hosts/fusion/utility_scripts/switch_ui.py index 2be91af32a..fe324d9a41 100644 --- a/openpype/hosts/fusion/utility_scripts/switch_ui.py +++ b/openpype/hosts/fusion/utility_scripts/switch_ui.py @@ -4,13 +4,12 @@ import logging from Qt import QtWidgets, QtCore -import avalon.io as io -import avalon.api as api -import avalon.pipeline as pipeline -import avalon.fusion -import avalon.style as style +import avalon.api +from avalon import io, pipeline from avalon.vendor import qtawesome as qta +from openpype import style +from openpype.hosts.fusion import api log = logging.getLogger("Fusion Switch Shot") @@ -150,7 +149,7 @@ class App(QtWidgets.QWidget): if not self._use_current.isChecked(): file_name = self._comps.itemData(self._comps.currentIndex()) else: - comp = avalon.fusion.get_current_comp() + comp = api.get_current_comp() file_name = comp.GetAttrs("COMPS_FileName") asset = self._assets.currentText() @@ -161,11 +160,11 @@ class App(QtWidgets.QWidget): def _get_context_directory(self): project = io.find_one({"type": "project", - "name": api.Session["AVALON_PROJECT"]}, + "name": avalon.api.Session["AVALON_PROJECT"]}, projection={"config": True}) template = project["config"]["template"]["work"] - dir = pipeline._format_work_template(template, api.Session) + dir = pipeline._format_work_template(template, avalon.api.Session) return dir @@ -174,7 +173,7 @@ class App(QtWidgets.QWidget): return items def collect_assets(self): - return list(io.find({"type": "asset", "silo": "film"})) + return list(io.find({"type": "asset"}, {"name": True})) def populate_comp_box(self, files): """Ensure we display the filename only but the path is stored as well @@ -193,7 +192,7 @@ class App(QtWidgets.QWidget): if __name__ == '__main__': import sys - api.install(avalon.fusion) + avalon.api.install(api) app = QtWidgets.QApplication(sys.argv) window = App() diff --git a/openpype/hosts/fusion/utility_scripts/update_loader_ranges.py b/openpype/hosts/fusion/utility_scripts/update_loader_ranges.py index 9ddf1e6dc6..3d2d1ecfa6 100644 --- a/openpype/hosts/fusion/utility_scripts/update_loader_ranges.py +++ b/openpype/hosts/fusion/utility_scripts/update_loader_ranges.py @@ -5,12 +5,15 @@ Warning: settings of the Loader. So use this at your own risk. """ -from avalon import fusion +from openpype.hosts.fusion.api.pipeline import ( + get_current_comp, + comp_lock_and_undo_chunk +) def update_loader_ranges(): - comp = fusion.get_current_comp() - with fusion.comp_lock_and_undo_chunk(comp, "Reload clip time ranges"): + comp = get_current_comp() + with comp_lock_and_undo_chunk(comp, "Reload clip time ranges"): tools = comp.GetToolList(True, "Loader").values() for tool in tools: From 8dca5c9ccb429b39216c2de40d1697945ed71976 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 14:26:30 +0100 Subject: [PATCH 047/109] Allow to add new app versions for Fusion in Setting --- .../host_settings/schema_fusion.json | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index 58f37fa99b..f62b439536 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -20,24 +20,20 @@ "type": "raw-json" }, { - "type": "dict", + "type": "dict-modifiable", "key": "variants", - "children": [ - { - "type": "schema_template", - "name": "template_host_variant", - "template_data": [ - { - "app_variant_label": "16", - "app_variant": "16" - }, - { - "app_variant_label": "9", - "app_variant": "9" - } - ] - } - ] + "collapsible_key": true, + "use_label_wrap": false, + "object_type": { + "type": "dict", + "collapsible": true, + "children": [ + { + "type": "schema_template", + "name": "template_host_variant_items" + } + ] + } } ] -} +} \ No newline at end of file From 4ae8d298a6af68e9a3a8a9bed86dc8bd8e28c5dd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 14:31:44 +0100 Subject: [PATCH 048/109] Add Fusion 17 to defaults --- .../system_settings/applications.json | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 317ed061b4..bfa1bd5cdc 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -690,15 +690,31 @@ "OPENPYPE_LOG_NO_COLORS": "Yes" }, "variants": { - "16": { - "enabled": true, - "variant_label": "16", + "17": { "use_python_2": false, "executables": { + "windows": [ + "C:\\Program Files\\Blackmagic Design\\Fusion 17\\Fusion.exe" + ], + "darwin": [], + "linux": [] + }, + "arguments": { "windows": [], "darwin": [], "linux": [] }, + "environment": {} + }, + "16": { + "use_python_2": false, + "executables": { + "windows": [ + "C:\\Program Files\\Blackmagic Design\\Fusion 16\\Fusion.exe" + ], + "darwin": [], + "linux": [] + }, "arguments": { "windows": [], "darwin": [], @@ -707,8 +723,6 @@ "environment": {} }, "9": { - "enabled": true, - "variant_label": "9", "use_python_2": false, "executables": { "windows": [ From 846082f50211f3ffe1b4a8245b27174d42dd7e71 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 14 Feb 2022 14:32:07 +0100 Subject: [PATCH 049/109] hound fixes --- openpype/hosts/fusion/api/pipeline.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/api/pipeline.py b/openpype/hosts/fusion/api/pipeline.py index 70aac69b44..ec68707401 100644 --- a/openpype/hosts/fusion/api/pipeline.py +++ b/openpype/hosts/fusion/api/pipeline.py @@ -95,9 +95,13 @@ def uninstall(): avalon.api.deregister_plugin_path(avalon.api.Loader, LOAD_PATH) avalon.api.deregister_plugin_path(avalon.api.Creator, CREATE_PATH) - avalon.api.deregister_plugin_path(avalon.api.InventoryAction, INVENTORY_PATH) + avalon.api.deregister_plugin_path( + avalon.api.InventoryAction, INVENTORY_PATH + ) - pyblish.api.deregister_callback("instanceToggled", on_pyblish_instance_toggled) + pyblish.api.deregister_callback( + "instanceToggled", on_pyblish_instance_toggled + ) def on_pyblish_instance_toggled(instance, new_value, old_value): From 00e1a042f4ac821ef840312f4ea10570c69130bb Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 14:52:41 +0100 Subject: [PATCH 050/109] Add "render" family so loaders and actions work on rendered output --- openpype/hosts/fusion/plugins/load/actions.py | 6 ++++-- openpype/hosts/fusion/plugins/load/load_sequence.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/fusion/plugins/load/actions.py b/openpype/hosts/fusion/plugins/load/actions.py index e1cdc6a41b..6af99e4c56 100644 --- a/openpype/hosts/fusion/plugins/load/actions.py +++ b/openpype/hosts/fusion/plugins/load/actions.py @@ -12,7 +12,8 @@ class FusionSetFrameRangeLoader(api.Loader): "camera", "imagesequence", "yeticache", - "pointcache"] + "pointcache", + "render"] representations = ["*"] label = "Set frame range" @@ -45,7 +46,8 @@ class FusionSetFrameRangeWithHandlesLoader(api.Loader): "camera", "imagesequence", "yeticache", - "pointcache"] + "pointcache", + "render"] representations = ["*"] label = "Set frame range (with handles)" diff --git a/openpype/hosts/fusion/plugins/load/load_sequence.py b/openpype/hosts/fusion/plugins/load/load_sequence.py index 667d50ed45..5d9cad61bb 100644 --- a/openpype/hosts/fusion/plugins/load/load_sequence.py +++ b/openpype/hosts/fusion/plugins/load/load_sequence.py @@ -120,7 +120,7 @@ def loader_shift(loader, frame, relative=True): class FusionLoadSequence(api.Loader): """Load image sequence into Fusion""" - families = ["imagesequence", "review"] + families = ["imagesequence", "review", "render"] representations = ["*"] label = "Load sequence" From 4f9699fa000ceaba0679e5491e26419cac65d8f4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 15:16:53 +0100 Subject: [PATCH 051/109] Fix loader update --- openpype/hosts/fusion/plugins/load/load_sequence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/load/load_sequence.py b/openpype/hosts/fusion/plugins/load/load_sequence.py index 5d9cad61bb..ea118585bf 100644 --- a/openpype/hosts/fusion/plugins/load/load_sequence.py +++ b/openpype/hosts/fusion/plugins/load/load_sequence.py @@ -204,7 +204,7 @@ class FusionLoadSequence(api.Loader): assert tool.ID == "Loader", "Must be Loader" comp = tool.Comp() - root = api.get_representation_path(representation) + root = os.path.dirname(api.get_representation_path(representation)) path = self._get_first_image(root) # Get start frame from version data From 379b93e47d83343fc2bc75deed50cc1b4e6ceeb3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 15:20:55 +0100 Subject: [PATCH 052/109] Rename "Inventory..." to "Manage..." to align with other hosts --- openpype/hosts/fusion/api/menu.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/api/menu.py b/openpype/hosts/fusion/api/menu.py index 11b6c2e273..6234322d7f 100644 --- a/openpype/hosts/fusion/api/menu.py +++ b/openpype/hosts/fusion/api/menu.py @@ -59,7 +59,7 @@ class OpenPypeMenu(QtWidgets.QWidget): create_btn = QtWidgets.QPushButton("Create...", self) publish_btn = QtWidgets.QPushButton("Publish...", self) load_btn = QtWidgets.QPushButton("Load...", self) - inventory_btn = QtWidgets.QPushButton("Inventory...", self) + manager_btn = QtWidgets.QPushButton("Manage...", self) libload_btn = QtWidgets.QPushButton("Library...", self) rendermode_btn = QtWidgets.QPushButton("Set render mode...", self) duplicate_with_inputs_btn = QtWidgets.QPushButton( @@ -76,7 +76,7 @@ class OpenPypeMenu(QtWidgets.QWidget): layout.addWidget(create_btn) layout.addWidget(publish_btn) layout.addWidget(load_btn) - layout.addWidget(inventory_btn) + layout.addWidget(manager_btn) layout.addWidget(Spacer(15, self)) @@ -97,7 +97,7 @@ class OpenPypeMenu(QtWidgets.QWidget): create_btn.clicked.connect(self.on_create_clicked) publish_btn.clicked.connect(self.on_publish_clicked) load_btn.clicked.connect(self.on_load_clicked) - inventory_btn.clicked.connect(self.on_inventory_clicked) + manager_btn.clicked.connect(self.on_manager_clicked) libload_btn.clicked.connect(self.on_libload_clicked) rendermode_btn.clicked.connect(self.on_rendernode_clicked) duplicate_with_inputs_btn.clicked.connect( @@ -120,8 +120,8 @@ class OpenPypeMenu(QtWidgets.QWidget): print("Clicked Load") host_tools.show_loader(use_context=True) - def on_inventory_clicked(self): - print("Clicked Inventory") + def on_manager_clicked(self): + print("Clicked Manager") host_tools.show_scene_inventory() def on_libload_clicked(self): From dba50e9fb0fb2783eef1354ecc24acc500810bd9 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 16:02:47 +0100 Subject: [PATCH 053/109] Update Documentation: remove Deadline Event Plug-in --- vendor/deadline/readme.md | 39 ++++++++---------- .../docs/assets/deadline_configure_event.png | Bin 30673 -> 0 bytes website/docs/module_deadline.md | 30 +++++--------- 3 files changed, 28 insertions(+), 41 deletions(-) delete mode 100644 website/docs/assets/deadline_configure_event.png diff --git a/vendor/deadline/readme.md b/vendor/deadline/readme.md index 803a290050..31ffffd0b7 100644 --- a/vendor/deadline/readme.md +++ b/vendor/deadline/readme.md @@ -1,32 +1,29 @@ ## OpenPype Deadline repository overlay - This directory is overlay for Deadline repository. - It means that you can copy whole hierarchy to Deadline repository and it should work. + This directory is an overlay for Deadline repository. + It means that you can copy the whole hierarchy to Deadline repository and it + should work. Logic: ----- - Event - ----- - For each rendering job OpenPype event is triggered, it stores path to OpenPype - executable (needs to be configured on `Deadline's Configure Events > OpenPype`) - job's extra key 'openpype_executables'. + GlobalJobPreLoad + ----- - This value is used by `GlobalJobPreLoad` to call that executable to pull - environment's variables which are needed to add to ALL plugins process environments. - These env. vars are injected into rendering process. - - Event is necessary here as a middle man to allow configuring location of executable - which is ONLY then used by `GlobalJobPreLoad` (which doesnt have any user facing - configuration at all). - - `GlobalJobPreLoad` is triggered before each job, it contains backward compatible - logic to not modify old Pype2 or not OpenPype triggered jobs. +The `GlobalJobPreLoad` will retrieve the OpenPype executable path from the +`OpenPype` Deadline Plug-in's settings. Then it will call the executable to +retrieve the environment variables needed for the Deadline Job. +These environment variables are injected into rendering process. + +Deadline triggers the `GlobalJobPreLoad.py` for each Worker as it starts the +Job. + +*Note*: It also contains backward compatible logic to preserve functionality +for old Pype2 and non-OpenPype triggered jobs. Plugin ------ - For each publishing job `OpenPypeDeadlinePlugin` is called, which calls - configured location of OpenPype executable (needs to be configured in - `Deadline's Configure Plugins > OpenPype`) - and triggers command. + For each render and publishing job the `OpenPype` Deadline Plug-in is checked + for the configured location of the OpenPype executable (needs to be configured + in `Deadline's Configure Plugins > OpenPype`) through `GlobalJobPreLoad`. diff --git a/website/docs/assets/deadline_configure_event.png b/website/docs/assets/deadline_configure_event.png deleted file mode 100644 index 537a18506c93bf49942469c4ed4c2d167e5f45fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30673 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

kR0=@N`HiAS=|hwq^ADTzz}-h9c~? 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 Super User Mode` in Deadline Monitor -- Go to `Tools > Configure plugins`, find `OpenPype` in the list on the left side, find location of OpenPype +- Go to `Tools > Configure Plugins...`, find `OpenPype` in the list on the left side, find location of OpenPype executable. It is recommended to use the `openpype_console` executable as it provides a bit more logging. -- In case of multi OS farms, provide multiple locations, each node goes through a list and tries to find accessible - locations for itself. +- In case of multi OS farms, provide multiple locations, each node goes through a list and tries to find the first accessible + location for itself. ![Configure plugin](assets/deadline_configure_plugin.png) -- Go to `Tools > Configure events`, find `OpenPype` in the list on the left side, find location of OpenPype -executable. It is recommended to use the `openpype_console` executable as it provides a bit more logging. - -- State is expected to be set to `Global Enabled` - -![Configure event](assets/deadline_configure_event.png) - -Path to executables needs to be configured on both, plugin and event level! - ## Troubleshooting #### Publishing jobs fail directly in DCCs @@ -67,7 +57,7 @@ Each publishing from OpenPype consists of 2 jobs, first one is rendering, second - Jobs are failing with `OpenPype executable was not found` error - Check if OpenPype is installed on a node handling this job, plugin and events are properly [configured](#configuration) + Check if OpenPype is installed on the Worker handling this job and ensure `OpenPype` Deadline Plug-in is properly [configured](#configuration) - Publishing job is failing with `ffmpeg not installed` error From bb88f5e8049aa0d34d474d54b673efb1f791ba61 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 14 Feb 2022 17:41:52 +0100 Subject: [PATCH 054/109] removed 'use_python_2' from fusion settings schema --- .../system_settings/applications.json | 23 ++++++++++++------- .../host_settings/schema_fusion.json | 5 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index bfa1bd5cdc..593fab7034 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -691,7 +691,6 @@ }, "variants": { "17": { - "use_python_2": false, "executables": { "windows": [ "C:\\Program Files\\Blackmagic Design\\Fusion 17\\Fusion.exe" @@ -707,7 +706,6 @@ "environment": {} }, "16": { - "use_python_2": false, "executables": { "windows": [ "C:\\Program Files\\Blackmagic Design\\Fusion 16\\Fusion.exe" @@ -723,7 +721,6 @@ "environment": {} }, "9": { - "use_python_2": false, "executables": { "windows": [ "C:\\Program Files\\Blackmagic Design\\Fusion 9\\Fusion.exe" @@ -952,8 +949,12 @@ "enabled": true, "variant_label": "21", "executables": { - "windows": ["c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 21 Premium\\win64\\bin\\HarmonyPremium.exe"], - "darwin": ["/Applications/Toon Boom Harmony 21 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium"], + "windows": [ + "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 21 Premium\\win64\\bin\\HarmonyPremium.exe" + ], + "darwin": [ + "/Applications/Toon Boom Harmony 21 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" + ], "linux": [] }, "arguments": { @@ -967,8 +968,12 @@ "enabled": true, "variant_label": "20", "executables": { - "windows": ["c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 20 Premium\\win64\\bin\\HarmonyPremium.exe"], - "darwin": ["/Applications/Toon Boom Harmony 20 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium"], + "windows": [ + "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 20 Premium\\win64\\bin\\HarmonyPremium.exe" + ], + "darwin": [ + "/Applications/Toon Boom Harmony 20 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" + ], "linux": [] }, "arguments": { @@ -982,7 +987,9 @@ "enabled": true, "variant_label": "17", "executables": { - "windows": ["c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 17 Premium\\win64\\bin\\HarmonyPremium.exe"], + "windows": [ + "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 17 Premium\\win64\\bin\\HarmonyPremium.exe" + ], "darwin": [ "/Applications/Toon Boom Harmony 17 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" ], diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json index f62b439536..5960da7774 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_fusion.json @@ -30,10 +30,11 @@ "children": [ { "type": "schema_template", - "name": "template_host_variant_items" + "name": "template_host_variant_items", + "skip_paths": ["use_python_2"] } ] } } ] -} \ No newline at end of file +} From 84a711dd7a3167fd573526dd341caf77038a593e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 14 Feb 2022 18:00:30 +0100 Subject: [PATCH 055/109] flame: load containerized postponed to next dev --- openpype/hosts/flame/plugins/load/load_clip.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index 23598cdb27..c0c6bf95c3 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -3,7 +3,6 @@ import flame from pprint import pformat import openpype.hosts.flame.api as opfapi - class LoadClip(opfapi.ClipLoader): """Load a subset to timeline as clip @@ -97,13 +96,16 @@ class LoadClip(opfapi.ClipLoader): "objectName": clip_name }) - opc_segment = opfapi.get_clip_segment(opc) + # TODO: finish the containerisation + # opc_segment = opfapi.get_clip_segment(opc) - return opfapi.containerise( - opc_segment, - name, namespace, context, - self.__class__.__name__, - data_imprint) + # return opfapi.containerise( + # opc_segment, + # name, namespace, context, + # self.__class__.__name__, + # data_imprint) + + return opc def _get_clip(self, name, clip_path): reel = self._get_reel() From 9873b46faa9cc49691a7823ffa6231b8878665f8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 14 Feb 2022 19:01:05 +0100 Subject: [PATCH 056/109] check env values properly --- .../hosts/fusion/hooks/pre_fusion_setup.py | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/fusion/hooks/pre_fusion_setup.py b/openpype/hosts/fusion/hooks/pre_fusion_setup.py index b104b3c081..e635a0ea74 100644 --- a/openpype/hosts/fusion/hooks/pre_fusion_setup.py +++ b/openpype/hosts/fusion/hooks/pre_fusion_setup.py @@ -14,27 +14,40 @@ class FusionPrelaunch(PreLaunchHook): def execute(self): # making sure python 3.6 is installed at provided path - py36_dir = os.path.normpath(self.launch_context.env.get("PYTHON36", "")) + py36_dir = self.launch_context.env.get("PYTHON36") + if not py36_dir: + raise ApplicationLaunchFailed( + "Required environment variable \"PYTHON36\" is not set." + "\n\nFusion implementation requires to have" + " installed Python 3.6" + ) + + py36_dir = os.path.normpath(py36_dir) if not os.path.isdir(py36_dir): raise ApplicationLaunchFailed( "Python 3.6 is not installed at the provided path.\n" - "Either make sure the 'environments/fusion.json' has " - "'PYTHON36' set corectly or make sure Python 3.6 is installed " - f"in the given path.\n\nPYTHON36: {py36_dir}" + "Either make sure the environments in fusion settings has" + " 'PYTHON36' set corectly or make sure Python 3.6 is installed" + f" in the given path.\n\nPYTHON36: {py36_dir}" ) self.log.info(f"Path to Fusion Python folder: '{py36_dir}'...") self.launch_context.env["PYTHON36"] = py36_dir + utility_dir = self.launch_context.env.get("FUSION_UTILITY_SCRIPTS_DIR") + if not utility_dir: + raise ApplicationLaunchFailed( + "Required Fusion utility script dir environment variable" + " \"FUSION_UTILITY_SCRIPTS_DIR\" is not set." + ) + # setting utility scripts dir for scripts syncing - us_dir = os.path.normpath( - self.launch_context.env.get("FUSION_UTILITY_SCRIPTS_DIR", "") - ) - if not os.path.isdir(us_dir): + utility_dir = os.path.normpath(utility_dir) + if not os.path.isdir(utility_dir): raise ApplicationLaunchFailed( "Fusion utility script dir does not exist. Either make sure " - "the 'environments/fusion.json' has " - "'FUSION_UTILITY_SCRIPTS_DIR' set correctly or reinstall " - f"Fusion.\n\nFUSION_UTILITY_SCRIPTS_DIR: '{us_dir}'" + "the environments in fusion settings has" + " 'FUSION_UTILITY_SCRIPTS_DIR' set correctly or reinstall " + f"Fusion.\n\nFUSION_UTILITY_SCRIPTS_DIR: '{utility_dir}'" ) self._sync_utility_scripts(self.launch_context.env) From ad68db50a59cab5e65282a0e3f3cd75a903bda91 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 14 Feb 2022 20:29:10 +0100 Subject: [PATCH 057/109] Improve formatting --- website/docs/module_deadline.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/website/docs/module_deadline.md b/website/docs/module_deadline.md index ed28ee4b3a..32dbcfa6df 100644 --- a/website/docs/module_deadline.md +++ b/website/docs/module_deadline.md @@ -25,8 +25,12 @@ For [AWS Thinkbox Deadline](https://www.awsthinkbox.com/deadline) support you ne ## Configuration -OpenPype integration with Deadline consists of two parts, an `OpenPype` Deadline Plug-in a `GlobalJobPreLoad` script that gets triggered for each job and - handles populating render and publish jobs with proper environment variables. +OpenPype integration for Deadline consists of two parts: + +- The `OpenPype` Deadline Plug-in +- A `GlobalJobPreLoad` Deadline Script (this gets triggered for each deadline job) + +The `GlobalJobPreLoad` handles populating render and publish jobs with proper environment variables using settings from the `OpenPype` Deadline Plug-in. The `OpenPype` Deadline Plug-in must be configured to point to a valid OpenPype executable location. The executable need to be installed to destinations accessible by DL process. Check permissions (must be executable and accessible by Deadline process) @@ -36,7 +40,7 @@ destinations accessible by DL process. Check permissions (must be executable and - Go to `Tools > Configure Plugins...`, find `OpenPype` in the list on the left side, find location of OpenPype executable. It is recommended to use the `openpype_console` executable as it provides a bit more logging. -- In case of multi OS farms, provide multiple locations, each node goes through a list and tries to find the first accessible +- In case of multi OS farms, provide multiple locations, each Deadline Worker goes through the list and tries to find the first accessible location for itself. ![Configure plugin](assets/deadline_configure_plugin.png) From d5092340667fa08c674bb8e8877cbfeb14e54ed4 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 15 Feb 2022 15:29:40 +0100 Subject: [PATCH 058/109] OP-2646 - fix for proper parsing of ffmpeg output arguments Previous implementation was too simple, values that contained flags anywhere inside were triggering it. --- openpype/plugins/publish/extract_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index d223c31291..5f286a53e6 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -694,13 +694,13 @@ class ExtractReview(pyblish.api.InstancePlugin): audio_args_dentifiers = ["-af", "-filter:a"] for arg in tuple(output_args): for identifier in video_args_dentifiers: - if identifier in arg: + if arg.startswith("{} ".format(identifier)): output_args.remove(arg) arg = arg.replace(identifier, "").strip() video_filters.append(arg) for identifier in audio_args_dentifiers: - if identifier in arg: + if arg.startswith("{} ".format(identifier)): output_args.remove(arg) arg = arg.replace(identifier, "").strip() audio_filters.append(arg) From b292438e2b8d36852b459a834740fa8d2056c335 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 15 Feb 2022 16:17:11 +0100 Subject: [PATCH 059/109] OP-2646 - added barebone unit test for ffmpeg_full_args_filters --- .../plugins/publish/test_extract_review.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/unit/openpype/plugins/publish/test_extract_review.py diff --git a/tests/unit/openpype/plugins/publish/test_extract_review.py b/tests/unit/openpype/plugins/publish/test_extract_review.py new file mode 100644 index 0000000000..0a48d3d059 --- /dev/null +++ b/tests/unit/openpype/plugins/publish/test_extract_review.py @@ -0,0 +1,30 @@ +from openpype.plugins.publish.extract_review import ExtractReview + + +def test_fix_ffmpeg_full_args_filters(): + """Tests because of wrong resolution of audio filters.""" + plugin = ExtractReview() + output_arg = "c:/test-afbdc" + ret = plugin.ffmpeg_full_args([], [], [], [output_arg]) + assert len(ret) == 2, "Parsed wrong" + assert ret[-1] == output_arg + + ret = plugin.ffmpeg_full_args([], [], ["adeclick"], [output_arg]) + assert len(ret) == 4, "Parsed wrong" + assert ret[-1] == output_arg + assert ret[-2] == '"adeclick"' + assert ret[-3] == "-filter:a" + + ret = plugin.ffmpeg_full_args([], [], [], [output_arg, "-af adeclick"]) + assert len(ret) == 4, "Parsed wrong" + assert ret[-1] == output_arg + assert ret[-2] == '"adeclick"' + assert ret[-3] == "-filter:a" + + ret = plugin.ffmpeg_full_args([], [], ["adeclick"], + [output_arg, "-af adeclick"]) + assert len(ret) == 4, "Parsed wrong" + assert ret[-1] == output_arg + assert ret[-2] == '"adeclick,addeclick"' # TODO fix this duplication + assert ret[-3] == "-filter:a" + From 21784799c318cf339fbbd8fea7ed1cd4dae3a921 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 15 Feb 2022 16:19:00 +0100 Subject: [PATCH 060/109] OP-2646 - modified readme --- tests/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/README.md b/tests/README.md index d0578f8059..6fb86cd027 100644 --- a/tests/README.md +++ b/tests/README.md @@ -12,8 +12,6 @@ Structure: How to run: ---------- -- single test class could be run by PyCharm and its pytest runner directly -- OR - use Openpype command 'runtests' from command line (`.venv` in ${OPENPYPE_ROOT} must be activated to use configured Python!) -- `${OPENPYPE_ROOT}/python start.py runtests` From 260257089c86cfd457e4564b1ae647b670194798 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 15 Feb 2022 16:26:17 +0100 Subject: [PATCH 061/109] OP-2646 - Hound --- tests/unit/openpype/plugins/publish/test_extract_review.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unit/openpype/plugins/publish/test_extract_review.py b/tests/unit/openpype/plugins/publish/test_extract_review.py index 0a48d3d059..48317f0eb9 100644 --- a/tests/unit/openpype/plugins/publish/test_extract_review.py +++ b/tests/unit/openpype/plugins/publish/test_extract_review.py @@ -25,6 +25,5 @@ def test_fix_ffmpeg_full_args_filters(): [output_arg, "-af adeclick"]) assert len(ret) == 4, "Parsed wrong" assert ret[-1] == output_arg - assert ret[-2] == '"adeclick,addeclick"' # TODO fix this duplication + assert ret[-2] == '"adeclick,adeclick"' # TODO fix this duplication assert ret[-3] == "-filter:a" - From 30b8908d6bf105fbd77133087cb0273f3d0c279b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 15 Feb 2022 18:13:41 +0100 Subject: [PATCH 062/109] fix selected items --- openpype/tools/loader/app.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 1d5dee21f3..2443489f3c 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -1,4 +1,5 @@ import sys +import collections from Qt import QtWidgets, QtCore from avalon import api, io, pipeline @@ -378,15 +379,19 @@ class LoaderWindow(QtWidgets.QDialog): version_docs = [] if rows: + items = collections.deque() for index in rows: if not index or not index.isValid(): continue item = index.data(subsets.model.ItemRole) - if item is None: - continue + if item is not None: + items.append(item) + + while items: + item = items.popleft() if item.get("isGroup") or item.get("isMerged"): for child in item.children(): - version_docs.append(child["version_document"]) + items.append(child) else: version_docs.append(item["version_document"]) From 83b19949f960112fcbb4f676a7d2c2e635a8dfe6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 15 Feb 2022 18:14:19 +0100 Subject: [PATCH 063/109] added ability to get selected items under group item --- openpype/tools/loader/lib.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/openpype/tools/loader/lib.py b/openpype/tools/loader/lib.py index 8f18c01913..857b40faf7 100644 --- a/openpype/tools/loader/lib.py +++ b/openpype/tools/loader/lib.py @@ -1,4 +1,5 @@ import inspect +import collections from Qt import QtGui from avalon.vendor import qtawesome @@ -19,23 +20,21 @@ def change_visibility(model, view, column_name, visible): def get_selected_items(rows, item_role): - items = [] + output = [] + items = collections.deque() for row_index in rows: item = row_index.data(item_role) - if item.get("isGroup"): - continue - - elif item.get("isMerged"): - for idx in range(row_index.model().rowCount(row_index)): - child_index = row_index.child(idx, 0) - item = child_index.data(item_role) - if item not in items: - items.append(item) + items.append(item) + while items: + item = items.popleft() + if item.get("isGroup") or item.get("isMerged"): + for child in item.children(): + items.append(child) else: - if item not in items: - items.append(item) - return items + if item not in output: + output.append(item) + return output def get_options(action, loader, parent, repre_contexts): From cd6dc59f1440104868deb09908d1796f19752515 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 15 Feb 2022 18:14:48 +0100 Subject: [PATCH 064/109] asset underline colors can be cleared again --- openpype/tools/loader/app.py | 5 ++--- openpype/tools/loader/model.py | 15 ++++++--------- openpype/tools/utils/assets_widget.py | 13 ++++++++----- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 2443489f3c..619dcbcb06 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -288,9 +288,7 @@ class LoaderWindow(QtWidgets.QDialog): on selection change so they match current selection. """ # TODO do not touch inner attributes of asset widget - last_asset_ids = self.data["state"]["assetIds"] - if last_asset_ids: - self._assets_widget.clear_underlines() + self._assets_widget.clear_underlines() def _assetschanged(self): """Selected assets have changed""" @@ -329,6 +327,7 @@ class LoaderWindow(QtWidgets.QDialog): asset_ids = self.data["state"]["assetIds"] # Skip setting colors if not asset multiselection if not asset_ids or len(asset_ids) < 2: + self.clear_assets_underlines() self._versionschanged() return diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 96a52fce97..1f9223f596 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -524,9 +524,13 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): return self._fill_subset_items( - asset_docs_by_id, subset_docs_by_id, last_versions_by_subset_id, + asset_docs_by_id, + subset_docs_by_id, + last_versions_by_subset_id, repre_info_by_version_id ) + self.endResetModel() + self.refreshed.emit(True) def create_multiasset_group( self, subset_name, asset_ids, subset_counter, parent_item=None @@ -538,7 +542,6 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): merge_group.update({ "subset": "{} ({})".format(subset_name, len(asset_ids)), "isMerged": True, - "childRow": 0, "subsetColor": subset_color, "assetIds": list(asset_ids), "icon": qtawesome.icon( @@ -547,7 +550,6 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): ) }) - subset_counter += 1 self.add_child(merge_group, parent_item) return merge_group @@ -567,8 +569,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): group_item = Item() group_item.update({ "subset": group_name, - "isGroup": True, - "childRow": 0 + "isGroup": True }) group_item.update(group_data) @@ -666,9 +667,6 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): index = self.index(item.row(), 0, parent_index) self.set_version(index, last_version) - self.endResetModel() - self.refreshed.emit(True) - def data(self, index, role): if not index.isValid(): return @@ -1139,7 +1137,6 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): "_id": doc["_id"], "name": doc["name"], "isMerged": True, - "childRow": 0, "active_site_name": self.active_site, "remote_site_name": self.remote_site, "icon": qtawesome.icon( diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index 55e34285fc..be9f442d10 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -303,7 +303,7 @@ class AssetModel(QtGui.QStandardItemModel): self._doc_fetched.connect(self._on_docs_fetched) - self._items_with_color_by_id = {} + self._item_ids_with_color = set() self._items_by_asset_id = {} self._last_project_name = None @@ -382,9 +382,11 @@ class AssetModel(QtGui.QStandardItemModel): self._stop_fetch_thread() def clear_underlines(self): - for asset_id in tuple(self._items_with_color_by_id.keys()): - item = self._items_with_color_by_id.pop(asset_id) - item.setData(None, ASSET_UNDERLINE_COLORS_ROLE) + for asset_id in set(self._item_ids_with_color): + self._item_ids_with_color.remove(asset_id) + item = self._items_by_asset_id.get(asset_id) + if item is not None: + item.setData(None, ASSET_UNDERLINE_COLORS_ROLE) def set_underline_colors(self, colors_by_asset_id): self.clear_underlines() @@ -394,12 +396,13 @@ class AssetModel(QtGui.QStandardItemModel): if item is None: continue item.setData(colors, ASSET_UNDERLINE_COLORS_ROLE) + self._item_ids_with_color.add(asset_id) def _clear_items(self): root_item = self.invisibleRootItem() root_item.removeRows(0, root_item.rowCount()) self._items_by_asset_id = {} - self._items_with_color_by_id = {} + self._item_ids_with_color = set() def _on_docs_fetched(self): # Make sure refreshing did not change From a78242f673f0dac334cd565a24f44cfa07a9c43f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 09:04:40 +0100 Subject: [PATCH 065/109] Disable ftrack module by default --- openpype/settings/defaults/system_settings/modules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/modules.json b/openpype/settings/defaults/system_settings/modules.json index b31dd6856c..d74269922f 100644 --- a/openpype/settings/defaults/system_settings/modules.json +++ b/openpype/settings/defaults/system_settings/modules.json @@ -13,7 +13,7 @@ } }, "ftrack": { - "enabled": true, + "enabled": false, "ftrack_server": "", "ftrack_actions_path": { "windows": [], From 67e75121fc50baf7cc28946d6bc5073f151561b7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 09:18:50 +0100 Subject: [PATCH 066/109] Deadline: set job/batch name to original source workfile name instead of published workfile --- .../deadline/plugins/publish/submit_maya_deadline.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py index a87c0c374a..15a6f8d828 100644 --- a/openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py @@ -404,7 +404,13 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): dirname = os.path.join(workspace, default_render_file) renderlayer = instance.data['setMembers'] # rs_beauty deadline_user = context.data.get("user", getpass.getuser()) - jobname = "%s - %s" % (filename, instance.name) + + # Always use the original work file name for the Job name even when + # rendering is done from the published Work File. The original work + # file name is clearer because it can also have subversion strings, + # etc. which are stripped for the published file. + src_filename = os.path.basename(context.data["currentFile"]) + jobname = "%s - %s" % (src_filename, instance.name) # Get the variables depending on the renderer render_variables = get_renderer_variables(renderlayer, dirname) @@ -452,7 +458,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): self.payload_skeleton["JobInfo"]["Plugin"] = self._instance.data.get( "mayaRenderPlugin", "MayaBatch") - self.payload_skeleton["JobInfo"]["BatchName"] = filename + self.payload_skeleton["JobInfo"]["BatchName"] = src_filename # Job name, as seen in Monitor self.payload_skeleton["JobInfo"]["Name"] = jobname # Arbitrary username, for visualisation in Monitor From 19bfb53ad9455a8276e6ddeea3b29a3145e94982 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Feb 2022 10:38:05 +0100 Subject: [PATCH 067/109] don't use ItemRole in loader --- openpype/tools/libraryloader/app.py | 39 +++--------- openpype/tools/loader/app.py | 56 +++--------------- openpype/tools/loader/lib.py | 18 ------ openpype/tools/loader/model.py | 19 +++++- openpype/tools/loader/widgets.py | 92 ++++++++++++++++++----------- 5 files changed, 92 insertions(+), 132 deletions(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index d030aa903d..9f8845f30f 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -396,9 +396,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog): self._versionschanged() return - selected_subsets = self._subsets_widget.selected_subsets( - _merged=True, _other=False - ) + selected_subsets = self._subsets_widget.get_selected_merge_items() asset_colors = {} asset_ids = [] @@ -423,35 +421,14 @@ class LibraryLoaderWindow(QtWidgets.QDialog): self._versionschanged() def _versionschanged(self): - selection = self._subsets_widget.view.selectionModel() - - # Active must be in the selected rows otherwise we - # assume it's not actually an "active" current index. - version_docs = None + items = self._subsets_widget.get_selected_subsets() version_doc = None - active = selection.currentIndex() - rows = selection.selectedRows(column=active.column()) - if active and active in rows: - item = active.data(self._subsets_widget.model.ItemRole) - if ( - item is not None - and not (item.get("isGroup") or item.get("isMerged")) - ): - version_doc = item["version_document"] - - if rows: - version_docs = [] - for index in rows: - if not index or not index.isValid(): - continue - item = index.data(self._subsets_widget.model.ItemRole) - if ( - item is None - or item.get("isGroup") - or item.get("isMerged") - ): - continue - version_docs.append(item["version_document"]) + version_docs = [] + for item in items: + doc = item["version_document"] + version_docs.append(doc) + if version_doc is None: + version_doc = doc self._version_info_widget.set_version(version_doc) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 619dcbcb06..6f67f0c641 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -331,9 +331,7 @@ class LoaderWindow(QtWidgets.QDialog): self._versionschanged() return - selected_subsets = self._subsets_widget.selected_subsets( - _merged=True, _other=False - ) + selected_subsets = self._subsets_widget.get_selected_merge_items() asset_colors = {} asset_ids = [] @@ -358,41 +356,16 @@ class LoaderWindow(QtWidgets.QDialog): self._versionschanged() def _versionschanged(self): - subsets = self._subsets_widget - selection = subsets.view.selectionModel() - - # Active must be in the selected rows otherwise we - # assume it's not actually an "active" current index. + items = self._subsets_widget.get_selected_subsets() version_doc = None - active = selection.currentIndex() - rows = selection.selectedRows(column=active.column()) - if active: - if active in rows: - item = active.data(subsets.model.ItemRole) - if ( - item is not None and - not (item.get("isGroup") or item.get("isMerged")) - ): - version_doc = item["version_document"] - self._version_info_widget.set_version(version_doc) - version_docs = [] - if rows: - items = collections.deque() - for index in rows: - if not index or not index.isValid(): - continue - item = index.data(subsets.model.ItemRole) - if item is not None: - items.append(item) + for item in items: + doc = item["version_document"] + version_docs.append(doc) + if version_doc is None: + version_doc = doc - while items: - item = items.popleft() - if item.get("isGroup") or item.get("isMerged"): - for child in item.children(): - items.append(child) - else: - version_docs.append(item["version_document"]) + self._version_info_widget.set_version(version_doc) thumbnail_src_ids = [ version_doc["_id"] @@ -484,18 +457,7 @@ class LoaderWindow(QtWidgets.QDialog): self.echo("Grouping not enabled.") return - selected = [] - merged_items = [] - for item in subsets.selected_subsets(_merged=True): - if item.get("isMerged"): - merged_items.append(item) - else: - selected.append(item) - - for merged_item in merged_items: - for child_item in merged_item.children(): - selected.append(child_item) - + selected = self._subsets_widget.get_selected_subsets() if not selected: self.echo("No selected subset.") return diff --git a/openpype/tools/loader/lib.py b/openpype/tools/loader/lib.py index 857b40faf7..60e7672340 100644 --- a/openpype/tools/loader/lib.py +++ b/openpype/tools/loader/lib.py @@ -19,24 +19,6 @@ def change_visibility(model, view, column_name, visible): view.setColumnHidden(index, not visible) -def get_selected_items(rows, item_role): - output = [] - items = collections.deque() - for row_index in rows: - item = row_index.data(item_role) - items.append(item) - - while items: - item = items.popleft() - if item.get("isGroup") or item.get("isMerged"): - for child in item.children(): - items.append(child) - else: - if item not in output: - output.append(item) - return output - - def get_options(action, loader, parent, repre_contexts): """Provides dialog to select value from loader provided options. diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 1f9223f596..f34eb157ab 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -1,6 +1,7 @@ import copy import re import math +from uuid import uuid4 from avalon import ( style, @@ -22,6 +23,8 @@ from openpype.tools.utils.constants import ( REMOTE_AVAILABILITY_ROLE ) +ITEM_ID_ROLE = QtCore.Qt.UserRole + 90 + def is_filtering_recursible(): """Does Qt binding support recursive filtering for QSortFilterProxyModel? @@ -179,6 +182,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): self._icons = { "subset": qtawesome.icon("fa.file-o", color=style.colors.default) } + self._items_by_id = {} self._doc_fetching_thread = None self._doc_fetching_stop = False @@ -188,6 +192,15 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): self.refresh() + def get_item_by_id(self, item_id): + return self._items_by_id.get(item_id) + + def add_child(self, new_item, *args, **kwargs): + item_id = str(uuid4()) + new_item["id"] = item_id + self._items_by_id[item_id] = new_item + super(SubsetsModel, self).add_child(new_item, *args, **kwargs) + def set_assets(self, asset_ids): self._asset_ids = asset_ids self.refresh() @@ -486,7 +499,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): def refresh(self): self.stop_fetch_thread() self.clear() - + self._items_by_id = {} self.reset_sync_server() if not self._asset_ids: @@ -497,6 +510,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): def on_doc_fetched(self): self.clear() + self._items_by_id = {} self.beginResetModel() asset_docs_by_id = self._doc_payload.get( @@ -672,6 +686,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): return item = index.internalPointer() + if role == ITEM_ID_ROLE: + return item["id"] + if role == self.SortDescendingRole: if item.get("isGroup"): # Ensure groups be on top when sorting by descending order diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index ed130f765c..f60341af2f 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -34,7 +34,8 @@ from .model import ( SubsetFilterProxyModel, FamiliesFilterProxyModel, RepresentationModel, - RepresentationSortProxyModel + RepresentationSortProxyModel, + ITEM_ID_ROLE ) from . import lib @@ -351,6 +352,59 @@ class SubsetWidget(QtWidgets.QWidget): lib.change_visibility(self.model, self.view, "repre_info", enabled) + def get_selected_items(self): + selection_model = self.view.selectionModel() + indexes = selection_model.selectedIndexes() + + item_ids = set() + for index in indexes: + item_id = index.data(ITEM_ID_ROLE) + if item_id is not None: + item_ids.add(item_id) + + output = [] + for item_id in item_ids: + item = self.model.get_item_by_id(item_id) + if item is not None: + output.append(item) + return output + + def get_selected_merge_items(self): + output = [] + items = collections.deque(self.get_selected_items()) + + item_ids = set() + while items: + item = items.popleft() + if item.get("isGroup"): + for child in item.children(): + items.appendleft(child) + + elif item.get("isMerged"): + item_id = item["id"] + if item_id not in item_ids: + item_ids.add(item_id) + output.append(item) + + return output + + def get_selected_subsets(self): + output = [] + items = collections.deque(self.get_selected_items()) + + item_ids = set() + while items: + item = items.popleft() + if item.get("isGroup") or item.get("isMerged"): + for child in item.children(): + items.appendleft(child) + else: + item_id = item["id"] + if item_id not in item_ids: + item_ids.add(item_id) + output.append(item) + return output + def on_context_menu(self, point): """Shows menu with loader actions on Right-click. @@ -367,10 +421,7 @@ class SubsetWidget(QtWidgets.QWidget): return # Get selected subsets without groups - selection = self.view.selectionModel() - rows = selection.selectedRows(column=0) - - items = lib.get_selected_items(rows, self.model.ItemRole) + items = self.get_selected_subsets() # Get all representation->loader combinations available for the # index under the cursor, so we can list the user the options. @@ -539,35 +590,6 @@ class SubsetWidget(QtWidgets.QWidget): box = LoadErrorMessageBox(error_info, self) box.show() - def selected_subsets(self, _groups=False, _merged=False, _other=True): - selection = self.view.selectionModel() - rows = selection.selectedRows(column=0) - - subsets = list() - if not any([_groups, _merged, _other]): - self.echo(( - "This is a BUG: Selected_subsets args must contain" - " at least one value set to True" - )) - return subsets - - for row in rows: - item = row.data(self.model.ItemRole) - if item.get("isGroup"): - if not _groups: - continue - - elif item.get("isMerged"): - if not _merged: - continue - else: - if not _other: - continue - - subsets.append(item) - - return subsets - def group_subsets(self, name, asset_ids, items): field = "data.subsetGroup" @@ -1279,7 +1301,7 @@ class RepresentationWidget(QtWidgets.QWidget): selection = self.tree_view.selectionModel() rows = selection.selectedRows(column=0) - items = lib.get_selected_items(rows, self.model.ItemRole) + items = self.get_selected_subsets() selected_side = self._get_selected_side(point_index, rows) From 4748e111a2a15d88b68ac23b613555a9570e1dde Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Feb 2022 10:40:03 +0100 Subject: [PATCH 068/109] hound fixes --- openpype/tools/loader/app.py | 1 - openpype/tools/loader/lib.py | 1 - 2 files changed, 2 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 6f67f0c641..aa743b05fe 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -1,5 +1,4 @@ import sys -import collections from Qt import QtWidgets, QtCore from avalon import api, io, pipeline diff --git a/openpype/tools/loader/lib.py b/openpype/tools/loader/lib.py index 60e7672340..180dee3eb5 100644 --- a/openpype/tools/loader/lib.py +++ b/openpype/tools/loader/lib.py @@ -1,5 +1,4 @@ import inspect -import collections from Qt import QtGui from avalon.vendor import qtawesome From 72439dd4f6d6249fd38d781a18ad34a966354fd7 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 11:03:34 +0100 Subject: [PATCH 069/109] flame: simplification of module fail mechanism --- .../openpype_flame_to_ftrack/openpype_flame_to_ftrack.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py index 65c1840a72..5a72706ba1 100644 --- a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py +++ b/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py @@ -3,10 +3,9 @@ from __future__ import print_function import os import sys -try: - import six # noqa -except ImportError as msg: - raise ImportError("Cannot import this module: {}".format(msg)) from msg +# only testing dependency for nested modules in package +import six # noqa + SCRIPT_DIR = os.path.dirname(__file__) PACKAGE_DIR = os.path.join(SCRIPT_DIR, "modules") From 671c1563737ef2a87b4f9c20544af178a24e7e91 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 11:05:55 +0100 Subject: [PATCH 070/109] hound: suggestion --- openpype/hosts/flame/plugins/load/load_clip.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index c0c6bf95c3..8ba01d6937 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -3,6 +3,7 @@ import flame from pprint import pformat import openpype.hosts.flame.api as opfapi + class LoadClip(opfapi.ClipLoader): """Load a subset to timeline as clip From 3c6c2d207f922bbb49aa13673e12a568c97eacec Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 11:06:00 +0100 Subject: [PATCH 071/109] Preserve subversion comment with Work Files save --- openpype/tools/workfiles/app.py | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 40edec76bd..d23338b7ce 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -1,5 +1,6 @@ import sys import os +import re import copy import getpass import shutil @@ -177,6 +178,40 @@ class NameWindow(QtWidgets.QDialog): # Add subversion only if template contains `{comment}` if "{comment}" in self.template: inputs_layout.addRow("Subversion:", subversion_input) + + # Detect whether a {comment} is in the current filename - if so, + # preserve it by default and set it in the comment/subversion field + current_filepath = self.host.current_file() + if current_filepath: + + # Get current extension without the dot (.) + ext = os.path.splitext(current_filepath)[1][1:] + current_fname = os.path.basename(current_filepath) + temp_data = copy.deepcopy(self.data) + temp_data["ext"] = ext + + # Use placeholders that we can safely escape with regex + temp_data["comment"] = "<>" + temp_data["version"] = "<>" + + fname_pattern = self.anatomy.format(temp_data)["work"]["file"] + fname_pattern = re.escape(fname_pattern) + + # Replace comment and version with something we can match with + # regex + fname_pattern = fname_pattern.replace("<>", "(.+)") + fname_pattern = fname_pattern.replace("<>", "[0-9]+") + + # Match from beginning to end of string to be safe + fname_pattern = "^{}$".format(fname_pattern) + match = re.match(fname_pattern, current_fname) + + if match: + comment = match.group(1) + log.info("Detected subversion comment: {}".format(comment)) + self.data["comment"] = comment + subversion_input.setText(comment) + else: subversion_input.setVisible(False) inputs_layout.addRow("Extension:", ext_combo) From 4cc7d84cd41de71ab1734e7e1d43038bcbd856f5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 11:12:35 +0100 Subject: [PATCH 072/109] flame: removing redundant exception --- .../flame/plugins/publish/extract_subset_resources.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index d774b07fca..db85bede85 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -47,16 +47,6 @@ class ExtractSubsetResources(openpype.api.Extractor): export_presets_mapping = {} def process(self, instance): - try: - self._process(instance) - except Exception as msg: - self.log.error(msg) - finally: - # bring ui back - self.hide_ui_on_process = False - - def _process(self, instance): - if ( self.keep_original_representation and "representations" not in instance.data From 2c5338af843905e16952213196e44a15d5ecb21d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Feb 2022 11:17:09 +0100 Subject: [PATCH 073/109] make sure window is visible after plugin process --- openpype/tools/pyblish_pype/window.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/tools/pyblish_pype/window.py b/openpype/tools/pyblish_pype/window.py index 7bb11745d6..9c4d4b10f4 100644 --- a/openpype/tools/pyblish_pype/window.py +++ b/openpype/tools/pyblish_pype/window.py @@ -1039,6 +1039,8 @@ class Window(QtWidgets.QDialog): and not self.controller.stopped ) self.button_suspend_logs.setEnabled(suspend_log_bool) + if not self.isVisible(): + self.setVisible(True) def on_was_skipped(self, plugin): plugin_item = self.plugin_model.plugin_items[plugin.id] @@ -1112,6 +1114,9 @@ class Window(QtWidgets.QDialog): plugin_item, instance_item ) + if not self.isVisible(): + self.setVisible(True) + # ------------------------------------------------------------------------- # # Functions From 1e0c67c7bdccf65f6419ab3a3d9cca8380ba84f9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 11:18:51 +0100 Subject: [PATCH 074/109] removing yarn.lock accidentally commited --- yarn.lock | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd13a..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - From 4cf9c2afceb651a7323eb1e522f13223947a3974 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 11:23:55 +0100 Subject: [PATCH 075/109] Use correct template key which can be customized --- openpype/tools/workfiles/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index d23338b7ce..6c3af86225 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -194,7 +194,8 @@ class NameWindow(QtWidgets.QDialog): temp_data["comment"] = "<>" temp_data["version"] = "<>" - fname_pattern = self.anatomy.format(temp_data)["work"]["file"] + formatted = self.anatomy.format(temp_data) + fname_pattern = formatted[template_key]["file"] fname_pattern = re.escape(fname_pattern) # Replace comment and version with something we can match with From f4593b860f259082925033f90d28315e05fbb2d0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 12:22:44 +0100 Subject: [PATCH 076/109] Always match comment against current context - Also separate matching logic so we can easily re-use for a dropdown menu of existing subversion comments next to the input field --- openpype/tools/workfiles/app.py | 190 ++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 80 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 6c3af86225..df9befcde7 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -38,6 +38,109 @@ module = sys.modules[__name__] module.window = None +def build_workfile_data(session): + """Get the data required for workfile formatting from avalon `session`""" + + # Set work file data for template formatting + asset_name = session["AVALON_ASSET"] + task_name = session["AVALON_TASK"] + project_doc = io.find_one( + {"type": "project"}, + { + "name": True, + "data.code": True, + "config.tasks": True, + } + ) + + asset_doc = io.find_one( + { + "type": "asset", + "name": asset_name + }, + { + "data.tasks": True, + "data.parents": True + } + ) + + task_type = asset_doc["data"]["tasks"].get(task_name, {}).get("type") + + project_task_types = project_doc["config"]["tasks"] + task_short = project_task_types.get(task_type, {}).get("short_name") + + asset_parents = asset_doc["data"]["parents"] + parent_name = project_doc["name"] + if asset_parents: + parent_name = asset_parents[-1] + + data = { + "project": { + "name": project_doc["name"], + "code": project_doc["data"].get("code") + }, + "asset": asset_name, + "task": { + "name": task_name, + "type": task_type, + "short": task_short, + }, + "parent": parent_name, + "version": 1, + "user": getpass.getuser(), + "comment": "", + "ext": None + } + + # add system general settings anatomy data + system_general_data = get_system_general_anatomy_data() + data.update(system_general_data) + + return data + + +class CommentMatcher(object): + """Use anatomy and work file data to parse comments from filenames""" + def __init__(self, anatomy, template_key, data): + + self.anatomy = anatomy + self.template_key = template_key + self.template = self.anatomy.templates[template_key]["file"] + self.data = data + + def parse_comment(self, filepath): + """Parse the {comment} part from a filename""" + + if "{comment}" not in self.template: + # Don't look for comment if template doesn't allow it + return + + # Get current extension without the dot (.) + ext = os.path.splitext(filepath)[1][1:] + current_fname = os.path.basename(filepath) + temp_data = copy.deepcopy(self.data) + temp_data["ext"] = ext + + # Use placeholders that we can safely escape with regex + temp_data["comment"] = "<>" + temp_data["version"] = "<>" + + formatted = self.anatomy.format(temp_data) + fname_pattern = formatted[self.template_key]["file"] + fname_pattern = re.escape(fname_pattern) + + # Replace comment and version with something we can match with + # regex + fname_pattern = fname_pattern.replace("<>", "(.+)") + fname_pattern = fname_pattern.replace("<>", "[0-9]+") + + # Match from beginning to end of string to be safe + fname_pattern = "^{}$".format(fname_pattern) + match = re.match(fname_pattern, current_fname) + if match: + return match.group(1) + + class NameWindow(QtWidgets.QDialog): """Name Window to define a unique filename inside a root folder @@ -59,60 +162,7 @@ class NameWindow(QtWidgets.QDialog): # Fallback to active session session = api.Session - # Set work file data for template formatting - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - project_doc = io.find_one( - {"type": "project"}, - { - "name": True, - "data.code": True, - "config.tasks": True, - } - ) - - asset_doc = io.find_one( - { - "type": "asset", - "name": asset_name - }, - { - "data.tasks": True, - "data.parents": True - } - ) - - task_type = asset_doc["data"]["tasks"].get(task_name, {}).get("type") - - project_task_types = project_doc["config"]["tasks"] - task_short = project_task_types.get(task_type, {}).get("short_name") - - asset_parents = asset_doc["data"]["parents"] - parent_name = project_doc["name"] - if asset_parents: - parent_name = asset_parents[-1] - - self.data = { - "project": { - "name": project_doc["name"], - "code": project_doc["data"].get("code") - }, - "asset": asset_name, - "task": { - "name": task_name, - "type": task_type, - "short": task_short, - }, - "parent": parent_name, - "version": 1, - "user": getpass.getuser(), - "comment": "", - "ext": None - } - - # add system general settings anatomy data - system_general_data = get_system_general_anatomy_data() - self.data.update(system_general_data) + self.data = build_workfile_data(session) # Store project anatomy self.anatomy = anatomy @@ -183,32 +233,12 @@ class NameWindow(QtWidgets.QDialog): # preserve it by default and set it in the comment/subversion field current_filepath = self.host.current_file() if current_filepath: - - # Get current extension without the dot (.) - ext = os.path.splitext(current_filepath)[1][1:] - current_fname = os.path.basename(current_filepath) - temp_data = copy.deepcopy(self.data) - temp_data["ext"] = ext - - # Use placeholders that we can safely escape with regex - temp_data["comment"] = "<>" - temp_data["version"] = "<>" - - formatted = self.anatomy.format(temp_data) - fname_pattern = formatted[template_key]["file"] - fname_pattern = re.escape(fname_pattern) - - # Replace comment and version with something we can match with - # regex - fname_pattern = fname_pattern.replace("<>", "(.+)") - fname_pattern = fname_pattern.replace("<>", "[0-9]+") - - # Match from beginning to end of string to be safe - fname_pattern = "^{}$".format(fname_pattern) - match = re.match(fname_pattern, current_fname) - - if match: - comment = match.group(1) + # We match the current filename against the current session + # instead of the session where the user is saving to. + current_data = build_workfile_data(api.Session) + matcher = CommentMatcher(anatomy, template_key, current_data) + comment = matcher.parse_comment(current_filepath) + if comment: log.info("Detected subversion comment: {}".format(comment)) self.data["comment"] = comment subversion_input.setText(comment) From 18f8741224d06e6aee41c924a9ad7796810072cd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 13:03:01 +0100 Subject: [PATCH 077/109] Add drop-down next to subversion to choose from existing subversion comments - Also optimize parse_comment for many files --- openpype/tools/workfiles/app.py | 144 ++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 24 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index df9befcde7..785e87738f 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -103,44 +103,117 @@ class CommentMatcher(object): """Use anatomy and work file data to parse comments from filenames""" def __init__(self, anatomy, template_key, data): - self.anatomy = anatomy - self.template_key = template_key - self.template = self.anatomy.templates[template_key]["file"] - self.data = data + self.fname_regex = None - def parse_comment(self, filepath): - """Parse the {comment} part from a filename""" - - if "{comment}" not in self.template: + template = anatomy.templates[template_key]["file"] + if "{comment}" not in template: # Don't look for comment if template doesn't allow it return - # Get current extension without the dot (.) - ext = os.path.splitext(filepath)[1][1:] - current_fname = os.path.basename(filepath) - temp_data = copy.deepcopy(self.data) - temp_data["ext"] = ext + # Create a regex group for extensions + extensions = api.registered_host().file_extensions() + any_extension = "(?:{})".format( + "|".join(re.escape(ext[1:]) for ext in extensions) + ) # Use placeholders that we can safely escape with regex + temp_data = copy.deepcopy(data) temp_data["comment"] = "<>" temp_data["version"] = "<>" + temp_data["ext"] = "<>" - formatted = self.anatomy.format(temp_data) - fname_pattern = formatted[self.template_key]["file"] + formatted = anatomy.format(temp_data) + fname_pattern = formatted[template_key]["file"] fname_pattern = re.escape(fname_pattern) # Replace comment and version with something we can match with # regex fname_pattern = fname_pattern.replace("<>", "(.+)") fname_pattern = fname_pattern.replace("<>", "[0-9]+") + fname_pattern = fname_pattern.replace("<>", any_extension) # Match from beginning to end of string to be safe fname_pattern = "^{}$".format(fname_pattern) - match = re.match(fname_pattern, current_fname) + + self.fname_regex = re.compile(fname_pattern) + + def parse_comment(self, filepath): + """Parse the {comment} part from a filename""" + if not self.fname_regex: + return + + fname = os.path.basename(filepath) + match = self.fname_regex.match(fname) if match: return match.group(1) +class SubversionLineEdit(QtWidgets.QWidget): + """QLineEdit with QPushButton for drop down selection of list of strings""" + def __init__(self, parent=None): + super(SubversionLineEdit, self).__init__(parent=parent) + + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(3) + + self._input = PlaceholderLineEdit() + self._button = QtWidgets.QPushButton("") + self._button.setFixedWidth(18) + self._menu = QtWidgets.QMenu(self) + self._button.setMenu(self._menu) + + layout.addWidget(self._input) + layout.addWidget(self._button) + + @property + def input(self): + return self._input + + def set_values(self, values): + self._update(values) + + def _on_button_clicked(self): + self._menu.exec_() + + def _on_action_clicked(self, action): + self._input.setText(action.text()) + + def _update(self, values): + """Create optional predefined subset names + + Args: + default_names(list): all predefined names + + Returns: + None + """ + + menu = self._menu + button = self._button + + state = any(values) + button.setEnabled(state) + if state is False: + return + + # Include an empty string + values = [""] + sorted(values) + + # Get and destroy the action group + group = button.findChild(QtWidgets.QActionGroup) + if group: + group.deleteLater() + + # Build new action group + group = QtWidgets.QActionGroup(button) + for name in values: + action = group.addAction(name) + menu.addAction(action) + + group.triggered.connect(self._on_action_clicked) + + class NameWindow(QtWidgets.QDialog): """Name Window to define a unique filename inside a root folder @@ -205,8 +278,8 @@ class NameWindow(QtWidgets.QDialog): preview_label = QtWidgets.QLabel("Preview filename", inputs_widget) # Subversion input - subversion_input = PlaceholderLineEdit(inputs_widget) - subversion_input.setPlaceholderText("Will be part of filename.") + subversion = SubversionLineEdit(inputs_widget) + subversion.input.setPlaceholderText("Will be part of filename.") # Extensions combobox ext_combo = QtWidgets.QComboBox(inputs_widget) @@ -227,7 +300,7 @@ class NameWindow(QtWidgets.QDialog): # Add subversion only if template contains `{comment}` if "{comment}" in self.template: - inputs_layout.addRow("Subversion:", subversion_input) + inputs_layout.addRow("Subversion:", subversion) # Detect whether a {comment} is in the current filename - if so, # preserve it by default and set it in the comment/subversion field @@ -241,10 +314,13 @@ class NameWindow(QtWidgets.QDialog): if comment: log.info("Detected subversion comment: {}".format(comment)) self.data["comment"] = comment - subversion_input.setText(comment) + subversion.input.setText(comment) + + existing_comments = self.get_existing_comments() + subversion.set_values(existing_comments) else: - subversion_input.setVisible(False) + subversion.setVisible(False) inputs_layout.addRow("Extension:", ext_combo) inputs_layout.addRow("Preview:", preview_label) @@ -259,7 +335,7 @@ class NameWindow(QtWidgets.QDialog): self.on_version_checkbox_changed ) - subversion_input.textChanged.connect(self.on_comment_changed) + subversion.input.textChanged.connect(self.on_comment_changed) ext_combo.currentIndexChanged.connect(self.on_extension_changed) btn_ok.pressed.connect(self.on_ok_pressed) @@ -270,7 +346,7 @@ class NameWindow(QtWidgets.QDialog): # Force default focus to comment, some hosts didn't automatically # apply focus to this line edit (e.g. Houdini) - subversion_input.setFocus() + subversion.input.setFocus() # Store widgets self.btn_ok = btn_ok @@ -281,12 +357,32 @@ class NameWindow(QtWidgets.QDialog): self.last_version_check = last_version_check self.preview_label = preview_label - self.subversion_input = subversion_input + self.subversion = subversion self.ext_combo = ext_combo self._ext_delegate = ext_delegate self.refresh() + def get_existing_comments(self): + + matcher = CommentMatcher(self.anatomy, self.template_key, self.data) + host_extensions = set(self.host.file_extensions()) + comments = set() + if os.path.isdir(self.root): + for fname in os.listdir(self.root): + if not os.path.isfile(os.path.join(self.root, fname)): + continue + + ext = os.path.splitext(fname)[-1] + if ext not in host_extensions: + continue + + comment = matcher.parse_comment(fname) + if comment: + comments.add(comment) + + return list(comments) + def on_version_spinbox_changed(self, value): self.data["version"] = value self.refresh() From 1801249a4d890be50af90d527289bf9dc81c45be Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 14:54:31 +0100 Subject: [PATCH 078/109] Preserve parts of filename after version number (like subversion) on version_up --- openpype/lib/path_tools.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index c0b78c5724..d6c32ad9e8 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -51,12 +51,6 @@ def version_up(filepath): padding=padding) new_label = label.replace(version, new_version, 1) new_basename = _rreplace(basename, label, new_label) - - if not new_basename.endswith(new_label): - index = (new_basename.find(new_label)) - index += len(new_label) - new_basename = new_basename[:index] - new_filename = "{}{}".format(new_basename, ext) new_filename = os.path.join(dirname, new_filename) new_filename = os.path.normpath(new_filename) @@ -65,8 +59,19 @@ def version_up(filepath): raise RuntimeError("Created path is the same as current file," "this is a bug") + # We check for version clashes against the current file for any file + # that matches completely in name up to the {version} label found. Thus + # if source file was test_v001_test.txt we want to also check clashes + # against test_v002.txt but do want to preserve the part after the version + # label for our new filename + clash_basename = new_basename + if not clash_basename.endswith(new_label): + index = (clash_basename.find(new_label)) + index += len(new_label) + clash_basename = clash_basename[:index] + for file in os.listdir(dirname): - if file.endswith(ext) and file.startswith(new_basename): + if file.endswith(ext) and file.startswith(clash_basename): log.info("Skipping existing version %s" % new_label) return version_up(new_filename) From 64e971087968672b71329cbd3e33f67d6a637572 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 15:59:41 +0100 Subject: [PATCH 079/109] Flame: removing testing label improving launching with flame correct launcher. fixing umask issue --- openpype/settings/defaults/system_settings/applications.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 317ed061b4..f8a09d70e9 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -121,7 +121,7 @@ "/opt/Autodesk/flame_2021/bin/flame.app/Contents/MacOS/startApp" ], "linux": [ - "/opt/Autodesk/flame_2021/bin/flame" + "/opt/Autodesk/flame_2021/bin/startApplication" ] }, "arguments": { @@ -136,7 +136,7 @@ } }, "__dynamic_keys_labels__": { - "2021": "2021 (Testing Only)" + "2021": "2021" } } }, From a39e8c7de561ee7ec9ce64da73707975c66fc27f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:04:59 +0100 Subject: [PATCH 080/109] flame: adding version launcher 2021.1 --- .../system_settings/applications.json | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index f8a09d70e9..1d821cb4ea 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -135,8 +135,31 @@ "OPENPYPE_WIRETAP_TOOLS": "/opt/Autodesk/wiretap/tools/2021" } }, + "2021.1": { + "use_python_2": true, + "executables": { + "windows": [], + "darwin": [ + "/opt/Autodesk/flame_2021.1/bin/flame.app/Contents/MacOS/startApp" + ], + "linux": [ + "/opt/Autodesk/flame_2021.1/bin/startApplication" + ] + }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "OPENPYPE_FLAME_PYTHON_EXEC": "/opt/Autodesk/python/2021.1/bin/python2.7", + "OPENPYPE_FLAME_PYTHONPATH": "/opt/Autodesk/flame_2021.1/python", + "OPENPYPE_WIRETAP_TOOLS": "/opt/Autodesk/wiretap/tools/2021.1" + } + }, "__dynamic_keys_labels__": { - "2021": "2021" + "2021": "2021", + "2021.1": "2021.1" } } }, From 409e3ccb268ed1d1d05deb21a0696739be21492e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:26:39 +0100 Subject: [PATCH 081/109] Flame: settings for imageio --- .../defaults/project_anatomy/imageio.json | 17 ++++++ .../schemas/schema_anatomy_imageio.json | 52 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/openpype/settings/defaults/project_anatomy/imageio.json b/openpype/settings/defaults/project_anatomy/imageio.json index 09ab398c37..8a8eb8b5c5 100644 --- a/openpype/settings/defaults/project_anatomy/imageio.json +++ b/openpype/settings/defaults/project_anatomy/imageio.json @@ -186,5 +186,22 @@ "renderSpace": "scene-linear Rec 709/sRGB", "viewTransform": "sRGB gamma" } + }, + "flame": { + "project": { + "colourPolicy": "ACES 1.1" + }, + "profilesMapping": { + "inputs": [ + { + "flameName": "ACEScg", + "ocioName": "ACES - ACEScg" + }, + { + "flameName": "Rec.709 video", + "ocioName": "Output - Rec.709" + } + ] + } } } \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json index 380ea4a83d..dece37cfda 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json @@ -403,6 +403,58 @@ ] } ] + }, + { + "key": "flame", + "type": "dict", + "label": "Flame/Flair", + "children": [ + { + "key": "project", + "type": "dict", + "label": "Project", + "collapsible": false, + "children": [ + { + "type": "form", + "children": [ + { + "type": "text", + "key": "colourPolicy", + "label": "Colour Policy" + } + ] + } + ] + }, + { + "key": "profilesMapping", + "type": "dict", + "label": "Profile names mapping", + "collapsible": true, + "children": [ + { + "type": "list", + "key": "inputs", + "object_type": { + "type": "dict", + "children": [ + { + "type": "text", + "key": "flameName", + "label": "Flame name" + }, + { + "type": "text", + "key": "ocioName", + "label": "OCIO name" + } + ] + } + } + ] + } + ] } ] } From 9bf8c24f4a8c967b335595439552f86bb9daeddf Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:36:16 +0100 Subject: [PATCH 082/109] flame: move utility scripts with rename to startup keep consistency across all hosts --- .../export_preset/openpype_seg_thumbnails_jpg.xml | 0 .../export_preset/openpype_seg_video_h264.xml | 0 .../openpype_flame_to_ftrack/modules/__init__.py | 0 .../openpype_flame_to_ftrack/modules/app_utils.py | 0 .../openpype_flame_to_ftrack/modules/ftrack_lib.py | 0 .../openpype_flame_to_ftrack/modules/panel_app.py | 0 .../openpype_flame_to_ftrack/modules/uiwidgets.py | 0 .../openpype_flame_to_ftrack/openpype_flame_to_ftrack.py | 0 .../flame/{api/utility_scripts => startup}/openpype_in_flame.py | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/export_preset/openpype_seg_thumbnails_jpg.xml (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/export_preset/openpype_seg_video_h264.xml (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/modules/__init__.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/modules/app_utils.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/modules/ftrack_lib.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/modules/panel_app.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/modules/uiwidgets.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py (100%) rename openpype/hosts/flame/{api/utility_scripts => startup}/openpype_in_flame.py (100%) diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/export_preset/openpype_seg_thumbnails_jpg.xml b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/export_preset/openpype_seg_thumbnails_jpg.xml similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/export_preset/openpype_seg_thumbnails_jpg.xml rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/export_preset/openpype_seg_thumbnails_jpg.xml diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/export_preset/openpype_seg_video_h264.xml b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/export_preset/openpype_seg_video_h264.xml similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/export_preset/openpype_seg_video_h264.xml rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/export_preset/openpype_seg_video_h264.xml diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/__init__.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/__init__.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/__init__.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/__init__.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/app_utils.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/app_utils.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/app_utils.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/app_utils.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/ftrack_lib.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/ftrack_lib.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/ftrack_lib.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/ftrack_lib.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/panel_app.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/panel_app.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/panel_app.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/panel_app.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/uiwidgets.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/uiwidgets.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/modules/uiwidgets.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/modules/uiwidgets.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py b/openpype/hosts/flame/startup/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py rename to openpype/hosts/flame/startup/openpype_flame_to_ftrack/openpype_flame_to_ftrack.py diff --git a/openpype/hosts/flame/api/utility_scripts/openpype_in_flame.py b/openpype/hosts/flame/startup/openpype_in_flame.py similarity index 100% rename from openpype/hosts/flame/api/utility_scripts/openpype_in_flame.py rename to openpype/hosts/flame/startup/openpype_in_flame.py From c0eed0dc141b6b1bf633f9ac0d398969f37ebbdf Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:37:16 +0100 Subject: [PATCH 083/109] flame: adding startup folder to environ var refactory to use `DL_PYTHON_HOOK_PATH` also cover `QT_AUTO_SCREEN_SCALE_FACTOR` issue --- openpype/hosts/flame/__init__.py | 18 ++++++++++++++++++ openpype/hosts/flame/hooks/pre_flame_setup.py | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/flame/__init__.py b/openpype/hosts/flame/__init__.py index 02befa76e2..1c9fa099da 100644 --- a/openpype/hosts/flame/__init__.py +++ b/openpype/hosts/flame/__init__.py @@ -3,3 +3,21 @@ import os HOST_DIR = os.path.dirname( os.path.abspath(__file__) ) + + +def add_implementation_envs(env, _app): + # Add requirements to DL_PYTHON_HOOK_PATH + pype_root = os.environ["OPENPYPE_REPOS_ROOT"] + new_flame_paths = os.path.join( + pype_root, "openpype", "hosts", "flame", "startup") + + env["DL_PYTHON_HOOK_PATH"] = os.pathsep.join(new_flame_paths) + env.pop("QT_AUTO_SCREEN_SCALE_FACTOR", None) + + # Set default values if are not already set via settings + defaults = { + "LOGLEVEL": "DEBUG" + } + for key, value in defaults.items(): + if not env.get(key): + env[key] = value diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index e8bdd840f4..94703396b9 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -4,7 +4,9 @@ import tempfile import contextlib import socket from openpype.lib import ( - PreLaunchHook, get_openpype_username) + PreLaunchHook, + get_openpype_username +) from openpype.hosts import flame as opflame import openpype.hosts.flame.api as opfapi import openpype From 3214fb91181826755d21a4303da7f8825051dabe Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:53:14 +0100 Subject: [PATCH 084/109] flame: adding field dominance, image depth to imageio --- .../settings/defaults/project_anatomy/imageio.json | 4 +++- .../schemas/schema_anatomy_imageio.json | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_anatomy/imageio.json b/openpype/settings/defaults/project_anatomy/imageio.json index 8a8eb8b5c5..4a1496fe1a 100644 --- a/openpype/settings/defaults/project_anatomy/imageio.json +++ b/openpype/settings/defaults/project_anatomy/imageio.json @@ -189,7 +189,9 @@ }, "flame": { "project": { - "colourPolicy": "ACES 1.1" + "colourPolicy": "ACES 1.1", + "frameDepth": "16-bit fp", + "fieldDominance": "PROGRESSIVE" }, "profilesMapping": { "inputs": [ diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json index dece37cfda..e000adacb0 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json @@ -422,6 +422,16 @@ "type": "text", "key": "colourPolicy", "label": "Colour Policy" + }, + { + "type": "text", + "key": "frameDepth", + "label": "Image Depth" + }, + { + "type": "text", + "key": "fieldDominance", + "label": "Field Dominance" } ] } From 65d23644e556961affe641aa9b900d3de41d78b4 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 16:55:25 +0100 Subject: [PATCH 085/109] flame: connecting imageio settings to project hook creation --- openpype/hosts/flame/hooks/pre_flame_setup.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index 94703396b9..bd1f687316 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -7,6 +7,7 @@ from openpype.lib import ( PreLaunchHook, get_openpype_username ) +from openpype.api import get_anatomy_settings from openpype.hosts import flame as opflame import openpype.hosts.flame.api as opfapi import openpype @@ -35,6 +36,13 @@ class FlamePrelaunch(PreLaunchHook): """Hook entry method.""" project_doc = self.data["project_doc"] + project_name = project_doc["name"] + + # get image io + project_anatomy = get_anatomy_settings(project_name) + imageio_flame = project_anatomy["imageio"]["flame"] + + # get user name and host name user_name = get_openpype_username() hostname = socket.gethostname() # not returning wiretap host name @@ -43,7 +51,7 @@ class FlamePrelaunch(PreLaunchHook): _db_p_data = project_doc["data"] width = _db_p_data["resolutionWidth"] height = _db_p_data["resolutionHeight"] - fps = int(_db_p_data["fps"]) + fps = float(_db_p_data["fps"]) project_data = { "Name": project_doc["name"], @@ -54,8 +62,8 @@ class FlamePrelaunch(PreLaunchHook): "FrameHeight": int(height), "AspectRatio": float((width / height) * _db_p_data["pixelAspect"]), "FrameRate": "{} fps".format(fps), - "FrameDepth": "16-bit fp", - "FieldDominance": "PROGRESSIVE" + "FrameDepth": str(imageio_flame["project"]["frameDepth"]), + "FieldDominance": str(imageio_flame["project"]["fieldDominance"]) } data_to_script = { @@ -63,10 +71,10 @@ class FlamePrelaunch(PreLaunchHook): "host_name": _env.get("FLAME_WIRETAP_HOSTNAME") or hostname, "volume_name": _env.get("FLAME_WIRETAP_VOLUME"), "group_name": _env.get("FLAME_WIRETAP_GROUP"), - "color_policy": "ACES 1.1", + "color_policy": str(imageio_flame["project"]["colourPolicy"]), # from project - "project_name": project_doc["name"], + "project_name": project_name, "user_name": user_name, "project_data": project_data } From 76ef5d92792011231eaadc26f097d1eea4ce7b8c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 17:05:07 +0100 Subject: [PATCH 086/109] Only save scene if current scene is in a modified state --- openpype/hosts/maya/plugins/publish/save_scene.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/save_scene.py b/openpype/hosts/maya/plugins/publish/save_scene.py index d3e1597e78..1750e220a4 100644 --- a/openpype/hosts/maya/plugins/publish/save_scene.py +++ b/openpype/hosts/maya/plugins/publish/save_scene.py @@ -17,5 +17,11 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): current = cmds.file(query=True, sceneName=True) assert context.data['currentFile'] == current + # If file has no modifications, skip forcing a file save + if not cmds.file(query=True, modified=True): + self.log.debug("Skipping file save as there " + "are no modifications..") + return + self.log.info("Saving current file..") cmds.file(save=True, force=True) From e08062b98be27d50a9223e68c97b603544a7fc74 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 17:05:25 +0100 Subject: [PATCH 087/109] Always save scene on Workfile publish --- openpype/hosts/maya/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/save_scene.py b/openpype/hosts/maya/plugins/publish/save_scene.py index 1750e220a4..0ed1c63b4b 100644 --- a/openpype/hosts/maya/plugins/publish/save_scene.py +++ b/openpype/hosts/maya/plugins/publish/save_scene.py @@ -9,7 +9,7 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): label = "Save current file" order = pyblish.api.IntegratorOrder - 0.49 hosts = ["maya"] - families = ["renderlayer"] + families = ["renderlayer", "workfile"] def process(self, context): import maya.cmds as cmds From 0e99b4cb514d4f86805378ce82e960a276e41a52 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 17:19:19 +0100 Subject: [PATCH 088/109] flame: user without dot and rather underscore --- openpype/hosts/flame/hooks/pre_flame_setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index bd1f687316..67c5c7e39b 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -44,6 +44,8 @@ class FlamePrelaunch(PreLaunchHook): # get user name and host name user_name = get_openpype_username() + user_name = user_name.replace(".", "_") + hostname = socket.gethostname() # not returning wiretap host name self.log.debug("Collected user \"{}\"".format(user_name)) From eec2e68dc44b2acf41155de97650981ceddb9f7c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 17:19:59 +0100 Subject: [PATCH 089/109] flame: disable utility setup in prelaunch hook --- openpype/hosts/flame/hooks/pre_flame_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index 67c5c7e39b..ff72609f34 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -89,7 +89,7 @@ class FlamePrelaunch(PreLaunchHook): app_arguments = self._get_launch_arguments(data_to_script) - opfapi.setup(self.launch_context.env) + # opfapi.setup(self.launch_context.env) self.launch_context.launch_args.extend(app_arguments) From 901f772f58f1e00caf343490506e4cc947741c74 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 17:36:30 +0100 Subject: [PATCH 090/109] flame: fix path creation for custom scripts --- openpype/hosts/flame/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/flame/__init__.py b/openpype/hosts/flame/__init__.py index 1c9fa099da..f839357147 100644 --- a/openpype/hosts/flame/__init__.py +++ b/openpype/hosts/flame/__init__.py @@ -8,10 +8,9 @@ HOST_DIR = os.path.dirname( def add_implementation_envs(env, _app): # Add requirements to DL_PYTHON_HOOK_PATH pype_root = os.environ["OPENPYPE_REPOS_ROOT"] - new_flame_paths = os.path.join( - pype_root, "openpype", "hosts", "flame", "startup") - env["DL_PYTHON_HOOK_PATH"] = os.pathsep.join(new_flame_paths) + env["DL_PYTHON_HOOK_PATH"] = os.path.join( + pype_root, "openpype", "hosts", "flame", "startup") env.pop("QT_AUTO_SCREEN_SCALE_FACTOR", None) # Set default values if are not already set via settings From d007c057d200eeb806cb15d5549a18ff866ae8aa Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 20:57:27 +0100 Subject: [PATCH 091/109] flame: optimize validate asset name to remove unicodes --- .../publish/validate_editorial_asset_name.py | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/openpype/plugins/publish/validate_editorial_asset_name.py b/openpype/plugins/publish/validate_editorial_asset_name.py index 7359ccf360..416e83a09e 100644 --- a/openpype/plugins/publish/validate_editorial_asset_name.py +++ b/openpype/plugins/publish/validate_editorial_asset_name.py @@ -32,7 +32,7 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): self.log.debug("__ db_assets: {}".format(db_assets)) asset_db_docs = { - str(e["name"]): e["data"]["parents"] + str(e["name"]): [str(p) for p in e["data"]["parents"]] for e in db_assets} self.log.debug("__ project_entities: {}".format( @@ -43,17 +43,15 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): for asset in asset_and_parents.keys(): if asset not in asset_db_docs.keys(): # add to some nonexistent list for next layer of check - assets_missing_name.update({asset: asset_and_parents[asset]}) + assets_missing_name[asset] = asset_and_parents[asset] continue if asset_and_parents[asset] != asset_db_docs[asset]: # add to some nonexistent list for next layer of check - assets_wrong_parent.update({ - asset: { - "required": asset_and_parents[asset], - "already_in_db": asset_db_docs[asset] - } - }) + assets_wrong_parent[asset] = { + "required": asset_and_parents[asset], + "already_in_db": asset_db_docs[asset] + } continue self.log.info("correct asset: {}".format(asset)) @@ -62,17 +60,21 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): wrong_names = {} self.log.debug( ">> assets_missing_name: {}".format(assets_missing_name)) - for asset in assets_missing_name.keys(): + + for asset in assets_missing_name: _asset = asset.lower().replace("_", "") - if _asset in [a.lower().replace("_", "") - for a in asset_db_docs.keys()]: - wrong_names.update({ - "required_name": asset, - "used_variants_in_db": [ - a for a in asset_db_docs.keys() - if a.lower().replace("_", "") == _asset - ] - }) + if _asset in [ + a.lower().replace("_", "") for a in asset_db_docs + ]: + wrong_names.update( + { + "required_name": asset, + "used_variants_in_db": [ + a for a in asset_db_docs + if a.lower().replace("_", "") == _asset + ] + } + ) if wrong_names: self.log.debug( @@ -114,8 +116,8 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): parents = instance.data["parents"] - return_dict.update({ - asset: [p["entity_name"] for p in parents - if p["entity_type"].lower() != "project"] - }) + return_dict[asset] = [ + str(p["entity_name"]) for p in parents + if p["entity_type"].lower() != "project" + ] return return_dict From 26ce68ad709d1fb00ff2f18e6ad70632f5878eed Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 21:15:46 +0100 Subject: [PATCH 092/109] flame: adding validation of source clip --- .../plugins/publish/validate_source_clip.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 openpype/hosts/flame/plugins/publish/validate_source_clip.py diff --git a/openpype/hosts/flame/plugins/publish/validate_source_clip.py b/openpype/hosts/flame/plugins/publish/validate_source_clip.py new file mode 100644 index 0000000000..1d2b693619 --- /dev/null +++ b/openpype/hosts/flame/plugins/publish/validate_source_clip.py @@ -0,0 +1,21 @@ +import pyblish + +@pyblish.api.log +class ValidateSourceClip(pyblish.api.InstancePlugin): + """Validate instance is not having empty `flameSourceClip`""" + + order = pyblish.api.ValidatorOrder + label = "Validate Source Clip" + hosts = ["flame"] + families = ["clip"] + + def process(self, instance): + flame_source_clip = instance.data["flameSourceClip"] + + if flame_source_clip is None: + raise ( + "Timeline segment `{}` is not having " + "relative clip in reels. Please make sure " + "you push `Save Sources` button in Conform Tab").format( + instance.data["name"] + ) From a2ff92660ccafb9d05f4460d91874ad4b7479122 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Feb 2022 21:30:28 +0100 Subject: [PATCH 093/109] flame: validator fix, adding exception --- .../hosts/flame/plugins/publish/validate_source_clip.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/flame/plugins/publish/validate_source_clip.py b/openpype/hosts/flame/plugins/publish/validate_source_clip.py index 1d2b693619..9ff015f628 100644 --- a/openpype/hosts/flame/plugins/publish/validate_source_clip.py +++ b/openpype/hosts/flame/plugins/publish/validate_source_clip.py @@ -1,5 +1,6 @@ import pyblish + @pyblish.api.log class ValidateSourceClip(pyblish.api.InstancePlugin): """Validate instance is not having empty `flameSourceClip`""" @@ -12,10 +13,12 @@ class ValidateSourceClip(pyblish.api.InstancePlugin): def process(self, instance): flame_source_clip = instance.data["flameSourceClip"] + self.log.debug("_ flame_source_clip: {}".format(flame_source_clip)) + if flame_source_clip is None: - raise ( + raise AttributeError(( "Timeline segment `{}` is not having " "relative clip in reels. Please make sure " "you push `Save Sources` button in Conform Tab").format( - instance.data["name"] - ) + instance.data["asset"] + )) From c4c7266529844ad97df4de45acdfbe406290f33f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 16 Feb 2022 21:41:32 +0100 Subject: [PATCH 094/109] Move Maya SaveCurrentScene to beginning of ExtractorOrder --- openpype/hosts/maya/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/save_scene.py b/openpype/hosts/maya/plugins/publish/save_scene.py index 0ed1c63b4b..50a2f2112a 100644 --- a/openpype/hosts/maya/plugins/publish/save_scene.py +++ b/openpype/hosts/maya/plugins/publish/save_scene.py @@ -7,7 +7,7 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): """ label = "Save current file" - order = pyblish.api.IntegratorOrder - 0.49 + order = pyblish.api.ExtractorOrder - 0.49 hosts = ["maya"] families = ["renderlayer", "workfile"] From 21ac7b25eaf3cf853292c1f4985db20dcde1a873 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 17 Feb 2022 10:45:29 +0100 Subject: [PATCH 095/109] OP-2551 - added multiprocess override by env var In case of multiple variants of AE, project setting might not be enough. Add MULTIPROCESS env var to specific app variant. --- .../publish/submit_aftereffects_deadline.py | 14 ++++++++++---- .../defaults/system_settings/applications.json | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py index d5346ad9b3..0c0ba47e6f 100644 --- a/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -1,11 +1,14 @@ -from openpype.lib import abstract_submit_deadline -from openpype.lib.abstract_submit_deadline import DeadlineJobInfo -import pyblish.api import os import attr import getpass +import pyblish.api + from avalon import api +from openpype.lib import abstract_submit_deadline +from openpype.lib.abstract_submit_deadline import DeadlineJobInfo +from openpype.lib import env_value_to_bool + @attr.s class DeadlinePluginInfo(): @@ -116,7 +119,10 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline deadline_plugin_info.Comp = self._instance.data["comp_name"] deadline_plugin_info.Version = self._instance.data["app_version"] # must be here because of DL AE plugin - deadline_plugin_info.MultiProcess = self.multiprocess + # added override of multiprocess by env var, if shouldn't be used for + # some app variant use MULTIPROCESS:false in Settings, default is True + env_multi = env_value_to_bool("MULTIPROCESS", default=True) + deadline_plugin_info.MultiProcess = env_multi and self.multiprocess deadline_plugin_info.SceneFile = self.scene_path deadline_plugin_info.Output = render_path.replace("\\", "/") diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 4a8b6d82a2..a9ab70cd28 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -1127,7 +1127,9 @@ "darwin": [], "linux": [] }, - "environment": {} + "environment": { + "MULTIPROCESS": "No" + } } } }, From 213741d652e01b2cb7381df5b57b91d7efb1ca7f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 17 Feb 2022 16:31:26 +0100 Subject: [PATCH 096/109] flame: making sure anatomy imageio flame key is present https://github.com/pypeclub/OpenPype/pull/2745#discussion_r808915085 --- openpype/hosts/flame/hooks/pre_flame_setup.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index ff72609f34..26056e6c16 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -7,9 +7,11 @@ from openpype.lib import ( PreLaunchHook, get_openpype_username ) +from openpype.lib.applications import ( + ApplicationLaunchFailed +) from openpype.api import get_anatomy_settings from openpype.hosts import flame as opflame -import openpype.hosts.flame.api as opfapi import openpype from pprint import pformat @@ -40,6 +42,15 @@ class FlamePrelaunch(PreLaunchHook): # get image io project_anatomy = get_anatomy_settings(project_name) + + # make sure anatomy settings are having flame key + if not project_anatomy["imageio"].get("flame"): + raise ApplicationLaunchFailed(( + "Anatomy project settings are missing `flame` key. " + "Please make sure you remove project overides on " + "Anatomy Image io") + ) + imageio_flame = project_anatomy["imageio"]["flame"] # get user name and host name @@ -89,8 +100,6 @@ class FlamePrelaunch(PreLaunchHook): app_arguments = self._get_launch_arguments(data_to_script) - # opfapi.setup(self.launch_context.env) - self.launch_context.launch_args.extend(app_arguments) def _add_pythonpath(self): From 8f8545e2b58c8a991c2f3ee7e58b4a6e5ff12b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 17 Feb 2022 16:35:00 +0100 Subject: [PATCH 097/109] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/flame/hooks/pre_flame_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index 26056e6c16..061cf8416b 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -41,7 +41,7 @@ class FlamePrelaunch(PreLaunchHook): project_name = project_doc["name"] # get image io - project_anatomy = get_anatomy_settings(project_name) + project_anatomy = self.data["anatomy"] # make sure anatomy settings are having flame key if not project_anatomy["imageio"].get("flame"): From 373b1c159bbc1430157943c5e3f407cc021ede66 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 17 Feb 2022 16:39:03 +0100 Subject: [PATCH 098/109] global: validating asset name for test preprocessing https://github.com/pypeclub/OpenPype/pull/2745#discussion_r808933011 --- .../plugins/publish/validate_editorial_asset_name.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/publish/validate_editorial_asset_name.py b/openpype/plugins/publish/validate_editorial_asset_name.py index 416e83a09e..c40f81a21a 100644 --- a/openpype/plugins/publish/validate_editorial_asset_name.py +++ b/openpype/plugins/publish/validate_editorial_asset_name.py @@ -61,11 +61,14 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): self.log.debug( ">> assets_missing_name: {}".format(assets_missing_name)) + # This will create set asset names + asset_names = { + a.lower().replace("_", "") for a in asset_db_docs + } + for asset in assets_missing_name: _asset = asset.lower().replace("_", "") - if _asset in [ - a.lower().replace("_", "") for a in asset_db_docs - ]: + if _asset in asset_names: wrong_names.update( { "required_name": asset, From d50893c6ead7ebed971ad2eb1dbfe7949068b4df Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 17 Feb 2022 16:45:57 +0100 Subject: [PATCH 099/109] global: dict was overwriting keys https://github.com/pypeclub/OpenPype/pull/2745#discussion_r808934017 --- openpype/plugins/publish/validate_editorial_asset_name.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/validate_editorial_asset_name.py b/openpype/plugins/publish/validate_editorial_asset_name.py index c40f81a21a..4a65f3c64a 100644 --- a/openpype/plugins/publish/validate_editorial_asset_name.py +++ b/openpype/plugins/publish/validate_editorial_asset_name.py @@ -69,7 +69,7 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): for asset in assets_missing_name: _asset = asset.lower().replace("_", "") if _asset in asset_names: - wrong_names.update( + wrong_names[asset].update( { "required_name": asset, "used_variants_in_db": [ From 1ed26cc7a5864ac689abbe5929ad2491db8ad8a7 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 17 Feb 2022 16:47:01 +0100 Subject: [PATCH 100/109] hound: catches --- openpype/hosts/flame/hooks/pre_flame_setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index 061cf8416b..0d63b0d926 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -10,7 +10,6 @@ from openpype.lib import ( from openpype.lib.applications import ( ApplicationLaunchFailed ) -from openpype.api import get_anatomy_settings from openpype.hosts import flame as opflame import openpype from pprint import pformat From 605d43296d8d1c932dad3ad9e15bd3d7ea39337a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 17 Feb 2022 17:39:43 +0100 Subject: [PATCH 101/109] OP-2669 - better selection of work folder Because work folder in Harmony is local, it must be replaced with folder where workfile will be finally published. In some cases naming convention of expected files didn't match correct value, which resulted in not updating the path. This explicitly replaces dir name of expected file with staging folder where renders will be created on a DL machine. --- .../plugins/publish/submit_harmony_deadline.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py index bd375dbd6a..c677b72b2f 100644 --- a/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -320,7 +320,8 @@ class HarmonySubmitDeadline( / published_scene.stem / f"{published_scene.stem}.xstage" ) - + self.log.info("published_scene:: {}".format(published_scene)) + self.log.info("xstage_path:: {}".format(xstage_path)) unzip_dir = (published_scene.parent / published_scene.stem) with _ZipFile(published_scene, "r") as zip_ref: zip_ref.extractall(unzip_dir.as_posix()) @@ -351,12 +352,12 @@ class HarmonySubmitDeadline( # use that one. if not ideal_scene: xstage_path = xstage_files[0] - + self.log.info("xstage_path:: {}".format(xstage_path)) return xstage_path def get_plugin_info(self): work_scene = Path(self._instance.data["source"]) - + self.log.info("work scene:: {}".format(work_scene)) # this is path to published scene workfile _ZIP_. Before # rendering, we need to unzip it. published_scene = Path( @@ -368,14 +369,13 @@ class HarmonySubmitDeadline( # for submit_publish job to create .json file in self._instance.data["outputDir"] = render_path new_expected_files = [] - work_path_str = str(work_scene.parent.as_posix()) render_path_str = str(render_path.as_posix()) for file in self._instance.data["expectedFiles"]: _file = str(Path(file).as_posix()) + expected_dir_str = os.path.dirname(_file) new_expected_files.append( - _file.replace(work_path_str, render_path_str) + _file.replace(expected_dir_str, render_path_str) ) - audio_file = self._instance.data.get("audioFile") if audio_file: abs_path = xstage_path.parent / audio_file From 3a7168861b0e8a3a1580ceadbf572674627329e4 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 17 Feb 2022 17:55:21 +0100 Subject: [PATCH 102/109] OP-2669 - removed unwanted logs --- .../deadline/plugins/publish/submit_harmony_deadline.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py index c677b72b2f..9d55d43ba6 100644 --- a/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -320,8 +320,6 @@ class HarmonySubmitDeadline( / published_scene.stem / f"{published_scene.stem}.xstage" ) - self.log.info("published_scene:: {}".format(published_scene)) - self.log.info("xstage_path:: {}".format(xstage_path)) unzip_dir = (published_scene.parent / published_scene.stem) with _ZipFile(published_scene, "r") as zip_ref: zip_ref.extractall(unzip_dir.as_posix()) @@ -352,12 +350,9 @@ class HarmonySubmitDeadline( # use that one. if not ideal_scene: xstage_path = xstage_files[0] - self.log.info("xstage_path:: {}".format(xstage_path)) return xstage_path def get_plugin_info(self): - work_scene = Path(self._instance.data["source"]) - self.log.info("work scene:: {}".format(work_scene)) # this is path to published scene workfile _ZIP_. Before # rendering, we need to unzip it. published_scene = Path( From de3f865d7729c8b4d2fe2bc1d815080135fdbe13 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 18 Feb 2022 02:40:25 +0100 Subject: [PATCH 103/109] Fix matching in Python 2 --- openpype/tools/workfiles/app.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 785e87738f..4b5bf07b47 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -116,7 +116,7 @@ class CommentMatcher(object): "|".join(re.escape(ext[1:]) for ext in extensions) ) - # Use placeholders that we can safely escape with regex + # Use placeholders that will never be in the filename temp_data = copy.deepcopy(data) temp_data["comment"] = "<>" temp_data["version"] = "<>" @@ -126,11 +126,14 @@ class CommentMatcher(object): fname_pattern = formatted[template_key]["file"] fname_pattern = re.escape(fname_pattern) - # Replace comment and version with something we can match with - # regex - fname_pattern = fname_pattern.replace("<>", "(.+)") - fname_pattern = fname_pattern.replace("<>", "[0-9]+") - fname_pattern = fname_pattern.replace("<>", any_extension) + # Replace comment and version with something we can match with regex + replacements = { + "<>": "(.+)", + "<>": "[0-9]+", + "<>": any_extension, + } + for src, dest in replacements.items(): + fname_pattern = fname_pattern.replace(re.escape(src), dest) # Match from beginning to end of string to be safe fname_pattern = "^{}$".format(fname_pattern) From 257c5e099be7191920069a4163845543abe7d6d8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 18 Feb 2022 10:47:30 +0100 Subject: [PATCH 104/109] fix right click in representation widget --- openpype/tools/loader/model.py | 14 ++++++++++++ openpype/tools/loader/widgets.py | 38 +++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index f34eb157ab..10b22d0e17 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -1068,6 +1068,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): self._icons = lib.get_repre_icons() self._icons["repre"] = qtawesome.icon("fa.file-o", color=style.colors.default) + self._items_by_id = {} def set_version_ids(self, version_ids): self.version_ids = version_ids @@ -1076,6 +1077,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): def data(self, index, role): item = index.internalPointer() + if role == ITEM_ID_ROLE: + return item["id"] + if role == self.IdRole: return item.get("_id") @@ -1149,8 +1153,11 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): if len(self.version_ids) > 1: group = repre_groups.get(doc["name"]) if not group: + group_item = Item() + item_id = str(uuid4()) group_item.update({ + "id": item_id, "_id": doc["_id"], "name": doc["name"], "isMerged": True, @@ -1161,6 +1168,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): color=style.colors.default ) }) + self._items_by_id[item_id] = group_item self.add_child(group_item, None) repre_groups[doc["name"]] = group_item repre_groups_items[doc["name"]] = 0 @@ -1173,7 +1181,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): active_site_icon = self._icons.get(self.active_provider) remote_site_icon = self._icons.get(self.remote_provider) + item_id = str(uuid4()) data = { + "id": item_id, "_id": doc["_id"], "name": doc["name"], "subset": doc["context"]["subset"], @@ -1192,6 +1202,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): item = Item() item.update(data) + self._items_by_id[item_id] = item current_progress = { 'active_site_progress': progress[self.active_site], @@ -1215,6 +1226,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel): self.endResetModel() self.refreshed.emit(False) + def get_item_by_id(self, item_id): + return self._items_by_id.get(item_id) + def refresh(self): docs = [] session_project = self.dbcon.Session['AVALON_PROJECT'] diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index f60341af2f..f145756cc5 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -1283,6 +1283,40 @@ class RepresentationWidget(QtWidgets.QWidget): } return repre_context_by_id + def get_selected_items(self): + selection_model = self.tree_view.selectionModel() + indexes = selection_model.selectedIndexes() + + item_ids = set() + for index in indexes: + item_id = index.data(ITEM_ID_ROLE) + if item_id is not None: + item_ids.add(item_id) + + output = [] + for item_id in item_ids: + item = self.model.get_item_by_id(item_id) + if item is not None: + output.append(item) + return output + + def get_selected_repre_items(self): + output = [] + items = collections.deque(self.get_selected_items()) + + item_ids = set() + while items: + item = items.popleft() + if item.get("isGroup") or item.get("isMerged"): + for child in item.children(): + items.appendleft(child) + else: + item_id = item["id"] + if item_id not in item_ids: + item_ids.add(item_id) + output.append(item) + return output + def on_context_menu(self, point): """Shows menu with loader actions on Right-click. @@ -1301,10 +1335,8 @@ class RepresentationWidget(QtWidgets.QWidget): selection = self.tree_view.selectionModel() rows = selection.selectedRows(column=0) - items = self.get_selected_subsets() - + items = self.get_selected_repre_items() selected_side = self._get_selected_side(point_index, rows) - # Get all representation->loader combinations available for the # index under the cursor, so we can list the user the options. available_loaders = api.discover(api.Loader) From 20f01ae321062f70ec2523261c6ad2456cfdff61 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 18 Feb 2022 11:41:36 +0100 Subject: [PATCH 105/109] Remove redundant new line in print output --- openpype/tools/pyblish_pype/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/pyblish_pype/app.py b/openpype/tools/pyblish_pype/app.py index 5ba0a47425..d15d586103 100644 --- a/openpype/tools/pyblish_pype/app.py +++ b/openpype/tools/pyblish_pype/app.py @@ -62,9 +62,9 @@ def install_fonts(): # In hosts, this will be called each time the GUI is shown, # potentially installing a font each time. if database.addApplicationFont(path) < 0: - print("Could not install %s\n" % path) + print("Could not install %s" % path) else: - print("Installed %s\n" % font) + print("Installed %s" % font) def on_destroyed(): From 6d3a1eb592341184bd2da47b3adf4b42583cb910 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 18 Feb 2022 12:27:23 +0100 Subject: [PATCH 106/109] update yarn.lock to latest dependencies --- website/yarn.lock | 2300 ++++++++++++++++----------------------------- 1 file changed, 830 insertions(+), 1470 deletions(-) diff --git a/website/yarn.lock b/website/yarn.lock index 9d9dd3f0a9..7f677aaed7 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -2,24 +2,24 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.5.0.tgz#6c91c9de7748e9c103846828a58dfe92bd4d6689" - integrity sha512-E7+VJwcvwMM8vPeaVn7fNUgix8WHV8A1WUeHDi2KHemCaaGc8lvUnP3QnvhMxiDhTe7OpMEv4o2TBUMyDgThaw== +"@algolia/autocomplete-core@1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.5.2.tgz#ec0178e07b44fd74a057728ac157291b26cecf37" + integrity sha512-DY0bhyczFSS1b/CqJlTE/nQRtnTAHl6IemIkBy0nEWnhDzRDdtdx4p5Uuk3vwAFxwEEgi1WqKwgSSMx6DpNL4A== dependencies: - "@algolia/autocomplete-shared" "1.5.0" + "@algolia/autocomplete-shared" "1.5.2" -"@algolia/autocomplete-preset-algolia@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.5.0.tgz#61671f09c0c77133d9baf1356719f8378c48437a" - integrity sha512-iiFxKERGHkvkiupmrFJbvESpP/zv5jSgH714XRiP5LDvUHaYOo4GLAwZCFf2ef/L5tdtPBARvekn6k1Xf33gjA== +"@algolia/autocomplete-preset-algolia@1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.5.2.tgz#36c5638cc6dba6ea46a86e5a0314637ca40a77ca" + integrity sha512-3MRYnYQFJyovANzSX2CToS6/5cfVjbLLqFsZTKcvF3abhQzxbqwwaMBlJtt620uBUOeMzhdfasKhCc40+RHiZw== dependencies: - "@algolia/autocomplete-shared" "1.5.0" + "@algolia/autocomplete-shared" "1.5.2" -"@algolia/autocomplete-shared@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.5.0.tgz#09580bc89408a2ab5f29e312120dad68f58019bd" - integrity sha512-bRSkqHHHSwZYbFY3w9hgMyQRm86Wz27bRaGCbNldLfbk0zUjApmE4ajx+ZCVSLqxvcUEjMqZFJzDsder12eKsg== +"@algolia/autocomplete-shared@1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.5.2.tgz#e157f9ad624ab8fd940ff28bd2094cdf199cdd79" + integrity sha512-ylQAYv5H0YKMfHgVWX0j0NmL8XBcAeeeVQUmppnnMtzDbDnca6CzhKj3Q8eF9cHCgcdTDdb5K+3aKyGWA0obug== "@algolia/cache-browser-local-storage@4.12.1": version "4.12.1" @@ -28,23 +28,11 @@ dependencies: "@algolia/cache-common" "4.12.1" -"@algolia/cache-browser-local-storage@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.8.6.tgz#6be9644b68efbbc231ac3f0a4cfa985ef31eade9" - integrity sha512-Bam7otzjIEgrRXWmk0Amm1+B3ROI5dQnUfJEBjIy0YPM0kMahEoJXCw6160tGKxJLl1g6icoC953nGshQKO7cA== - dependencies: - "@algolia/cache-common" "4.8.6" - "@algolia/cache-common@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.12.1.tgz#d3f1676ca9c404adce0f78d68f6381bedb44cd9c" integrity sha512-UugTER3V40jT+e19Dmph5PKMeliYKxycNPwrPNADin0RcWNfT2QksK9Ff2N2W7UKraqMOzoeDb4LAJtxcK1a8Q== -"@algolia/cache-common@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.8.6.tgz#dff1697a0fe3d7856630071559661ec5ad90f31c" - integrity sha512-eGQlsXU5G7n4RvV/K6qe6lRAeL6EKAYPT3yZDBjCW4pAh7JWta+77a7BwUQkTqXN1MEQWZXjex3E4z/vFpzNrg== - "@algolia/cache-in-memory@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.12.1.tgz#0ef6aac2f8feab5b46fc130beb682bbd21b55244" @@ -52,13 +40,6 @@ dependencies: "@algolia/cache-common" "4.12.1" -"@algolia/cache-in-memory@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.8.6.tgz#9a100a1be05e700a253ef4bdabd3bd45df2f67d4" - integrity sha512-kbJrvCFANxL/l5Pq1NFyHLRphKDwmqcD/OJga0IbNKEulRGDPkt1+pC7/q8d2ikP12adBjLLg2CVias9RJpIaw== - dependencies: - "@algolia/cache-common" "4.8.6" - "@algolia/client-account@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.12.1.tgz#e838c9283db2fab32a425dd13c77da321d48fd8b" @@ -68,15 +49,6 @@ "@algolia/client-search" "4.12.1" "@algolia/transporter" "4.12.1" -"@algolia/client-account@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.8.6.tgz#050cfd6a6d3e06a5a8e1029f24d6d50524d186c6" - integrity sha512-FQVJE/BgCb78jtG7V0r30sMl9P5JKsrsOacGtGF2YebqI0YF25y8Z1nO39lbdjahxUS3QkDw2d0P2EVMj65g2Q== - dependencies: - "@algolia/client-common" "4.8.6" - "@algolia/client-search" "4.8.6" - "@algolia/transporter" "4.8.6" - "@algolia/client-analytics@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.12.1.tgz#2976d658655a1590cf84cfb596aa75a204f6dec4" @@ -87,16 +59,6 @@ "@algolia/requester-common" "4.12.1" "@algolia/transporter" "4.12.1" -"@algolia/client-analytics@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.8.6.tgz#ac644cfc9d87a085b9e53c71a42ef6e90d828501" - integrity sha512-ZBYFUlzNaWDFtt0rYHI7xbfVX0lPWU9lcEEXI/BlnkRgEkm247H503tNatPQFA1YGkob52EU18sV1eJ+OFRBLA== - dependencies: - "@algolia/client-common" "4.8.6" - "@algolia/client-search" "4.8.6" - "@algolia/requester-common" "4.8.6" - "@algolia/transporter" "4.8.6" - "@algolia/client-common@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.12.1.tgz#104ccefe96bda3ff926bc70c31ff6d17c41b6107" @@ -105,14 +67,6 @@ "@algolia/requester-common" "4.12.1" "@algolia/transporter" "4.12.1" -"@algolia/client-common@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.8.6.tgz#c8b81af250ed8beb741a0e5cfdd3236bb4292c94" - integrity sha512-8dI+K3Nvbes2YRZm2LY7bdCUD05e60BhacrMLxFuKxnBGuNehME1wbxq/QxcG1iNFJlxLIze5TxIcNN3+pn76g== - dependencies: - "@algolia/requester-common" "4.8.6" - "@algolia/transporter" "4.8.6" - "@algolia/client-personalization@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.12.1.tgz#f63d1890f95de850e1c8e41c1d57adda521d9e7f" @@ -122,15 +76,6 @@ "@algolia/requester-common" "4.12.1" "@algolia/transporter" "4.12.1" -"@algolia/client-recommendation@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/client-recommendation/-/client-recommendation-4.8.6.tgz#2518a09bfbeaec78b0d7a4213107f0899f80f9ac" - integrity sha512-Kg8DpjwvaWWujNx6sAUrSL+NTHxFe/UNaliCcSKaMhd3+FiPXN+CrSkO0KWR7I+oK2qGBTG/2Y0BhFOJ5/B/RA== - dependencies: - "@algolia/client-common" "4.8.6" - "@algolia/requester-common" "4.8.6" - "@algolia/transporter" "4.8.6" - "@algolia/client-search@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.12.1.tgz#fcd7a974be5d39d5c336d7f2e89577ffa66aefdd" @@ -140,15 +85,6 @@ "@algolia/requester-common" "4.12.1" "@algolia/transporter" "4.12.1" -"@algolia/client-search@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.8.6.tgz#1ca3f28c04ef4120b0563a293b30fcfe1b3fd1d0" - integrity sha512-vXLS6umL/9G3bwqc6pkrS9K5/s8coq55mpfRARL+bs0NsToOf77WSTdwzlxv/KdbVF7dHjXgUpBvJ6RyR4ZdAw== - dependencies: - "@algolia/client-common" "4.8.6" - "@algolia/requester-common" "4.8.6" - "@algolia/transporter" "4.8.6" - "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" @@ -159,11 +95,6 @@ resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.12.1.tgz#d6501b4d9d242956257ba8e10f6b4bbf6863baa4" integrity sha512-fCgrzlXGATNqdFTxwx0GsyPXK+Uqrx1SZ3iuY2VGPPqdt1a20clAG2n2OcLHJpvaa6vMFPlJyWvbqAgzxdxBlQ== -"@algolia/logger-common@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.8.6.tgz#8c44a4f550e12418b0ec8d76a068e4f1c64206d1" - integrity sha512-FMRxZGdDxSzd0/Mv0R1021FvUt0CcbsQLYeyckvSWX8w+Uk4o0lcV6UtZdERVR5XZsGOqoXLMIYDbR2vkbGbVw== - "@algolia/logger-console@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.12.1.tgz#841edd39dd5c5530a69fc66084bfee3254dd0807" @@ -171,13 +102,6 @@ dependencies: "@algolia/logger-common" "4.12.1" -"@algolia/logger-console@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.8.6.tgz#77176570fa6532fa846c7cfa2c6280935b1a3a06" - integrity sha512-TYw9lwUCjvApC6Z0zn36T6gkCl7hbfJmnU+Z/D8pFJ3Yp7lz06S3oWGjbdrULrYP1w1VOhjd0X7/yGNsMhzutQ== - dependencies: - "@algolia/logger-common" "4.8.6" - "@algolia/requester-browser-xhr@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.12.1.tgz#2d0c18ee188d7cae0e4a930e5e89989e3c4a816b" @@ -185,23 +109,11 @@ dependencies: "@algolia/requester-common" "4.12.1" -"@algolia/requester-browser-xhr@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.8.6.tgz#dbcb5906d10c619d7f08fced2f68fa09abffe5fd" - integrity sha512-omh6uJ3CJXOmcrU9M3/KfGg8XkUuGJGIMkqEbkFvIebpBJxfs6TVs0ziNeMFAcAfhi8/CGgpLbDSgJtWdGQa6w== - dependencies: - "@algolia/requester-common" "4.8.6" - "@algolia/requester-common@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.12.1.tgz#95bb6539da7199da3e205341cea8f27267f7af29" integrity sha512-XWIrWQNJ1vIrSuL/bUk3ZwNMNxl+aWz6dNboRW6+lGTcMIwc3NBFE90ogbZKhNrFRff8zI4qCF15tjW+Fyhpow== -"@algolia/requester-common@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.8.6.tgz#37ea1f9ecc1afcd91532b9f9c952c62fdef42bca" - integrity sha512-r5xJqq/D9KACkI5DgRbrysVL5DUUagikpciH0k0zjBbm+cXiYfpmdflo/h6JnY6kmvWgjr/4DoeTjKYb/0deAQ== - "@algolia/requester-node-http@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.12.1.tgz#c9df97ff1daa7e58c5c2b1f28cf7163005edccb0" @@ -209,13 +121,6 @@ dependencies: "@algolia/requester-common" "4.12.1" -"@algolia/requester-node-http@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.8.6.tgz#e966293224f3bd1ba32ce4f9bc0fdada5d8e69ec" - integrity sha512-TB36OqTVOKyHCOtdxhn/IJyI/NXi/BWy8IEbsiWwwZWlL79NWHbetj49jXWFolEYEuu8PgDjjZGpRhypSuO9XQ== - dependencies: - "@algolia/requester-common" "4.8.6" - "@algolia/transporter@4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.12.1.tgz#61b9829916c474f42e2d4a6eada0d6c138379945" @@ -225,38 +130,24 @@ "@algolia/logger-common" "4.12.1" "@algolia/requester-common" "4.12.1" -"@algolia/transporter@4.8.6": - version "4.8.6" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.8.6.tgz#b605dcd971aed374bdd95dd8938b93b9df650109" - integrity sha512-NRb31J0TP7EPoVMpXZ4yAtr61d26R8KGaf6qdULknvq5sOVHuuH4PwmF08386ERfIsgnM/OBhl+uzwACdCIjSg== +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== dependencies: - "@algolia/cache-common" "4.8.6" - "@algolia/logger-common" "4.8.6" - "@algolia/requester-common" "4.8.6" + "@jridgewell/trace-mapping" "^0.3.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - dependencies: - "@babel/highlight" "^7.12.13" - -"@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" - integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== - -"@babel/compat-data@^7.13.8": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" - integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== "@babel/core@7.12.9": version "7.12.9" @@ -281,51 +172,35 @@ source-map "^0.5.0" "@babel/core@^7.15.5", "@babel/core@^7.16.0": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784" - integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg== + version "7.17.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.5.tgz#6cd2e836058c28f06a4ca8ee7ed955bbf37c8225" + integrity sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA== dependencies: + "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.3" "@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-module-transforms" "^7.16.7" - "@babel/helpers" "^7.16.7" - "@babel/parser" "^7.16.12" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.3" "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.10" - "@babel/types" "^7.16.8" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" -"@babel/generator@^7.12.5", "@babel/generator@^7.13.0": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" - integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== +"@babel/generator@^7.12.5", "@babel/generator@^7.16.0", "@babel/generator@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" + integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg== dependencies: - "@babel/types" "^7.13.0" + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.16.0", "@babel/generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" - integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== - dependencies: - "@babel/types" "^7.16.8" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" - integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -341,17 +216,7 @@ "@babel/helper-explode-assignable-expression" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-compilation-targets@^7.13.0": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz#1310a1678cb8427c07a753750da4f8ce442bdd0c" - integrity sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA== - dependencies: - "@babel/compat-data" "^7.13.8" - "@babel/helper-validator-option" "^7.12.17" - browserslist "^4.14.5" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.16.7": +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== @@ -362,9 +227,9 @@ semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c" - integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg== + version "7.17.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" + integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7" @@ -374,21 +239,13 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" -"@babel/helper-create-regexp-features-plugin@^7.12.13": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" - integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.13" - regexpu-core "^4.7.1" - "@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" - integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^4.7.1" + regexpu-core "^5.0.1" "@babel/helper-define-polyfill-provider@^0.3.1": version "0.3.1" @@ -418,15 +275,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" - integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== - dependencies: - "@babel/helper-get-function-arity" "^7.12.13" - "@babel/template" "^7.12.13" - "@babel/types" "^7.12.13" - "@babel/helper-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" @@ -436,13 +284,6 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-get-function-arity@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" - integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -457,13 +298,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-member-expression-to-functions@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" - integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== - dependencies: - "@babel/types" "^7.13.12" - "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" @@ -471,35 +305,14 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" - integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== - dependencies: - "@babel/types" "^7.13.12" - -"@babel/helper-module-imports@^7.16.7": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.12.1": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.12.tgz#600e58350490828d82282631a1422268e982ba96" - integrity sha512-7zVQqMO3V+K4JOOj40kxiCrMf6xlQAkewBB0eu2b03OO/Q21ZutOzjpfD79A5gtE/2OWi1nv625MrDlGlkbknQ== - dependencies: - "@babel/helper-module-imports" "^7.13.12" - "@babel/helper-replace-supers" "^7.13.12" - "@babel/helper-simple-access" "^7.13.12" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.12.11" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.12" - -"@babel/helper-module-transforms@^7.16.7": +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== @@ -513,13 +326,6 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-optimise-call-expression@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" - integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" @@ -532,12 +338,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" - integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== - -"@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== @@ -551,16 +352,6 @@ "@babel/helper-wrap-function" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helper-replace-supers@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" - integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.13.12" - "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.12" - "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -572,13 +363,6 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-simple-access@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" - integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== - dependencies: - "@babel/types" "^7.13.12" - "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -593,13 +377,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-split-export-declaration@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" - integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== - dependencies: - "@babel/types" "^7.12.13" - "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -607,21 +384,11 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/helper-validator-option@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" - integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== - "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" @@ -637,32 +404,14 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helpers@^7.12.5": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" - integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== - dependencies: - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" - -"@babel/helpers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" - integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== +"@babel/helpers@^7.12.5", "@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== dependencies: "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/highlight@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" - integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - chalk "^2.0.0" - js-tokens "^4.0.0" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" "@babel/highlight@^7.16.7": version "7.16.10" @@ -673,15 +422,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.13.0": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.12.tgz#ba320059420774394d3b0c0233ba40e4250b81d1" - integrity sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw== - -"@babel/parser@^7.16.10", "@babel/parser@^7.16.12", "@babel/parser@^7.16.4", "@babel/parser@^7.16.7": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" - integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== +"@babel/parser@^7.12.7", "@babel/parser@^7.16.4", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" + integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" @@ -783,11 +527,11 @@ "@babel/plugin-transform-parameters" "^7.12.1" "@babel/plugin-proposal-object-rest-spread@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" - integrity sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA== + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" + integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== dependencies: - "@babel/compat-data" "^7.16.4" + "@babel/compat-data" "^7.17.0" "@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" @@ -828,7 +572,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.16.7": +"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== @@ -836,14 +580,6 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" - integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -1015,13 +751,13 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-transform-destructuring@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" - integrity sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A== + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz#c445f75819641788a27a0a3a759d9df911df6abc" + integrity sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.16.7": +"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== @@ -1029,14 +765,6 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" - integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-transform-duplicate-keys@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" @@ -1142,14 +870,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" -"@babel/plugin-transform-parameters@^7.12.1": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" - integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - -"@babel/plugin-transform-parameters@^7.16.7": +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== @@ -1185,15 +906,15 @@ "@babel/plugin-transform-react-jsx" "^7.16.7" "@babel/plugin-transform-react-jsx@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4" - integrity sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag== + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz#eac1565da176ccb1a715dae0b4609858808008c1" + integrity sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-module-imports" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-jsx" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/types" "^7.17.0" "@babel/plugin-transform-react-pure-annotations@^7.16.7": version "7.16.7" @@ -1218,9 +939,9 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-transform-runtime@^7.16.0": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.10.tgz#53d9fd3496daedce1dd99639097fa5d14f4c7c2c" - integrity sha512-9nwTiqETv2G7xI4RvXHNfpGdr8pAA+Q/YtN3yLK7OoK7n9OibVm/xymJ838a9A6E/IciOLPj82lZk0fW6O4O7w== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz#0a2e08b5e2b2d95c4b1d3b3371a2180617455b70" + integrity sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -1402,37 +1123,21 @@ "@babel/plugin-transform-typescript" "^7.16.7" "@babel/runtime-corejs3@^7.16.3": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.16.8.tgz#ea533d96eda6fdc76b1812248e9fbd0c11d4a1a7" - integrity sha512-3fKhuICS1lMz0plI5ktOE/yEtBRMVxplzRkdn6mJQ197XiY0JnrzYV0+Mxozq3JZ8SBV9Ecurmw1XsGbwOf+Sg== + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz#fdca2cd05fba63388babe85d349b6801b008fd13" + integrity sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg== dependencies: core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.1", "@babel/runtime@^7.8.4": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.16.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" - integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.12.13", "@babel/template@^7.12.7": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" - integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/parser" "^7.12.13" - "@babel/types" "^7.12.13" - -"@babel/template@^7.16.7": +"@babel/template@^7.12.7", "@babel/template@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== @@ -1441,67 +1146,43 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc" - integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.0" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.13.0" - "@babel/types" "^7.13.0" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - -"@babel/traverse@^7.16.10", "@babel/traverse@^7.16.3", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" - integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== +"@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.3", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== dependencies: "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.3" "@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-function-name" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.10" - "@babel/types" "^7.16.8" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.12.13", "@babel/types@^7.12.7", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.4.4": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.12.tgz#edbf99208ef48852acdff1c8a681a1e4ade580cd" - integrity sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@babel/types@^7.15.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" - integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== +"@babel/types@^7.12.7", "@babel/types@^7.15.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.4.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@docsearch/css@3.0.0-alpha.42": - version "3.0.0-alpha.42" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.0.0-alpha.42.tgz#deb6049e999d6ca9451eba4793cb5b6da28c8773" - integrity sha512-AGwI2AXUacYhVOHmYnsXoYDJKO6Ued2W+QO80GERbMLhC7GH5tfvtW5REs/s7jSdcU3vzFoxT8iPDBCh/PkrlQ== +"@docsearch/css@3.0.0-alpha.50": + version "3.0.0-alpha.50" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.0.0-alpha.50.tgz#794c6a8d301840a49b55f5b331c7be84b9723643" + integrity sha512-QeWFCQOtS9D+Fi20liKsPXF2j/xWKh52e+P2Z1UATIdPMqmH6zoB2lcUz+cgv6PPVgWUtECeR6VSSUm71LT94w== "@docsearch/react@^3.0.0-alpha.39": - version "3.0.0-alpha.42" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.0.0-alpha.42.tgz#1d22a2b05779f24d090ff8d7ff2699e4d50dff5c" - integrity sha512-1aOslZJDxwUUcm2QRNmlEePUgL8P5fOAeFdOLDMctHQkV2iTja9/rKVbkP8FZbIUnZxuuCCn8ErLrjD/oXWOag== + version "3.0.0-alpha.50" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.0.0-alpha.50.tgz#a7dc547836c2b221fd3aa8eb87bfb47a579ef141" + integrity sha512-oDGV1zZCRYv7MWsh6CyQVthYTRc3b4q+6kKwNYb1/g/Wf/4nJHutpxolFLHdEUDhrJ4Xi8wxwQG+lEwAVBTHPg== dependencies: - "@algolia/autocomplete-core" "1.5.0" - "@algolia/autocomplete-preset-algolia" "1.5.0" - "@docsearch/css" "3.0.0-alpha.42" + "@algolia/autocomplete-core" "1.5.2" + "@algolia/autocomplete-preset-algolia" "1.5.2" + "@docsearch/css" "3.0.0-alpha.50" algoliasearch "^4.0.0" "@docusaurus/core@2.0.0-beta.15": @@ -1851,17 +1532,35 @@ url-loader "^4.1.1" "@hapi/hoek@^9.0.0": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" - integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== + version "9.2.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.1.tgz#9551142a1980503752536b5050fd99f4a7f13b17" + integrity sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw== "@hapi/topo@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" - integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== dependencies: "@hapi/hoek" "^9.0.0" +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@mdx-js/mdx@1.6.22", "@mdx-js/mdx@^1.6.21": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" @@ -1906,38 +1605,31 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@nodelib/fs.scandir@2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" - integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" - integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" - integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@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" - integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== - -"@sideway/address@^4.1.0": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" - integrity sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ== - dependencies: - "@hapi/hoek" "^9.0.0" +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.21" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" + integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== "@sideway/address@^4.1.3": version "4.1.3" @@ -2118,31 +1810,26 @@ dependencies: "@types/node" "*" -"@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== +"@types/eslint-scope@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== 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== + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "0.0.47" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" - integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== - -"@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/estree@*", "@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.28" @@ -2153,7 +1840,7 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*": +"@types/express@*", "@types/express@^4.17.13": version "4.17.13" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== @@ -2164,9 +1851,9 @@ "@types/serve-static" "*" "@types/hast@^2.0.0": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9" - integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q== + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== dependencies: "@types/unist" "*" @@ -2182,20 +1869,15 @@ dependencies: "@types/node" "*" -"@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== - -"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== "@types/mdast@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" - integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw== + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" + integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== dependencies: "@types/unist" "*" @@ -2204,15 +1886,10 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== -"@types/node@*": - version "14.14.35" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313" - integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag== - -"@types/node@^17.0.5": - version "17.0.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.14.tgz#33b9b94f789a8fedd30a68efdbca4dbb06b61f20" - integrity sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng== +"@types/node@*", "@types/node@^17.0.5": + version "17.0.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.18.tgz#3b4fed5cfb58010e3a2be4b6e74615e4847f1074" + integrity sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA== "@types/parse-json@^4.0.0": version "4.0.0" @@ -2240,9 +1917,9 @@ integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== "@types/react@*": - version "17.0.38" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd" - integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ== + version "17.0.39" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" + integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2254,9 +1931,9 @@ integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== "@types/sax@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.1.tgz#e0248be936ece791a82db1a57f3fb5f7c87e8172" - integrity sha512-dqYdvN7Sbw8QT/0Ci5rhjE4/iCMJEM0Y9rHpCu+gGXD9Lwbz28t6HI2yegsB6BoV1sShRMU6lAmAcgRjmFy7LA== + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.4.tgz#8221affa7f4f3cb21abd22f244cfabfa63e6a69e" + integrity sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw== dependencies: "@types/node" "*" @@ -2288,9 +1965,9 @@ "@types/node" "*" "@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== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" + integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== "@types/ws@^8.2.2": version "8.2.2" @@ -2430,13 +2107,13 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-dynamic-import@^4.0.0: version "4.0.0" @@ -2454,21 +2131,16 @@ acorn-jsx@^5.0.1: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" - integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^6.1.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.4.1: +acorn@^8.0.4, acorn@^8.4.1: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== @@ -2516,9 +2188,9 @@ ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: uri-js "^4.2.2" ajv@^8.0.0, ajv@^8.8.0: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" - integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2532,27 +2204,7 @@ algoliasearch-helper@^3.5.5: dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.0.0: - version "4.8.6" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.8.6.tgz#8d6d7d2315bb052705a8ef5c8dbf57a19d357c2b" - integrity sha512-G8IA3lcgaQB4r9HuQ4G+uSFjjz0Wv2OgEPiQ8emA+G2UUlroOfMl064j1bq/G+QTW0LmTQp9JwrFDRWxFM9J7w== - dependencies: - "@algolia/cache-browser-local-storage" "4.8.6" - "@algolia/cache-common" "4.8.6" - "@algolia/cache-in-memory" "4.8.6" - "@algolia/client-account" "4.8.6" - "@algolia/client-analytics" "4.8.6" - "@algolia/client-common" "4.8.6" - "@algolia/client-recommendation" "4.8.6" - "@algolia/client-search" "4.8.6" - "@algolia/logger-common" "4.8.6" - "@algolia/logger-console" "4.8.6" - "@algolia/requester-browser-xhr" "4.8.6" - "@algolia/requester-common" "4.8.6" - "@algolia/requester-node-http" "4.8.6" - "@algolia/transporter" "4.8.6" - -algoliasearch@^4.10.5: +algoliasearch@^4.0.0, algoliasearch@^4.10.5: version "4.12.1" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.12.1.tgz#574a2c5424c4b6681c026928fb810be2d2ec3924" integrity sha512-c0dM1g3zZBJrkzE5GA/Nu1y3fFxx3LCzxKzcmp2dgGS8P4CjszB/l3lsSh2MSrrK1Hn/KV4BlbBMXtYgG1Bfrw== @@ -2573,27 +2225,17 @@ algoliasearch@^4.10.5: "@algolia/transporter" "4.12.1" ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== dependencies: - string-width "^3.0.0" + string-width "^4.1.0" ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -2627,9 +2269,9 @@ anymatch@~3.1.2: picomatch "^2.0.4" arg@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.0.tgz#a20e2bb5710e82950a516b3f933fee5ed478be90" - integrity sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ== + version "5.0.1" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.1.tgz#eb0c9a8f77786cad2af8ff2b862899842d7b6adb" + integrity sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA== argparse@^1.0.7: version "1.0.10" @@ -2692,17 +2334,17 @@ autoprefixer@^10.3.5, autoprefixer@^10.3.7: picocolors "^1.0.0" postcss-value-parser "^4.2.0" -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== +axios@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" + integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g== dependencies: - follow-redirects "^1.14.0" + follow-redirects "^1.14.7" babel-loader@^8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" - integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== + version "8.2.3" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" + integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw== dependencies: find-cache-dir "^3.3.1" loader-utils "^1.4.0" @@ -2748,12 +2390,12 @@ babel-plugin-polyfill-corejs2@^0.3.0: semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060" - integrity sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A== + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.20.0" + core-js-compat "^3.21.0" babel-plugin-polyfill-regenerator@^0.3.0: version "0.3.1" @@ -2797,21 +2439,21 @@ bluebird@^3.7.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== dependencies: - bytes "3.1.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" depd "~1.1.2" - http-errors "1.7.2" + http-errors "1.8.1" iconv-lite "0.4.24" on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" bonjour@^3.5.0: version "3.5.0" @@ -2830,21 +2472,7 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -boxen@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.0.0.tgz#64fe9b16066af815f51057adcc800c3730120854" - integrity sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.0" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -boxen@^5.0.1: +boxen@^5.0.0, boxen@^5.0.1: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== @@ -2873,18 +2501,7 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.0.0, browserslist@^4.14.5: - version "4.16.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" - integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== - dependencies: - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - electron-to-chromium "^1.3.649" - escalade "^3.1.1" - node-releases "^1.1.70" - -browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1: version "4.19.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== @@ -2909,9 +2526,9 @@ buble-jsx-only@^0.19.8: regexpu-core "^4.5.4" buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-indexof@^1.0.0: version "1.1.1" @@ -2923,10 +2540,10 @@ bytes@3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacheable-request@^6.0.0: version "6.1.0" @@ -2968,9 +2585,9 @@ camelcase-css@2.0.1: integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-api@^3.0.0: version "3.0.0" @@ -2982,15 +2599,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001181: - 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.30001286, caniuse-lite@^1.0.30001297: - version "1.0.30001304" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001304.tgz#38af55ed3fc8220cb13e35e6e7309c8c65a05559" - integrity sha512-bdsfZd6K6ap87AGqSHJP/s1V+U6Z5lyrcbBu3ovbCCf8cSYpwTtGrCBObMpJqwxfTbLW6YTIdbb1jEeTelcpYQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001297: + version "1.0.30001312" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" + integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== ccount@^1.0.0, ccount@^1.0.3: version "1.1.0" @@ -3006,15 +2618,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.2: +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3083,7 +2687,7 @@ cheerio@^1.0.0-rc.10: parse5-htmlparser2-tree-adapter "^6.0.1" tslib "^2.2.0" -chokidar@^3.4.2, chokidar@^3.5.2: +chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3099,11 +2703,9 @@ chokidar@^3.4.2, chokidar@^3.5.2: fsevents "~2.3.2" 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" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^2.0.0: version "2.0.0" @@ -3111,9 +2713,9 @@ ci-info@^2.0.0: integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 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== + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== clean-css@^5.1.5, clean-css@^5.2.2: version "5.2.4" @@ -3187,11 +2789,6 @@ colord@^2.9.1: resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1" integrity sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ== -colorette@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== - colorette@^2.0.10: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" @@ -3284,12 +2881,12 @@ content-disposition@0.5.2: resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - safe-buffer "5.1.2" + safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.4" @@ -3297,9 +2894,9 @@ content-type@~1.0.4: integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -3308,10 +2905,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== copy-text-to-clipboard@^3.0.1: version "3.0.1" @@ -3330,28 +2927,28 @@ copy-webpack-plugin@^10.2.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.20.0, core-js-compat@^3.20.2: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" - integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== +core-js-compat@^3.20.2, core-js-compat@^3.21.0: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" + integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== dependencies: browserslist "^4.19.1" semver "7.0.0" core-js-pure@^3.20.2: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.3.tgz#6cc4f36da06c61d95254efc54024fe4797fd5d02" - integrity sha512-Q2H6tQ5MtPtcC7f3HxJ48i4Q7T9ybPKgvWyuH7JXIoNa2pm0KuBnycsET/qw1SLLZYfbsbrZQNMeIOClb+6WIA== + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" + integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== core-js@^3.18.0: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.3.tgz#c710d0a676e684522f3db4ee84e5e18a9d11d69a" - integrity sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag== + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" + integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^6.0.0: version "6.0.0" @@ -3364,18 +2961,7 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cosmiconfig@^7.0.1: +cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== @@ -3386,12 +2972,12 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -cross-fetch@^3.0.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.2.tgz#ee0c2f18844c4fde36150c2a4ddc068d20c1bc41" - integrity sha512-+JhD65rDNqLbGmB3Gzs3HrEKC0aQnD+XA3SY6RjgkF88jV2q5cTc5+CwxlS3sdmLk98gpPt5CF9XRnPdlxZe6w== +cross-fetch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== dependencies: - node-fetch "2.6.1" + node-fetch "2.6.7" cross-spawn@^7.0.3: version "7.0.3" @@ -3415,17 +3001,17 @@ css-declaration-sorter@^6.0.3: timsort "^0.3.0" css-loader@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" - integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + version "6.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3" + integrity sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg== dependencies: icss-utils "^5.1.0" - postcss "^8.2.15" + postcss "^8.4.5" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" + postcss-value-parser "^4.2.0" semver "^7.3.5" css-minimizer-webpack-plugin@^3.3.1: @@ -3461,15 +3047,7 @@ css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" -css-tree@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5" - integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-tree@^1.1.3: +css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== @@ -3493,63 +3071,63 @@ cssesc@^3.0.0: integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== cssnano-preset-advanced@^5.1.4: - version "5.1.11" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.1.11.tgz#43242fc1686dd0ed063affd6aced01df5d9161e7" - integrity sha512-M9f/4oRh5oxVUOtpKztACqtwAtcvHoWpEIB7axIxnLwhndvEMi7MtwPAOnKdSPBvH3RDGE80AL2JJ/e3Ruv2Qg== + version "5.1.12" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.1.12.tgz#11f5b0c4e3c32bcfd475465a283fa14dec8df972" + integrity sha512-5WWV9mbqVNwH4nRjs5UbhNl7eKo+16eYNzGogmz0Sa6iqWUeLdN8oo83WuTTqz5vjEKhTbRM5oX6WV1i6ees6g== dependencies: autoprefixer "^10.3.7" - cssnano-preset-default "^5.1.11" - postcss-discard-unused "^5.0.2" - postcss-merge-idents "^5.0.2" - postcss-reduce-idents "^5.0.2" - postcss-zindex "^5.0.1" + cssnano-preset-default "^5.1.12" + postcss-discard-unused "^5.0.3" + postcss-merge-idents "^5.0.3" + postcss-reduce-idents "^5.0.3" + postcss-zindex "^5.0.2" -cssnano-preset-default@^5.1.11: - version "5.1.11" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.11.tgz#db10fb1ecee310e8285c5aca45bd8237be206828" - integrity sha512-ETet5hqHxmzQq2ynXMOQofKuLm7VOjMiOB7E2zdtm/hSeCKlD9fabzIUV4GoPcRyJRHi+4kGf0vsfGYbQ4nmPw== +cssnano-preset-default@^5.1.12: + version "5.1.12" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.12.tgz#64e2ad8e27a279e1413d2d2383ef89a41c909be9" + integrity sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w== dependencies: css-declaration-sorter "^6.0.3" - cssnano-utils "^3.0.1" + cssnano-utils "^3.0.2" postcss-calc "^8.2.0" - postcss-colormin "^5.2.4" - postcss-convert-values "^5.0.3" - postcss-discard-comments "^5.0.2" - postcss-discard-duplicates "^5.0.2" - postcss-discard-empty "^5.0.2" - postcss-discard-overridden "^5.0.3" - postcss-merge-longhand "^5.0.5" - postcss-merge-rules "^5.0.5" - postcss-minify-font-values "^5.0.3" - postcss-minify-gradients "^5.0.5" - postcss-minify-params "^5.0.4" - postcss-minify-selectors "^5.1.2" - postcss-normalize-charset "^5.0.2" - postcss-normalize-display-values "^5.0.2" - postcss-normalize-positions "^5.0.3" - postcss-normalize-repeat-style "^5.0.3" - postcss-normalize-string "^5.0.3" - postcss-normalize-timing-functions "^5.0.2" - postcss-normalize-unicode "^5.0.3" - postcss-normalize-url "^5.0.4" - postcss-normalize-whitespace "^5.0.3" - postcss-ordered-values "^5.0.4" - postcss-reduce-initial "^5.0.2" - postcss-reduce-transforms "^5.0.3" - postcss-svgo "^5.0.3" - postcss-unique-selectors "^5.0.3" + postcss-colormin "^5.2.5" + postcss-convert-values "^5.0.4" + postcss-discard-comments "^5.0.3" + postcss-discard-duplicates "^5.0.3" + postcss-discard-empty "^5.0.3" + postcss-discard-overridden "^5.0.4" + postcss-merge-longhand "^5.0.6" + postcss-merge-rules "^5.0.6" + postcss-minify-font-values "^5.0.4" + postcss-minify-gradients "^5.0.6" + postcss-minify-params "^5.0.5" + postcss-minify-selectors "^5.1.3" + postcss-normalize-charset "^5.0.3" + postcss-normalize-display-values "^5.0.3" + postcss-normalize-positions "^5.0.4" + postcss-normalize-repeat-style "^5.0.4" + postcss-normalize-string "^5.0.4" + postcss-normalize-timing-functions "^5.0.3" + postcss-normalize-unicode "^5.0.4" + postcss-normalize-url "^5.0.5" + postcss-normalize-whitespace "^5.0.4" + postcss-ordered-values "^5.0.5" + postcss-reduce-initial "^5.0.3" + postcss-reduce-transforms "^5.0.4" + postcss-svgo "^5.0.4" + postcss-unique-selectors "^5.0.4" -cssnano-utils@^3.0.0, cssnano-utils@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.0.1.tgz#d3cc0a142d3d217f8736837ec0a2ccff6a89c6ea" - integrity sha512-VNCHL364lh++/ono+S3j9NlUK+d97KNkxI77NlqZU2W3xd2/qmyN61dsa47pTpb55zuU4G4lI7qFjAXZJH1OAQ== +cssnano-utils@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.0.2.tgz#d82b4991a27ba6fec644b39bab35fe027137f516" + integrity sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ== cssnano@^5.0.6, cssnano@^5.0.8: - version "5.0.16" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.16.tgz#4ee97d30411693f3de24cef70b36f7ae2a843e04" - integrity sha512-ryhRI9/B9VFCwPbb1z60LLK5/ldoExi7nwdnJzpkLZkm2/r7j2X3jfY+ZvDVJhC/0fPZlrAguYdHNFg0iglPKQ== + version "5.0.17" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.17.tgz#ff45713c05cfc780a1aeb3e663b6f224d091cabf" + integrity sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw== dependencies: - cssnano-preset-default "^5.1.11" + cssnano-preset-default "^5.1.12" lilconfig "^2.0.3" yaml "^1.10.2" @@ -3580,9 +3158,9 @@ debug@^3.1.1: ms "^2.1.1" debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -3676,9 +3254,9 @@ detab@2.0.4: repeat-string "^1.5.4" detect-node@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" - integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== detect-port-alt@^1.1.6: version "1.1.6" @@ -3760,12 +3338,7 @@ domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domelementtype@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" - integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== - -domelementtype@^2.2.0: +domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== @@ -3777,14 +3350,7 @@ 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" - -domhandler@^4.3.0: +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== @@ -3846,20 +3412,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.649: - version "1.3.698" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz#5de813960f23581a268718a0058683dffa15d221" - integrity sha512-VEXDzYblnlT+g8Q3gedwzgKOso1evkeJzV8lih7lV8mL8eAnGVnKyC3KsFT6S+R5PQO4ffdr1PI16/ElibY/kQ== - electron-to-chromium@^1.4.17: - version "1.4.59" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.59.tgz#657f2588c048fb95975779f8fea101fad854de89" - integrity sha512-AOJ3cAE0TWxz4fQ9zkND5hWrQg16nsZKVz9INOot1oV//u4wWu5xrj9CQMmPTYskkZRunSRc9sAnr4EkexXokg== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + version "1.4.71" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6" + integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw== emoji-regex@^8.0.0: version "8.0.0" @@ -3889,9 +3445,9 @@ end-of-stream@^1.1.0: once "^1.4.0" enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + version "5.9.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz#49ac24953ac8452ed8fed2ef1340fc8e043667ee" + integrity sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3974,9 +3530,9 @@ estraverse@^4.1.1: integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" @@ -4011,9 +3567,9 @@ events@^3.2.0: integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== execa@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" get-stream "^6.0.0" @@ -4026,16 +3582,16 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + version "4.17.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" + body-parser "1.19.2" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.0" + cookie "0.4.2" cookie-signature "1.0.6" debug "2.6.9" depd "~1.1.2" @@ -4049,13 +3605,13 @@ express@^4.17.1: on-finished "~2.3.0" parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" + proxy-addr "~2.0.7" + qs "6.9.7" range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" statuses "~1.5.0" type-is "~1.6.18" utils-merge "1.0.1" @@ -4078,18 +3634,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 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: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - fast-glob@^3.2.7, fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" @@ -4114,16 +3658,16 @@ fast-url-parser@1.1.3: punycode "^1.3.2" fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" faye-websocket@^0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" @@ -4139,18 +3683,18 @@ fbjs-css-vars@^1.0.0: resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== -fbjs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165" - integrity sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg== +fbjs@^3.0.0, fbjs@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6" + integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ== dependencies: - cross-fetch "^3.0.4" + cross-fetch "^3.1.5" fbjs-css-vars "^1.0.0" loose-envify "^1.0.0" object-assign "^4.1.0" promise "^7.1.1" setimmediate "^1.0.5" - ua-parser-js "^0.7.18" + ua-parser-js "^0.7.30" feed@^4.2.2: version "4.2.2" @@ -4193,9 +3737,9 @@ finalhandler@~1.1.2: unpipe "~1.0.0" 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== + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== dependencies: commondir "^1.0.1" make-dir "^3.0.2" @@ -4225,17 +3769,17 @@ find-up@^5.0.0: path-exists "^4.0.0" flux@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.1.tgz#7843502b02841d4aaa534af0b373034a1f75ee5c" - integrity sha512-emk4RCvJ8RzNP2lNpphKnG7r18q8elDYNAPx7xn+bDeOIo9FFfxEfIQ2y6YbQNmnsGD3nH1noxtLE64Puz1bRQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.3.tgz#573b504a24982c4768fdfb59d8d2ea5637d72ee7" + integrity sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw== dependencies: fbemitter "^3.0.0" - fbjs "^3.0.0" + fbjs "^3.0.1" -follow-redirects@^1.0.0, follow-redirects@^1.14.0: - version "1.14.7" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" - integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== +follow-redirects@^1.0.0, follow-redirects@^1.14.7: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.0" @@ -4256,15 +3800,15 @@ fork-ts-checker-webpack-plugin@^6.5.0: semver "^7.3.2" tapable "^1.0.0" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fraction.js@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.2.tgz#13e420a92422b6cf244dff8690ed89401029fbe8" - integrity sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA== + version "4.1.3" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.3.tgz#be65b0f20762ef27e1e793860bc2dfb716e99e65" + integrity sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg== fresh@0.5.2: version "0.5.2" @@ -4344,16 +3888,16 @@ get-stream@^5.1.0: pump "^3.0.0" get-stream@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== github-slugger@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.4.0.tgz#206eb96cdb22ee56fdc53a28d5a302338463444e" integrity sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ== -glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -4412,19 +3956,7 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globby@^11.0.1, globby@^11.0.2: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@^11.0.4: +globby@^11.0.1, globby@^11.0.2, globby@^11.0.4: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -4465,12 +3997,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -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== - -graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.9" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== @@ -4507,11 +4034,18 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1: +has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has-yarn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" @@ -4718,16 +4252,16 @@ http-deceiver@^1.2.7: resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== dependencies: depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" + inherits "2.0.4" + setprototypeof "1.2.0" statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" + toidentifier "1.0.1" http-errors@~1.6.2: version "1.6.3" @@ -4739,26 +4273,15 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - http-parser-js@>=0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" - integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== + version "0.5.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== http-proxy-middleware@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz#94d7593790aad6b3de48164f13792262f656c332" - integrity sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g== + version "2.0.3" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz#5df04f69a89f530c2284cd71eeaa51ba52243289" + integrity sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -4792,11 +4315,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== -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - ignore@^5.1.9, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -4837,11 +4355,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - infima@0.2.0-alpha.37: version "0.2.0-alpha.37" resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.37.tgz#b87ff42d528d6d050098a560f0294fbdd12adb78" @@ -4914,11 +4427,12 @@ is-alphanumerical@^1.0.0: is-decimal "^1.0.0" is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -4944,14 +4458,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - -is-core-module@^2.8.0: +is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== @@ -4959,21 +4466,18 @@ is-core-module@^2.8.0: has "^1.0.3" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" is-decimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== -is-docker@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" - integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== - -is-docker@^2.1.1: +is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== @@ -4988,24 +4492,12 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-glob@^4.0.3: +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -5073,12 +4565,12 @@ is-plain-object@^2.0.4: isobject "^3.0.1" is-regex@^1.0.4: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.1" + has-tostringtag "^1.0.0" is-regexp@^1.0.0: version "1.0.0" @@ -5091,9 +4583,9 @@ is-root@^2.1.0: integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-typedarray@^1.0.0: version "1.0.0" @@ -5143,26 +4635,15 @@ isobject@^3.0.1: integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= jest-worker@^27.0.2, jest-worker@^27.4.5: - version "27.4.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" - integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw== + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" -joi@^17.4.0: - version "17.4.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" - integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.0" - "@sideway/formula" "^3.0.0" - "@sideway/pinpoint" "^2.0.0" - -joi@^17.4.2: +joi@^17.4.2, joi@^17.6.0: version "17.6.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2" integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw== @@ -5291,9 +4772,9 @@ lilconfig@^2.0.3: integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== loader-runner@^4.2.0: version "4.2.0" @@ -5310,9 +4791,9 @@ loader-utils@^1.4.0: json5 "^1.0.1" loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -5425,11 +4906,6 @@ lodash.some@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= -lodash.toarray@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" - integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= - lodash.uniq@4.5.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -5565,15 +5041,7 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -micromatch@^4.0.4: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -5581,12 +5049,7 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -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" - integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== - -mime-db@1.51.0: +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": version "1.51.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== @@ -5603,14 +5066,7 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24: - version "2.1.29" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" - integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== - dependencies: - mime-db "1.46.0" - -mime-types@^2.1.31: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== @@ -5622,11 +5078,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.3.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -5659,13 +5110,20 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -5678,22 +5136,22 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.5" +mrmime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.0.tgz#14d387f0585a5233d291baba339b063752a2398b" + integrity sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5712,14 +5170,14 @@ multicast-dns@^6.0.1: thunky "^1.0.2" nanoid@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.6.2: version "2.6.2" @@ -5735,31 +5193,28 @@ no-case@^3.0.4: tslib "^2.0.3" node-emoji@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" - integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== dependencies: - lodash.toarray "^4.4.0" + lodash "^4.17.21" -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" node-forge@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== -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@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -6047,7 +5502,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -6079,12 +5534,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -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" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -6113,54 +5563,54 @@ portfinder@^1.0.28: mkdirp "^0.5.5" postcss-calc@^8.2.0: - version "8.2.3" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.3.tgz#53b95ce93de19213c2a5fdd71277a81690ef41d0" - integrity sha512-EGM2EBBWqP57N0E7N7WOLT116PJ39dwHVU01WO4XPPQLJfkL2xVgkMZ+TZvCfapj/uJH07UEfKHQNPHzSw/14Q== + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== dependencies: - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.2" + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" -postcss-colormin@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.4.tgz#7726d3f3d24f111d39faff50a6500688225d5324" - integrity sha512-rYlC5015aNqVQt/B6Cy156g7sH5tRUJGmT9xeagYthtKehetbKx7jHxhyLpulP4bs4vbp8u/B2rac0J7S7qPQg== +postcss-colormin@^5.2.5: + version "5.2.5" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.5.tgz#d1fc269ac2ad03fe641d462b5d1dada35c69968a" + integrity sha512-+X30aDaGYq81mFqwyPpnYInsZQnNpdxMX0ajlY7AExCexEFkPVV+KrO7kXwayqEWL2xwEbNQ4nUO0ZsRWGnevg== dependencies: browserslist "^4.16.6" caniuse-api "^3.0.0" colord "^2.9.1" postcss-value-parser "^4.2.0" -postcss-convert-values@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.3.tgz#492db08a28af84d57651f10edc8f6c8fb2f6df40" - integrity sha512-fVkjHm2T0PSMqXUCIhHNWVGjhB9mHEWX2GboVs7j3iCgr6FpIl9c/IdXy0PHWZSQ9LFTRgmj98amxJE6KOnlsA== +postcss-convert-values@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.4.tgz#3e74dd97c581f475ae7b4500bc0a7c4fb3a6b1b6" + integrity sha512-bugzSAyjIexdObovsPZu/sBCTHccImJxLyFgeV0MmNBm/Lw5h5XnjfML6gzEmJ3A6nyfCW7hb1JXzcsA4Zfbdw== dependencies: postcss-value-parser "^4.2.0" -postcss-discard-comments@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.2.tgz#811ed34e2b6c40713daab0beb4d7a04125927dcd" - integrity sha512-6VQ3pYTsJHEsN2Bic88Aa7J/Brn4Bv8j/rqaFQZkH+pcVkKYwxCIvoMQkykEW7fBjmofdTnQgcivt5CCBJhtrg== - -postcss-discard-duplicates@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.2.tgz#61076f3d256351bdaac8e20aade730fef0609f44" - integrity sha512-LKY81YjUjc78p6rbXIsnppsaFo8XzCoMZkXVILJU//sK0DgPkPSpuq/cZvHss3EtdKvWNYgWzQL+wiJFtEET4g== - -postcss-discard-empty@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.2.tgz#0676a9bcfc44bb00d338352a45ab80845a31d8f0" - integrity sha512-SxBsbTjlsKUvZLL+dMrdWauuNZU8TBq5IOL/DHa6jBUSXFEwmDqeXRfTIK/FQpPTa8MJMxEHjSV3UbiuyLARPQ== - -postcss-discard-overridden@^5.0.3: +postcss-discard-comments@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.3.tgz#004b9818cabb407e60616509267567150b327a3f" - integrity sha512-yRTXknIZA4k8Yo4FiF1xbsLj/VBxfXEWxJNIrtIy6HC9KQ4xJxcPtoaaskh6QptCGrrcGnhKsTsENTRPZOBu4g== + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz#011acb63418d600fdbe18804e1bbecb543ad2f87" + integrity sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q== -postcss-discard-unused@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.0.2.tgz#674bad5fde61517217e7e056015fda694e0cb722" - integrity sha512-vP5MOINH2LouL2slqENa8vmKphKjv+VOeeAdlUfySkwi3HoaW1p7++Oh8bqRQzoAmeTrf5G6CHzxa7xMXFNkIA== +postcss-discard-duplicates@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz#10f202a4cfe9d407b73dfea7a477054d21ea0c1f" + integrity sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw== + +postcss-discard-empty@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz#ec185af4a3710b88933b0ff751aa157b6041dd6a" + integrity sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA== + +postcss-discard-overridden@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz#cc999d6caf18ea16eff8b2b58f48ec3ddee35c9c" + integrity sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg== + +postcss-discard-unused@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.0.3.tgz#89fd3ebdbed8320df77a4ad503bd83cff52409f5" + integrity sha512-WO6FJxL5fGnuE77ZbTcZ/nRZJ4+TOqNaqLBLWgkR4e+WdmHn77OHPyQmsRv7eOB2rLKL6tsq2bs1GwoKXD/++Q== dependencies: postcss-selector-parser "^6.0.5" @@ -6173,61 +5623,61 @@ postcss-loader@^6.1.1: klona "^2.0.5" semver "^7.3.5" -postcss-merge-idents@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.0.2.tgz#d67d9505857a9546c3f7a305386e4147497322d6" - integrity sha512-V8IlmvQez+/mB06touksO3lUKtzL3ZKfBxfXFK2q136TOyOLXBuoI8kQwZsIOFWUfA8gk/XpFtmMsqURqYPk6Q== +postcss-merge-idents@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.0.3.tgz#04f333f32767bd7b7b002f0032da347ec3c8c484" + integrity sha512-Z4LCzh2WzMn69KaS2FaJcrIeDQ170V13QHq+0hnBEFKJJkD+y5qndZ/bl3AhpddrSrXWIVR+xAwjmHQIJI2Eog== dependencies: - cssnano-utils "^3.0.0" + cssnano-utils "^3.0.2" postcss-value-parser "^4.2.0" -postcss-merge-longhand@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.5.tgz#cbc217ca22fb5a3e6ee22a6a1aa6920ec1f3c628" - integrity sha512-R2BCPJJ/U2oh1uTWEYn9CcJ7MMcQ1iIbj9wfr2s/zHu5om5MP/ewKdaunpfJqR1WYzqCsgnXuRoVXPAzxdqy8g== +postcss-merge-longhand@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.6.tgz#090e60d5d3b3caad899f8774f8dccb33217d2166" + integrity sha512-rkmoPwQO6ymJSmWsX6l2hHeEBQa7C4kJb9jyi5fZB1sE8nSCv7sqchoYPixRwX/yvLoZP2y6FA5kcjiByeJqDg== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^5.0.2" + stylehacks "^5.0.3" -postcss-merge-rules@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.5.tgz#2a18669ec214019884a60f0a0d356803a8138366" - integrity sha512-3Oa26/Pb9VOFVksJjFG45SNoe4nhGvJ2Uc6TlRimqF8uhfOCEhVCaJ3rvEat5UFOn2UZqTY5Da8dFgCh3Iq0Ug== +postcss-merge-rules@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.6.tgz#26b37411fe1e80202fcef61cab027265b8925f2b" + integrity sha512-nzJWJ9yXWp8AOEpn/HFAW72WKVGD2bsLiAmgw4hDchSij27bt6TF+sIK0cJUBAYT3SGcjtGGsOR89bwkkMuMgQ== dependencies: browserslist "^4.16.6" caniuse-api "^3.0.0" - cssnano-utils "^3.0.1" + cssnano-utils "^3.0.2" postcss-selector-parser "^6.0.5" -postcss-minify-font-values@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.3.tgz#48c455c4cd980ecd07ac9bf3fc58e9d8a2ae4168" - integrity sha512-bC45rVzEwsLhv/cL1eCjoo2OOjbSk9I7HKFBYnBvtyuIZlf7uMipMATXtA0Fc3jwPo3wuPIW1jRJWKzflMh1sA== +postcss-minify-font-values@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.4.tgz#627d824406b0712243221891f40a44fffe1467fd" + integrity sha512-RN6q3tyuEesvyCYYFCRGJ41J1XFvgV+dvYGHr0CeHv8F00yILlN8Slf4t8XW4IghlfZYCeyRrANO6HpJ948ieA== dependencies: postcss-value-parser "^4.2.0" -postcss-minify-gradients@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.5.tgz#a5572b9c98ed52cbd7414db24b873f8b9e418290" - integrity sha512-/YjvXs8PepsoiZAIpjstOO4IHKwFAqYNqbA1yVdqklM84tbUUneh6omJxGlRlF3mi6K5Pa067Mg6IwqEnYC8Zg== +postcss-minify-gradients@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.6.tgz#b07cef51a93f075e94053fd972ff1cba2eaf6503" + integrity sha512-E/dT6oVxB9nLGUTiY/rG5dX9taugv9cbLNTFad3dKxOO+BQg25Q/xo2z2ddG+ZB1CbkZYaVwx5blY8VC7R/43A== dependencies: colord "^2.9.1" - cssnano-utils "^3.0.1" + cssnano-utils "^3.0.2" postcss-value-parser "^4.2.0" -postcss-minify-params@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.4.tgz#230a4d04456609e614db1d48c2eebc21f6490a45" - integrity sha512-Z0vjod9lRZEmEPfEmA2sCfjbfEEFKefMD3RDIQSUfXK4LpCyWkX1CniUgyNvnjJFLDPSxtgKzozhHhPHKoeGkg== +postcss-minify-params@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.5.tgz#86cb624358cd45c21946f8c317893f0449396646" + integrity sha512-YBNuq3Rz5LfLFNHb9wrvm6t859b8qIqfXsWeK7wROm3jSKNpO1Y5e8cOyBv6Acji15TgSrAwb3JkVNCqNyLvBg== dependencies: browserslist "^4.16.6" - cssnano-utils "^3.0.1" + cssnano-utils "^3.0.2" postcss-value-parser "^4.2.0" -postcss-minify-selectors@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.2.tgz#bc9698f713b9dab7f44f1ec30643fcbad9a043c0" - integrity sha512-gpn1nJDMCf3g32y/7kl+jsdamhiYT+/zmEt57RoT9GmzlixBNRPohI7k8UIHelLABhdLf3MSZhtM33xuH5eQOQ== +postcss-minify-selectors@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.3.tgz#6ac12d52aa661fd509469d87ab2cebb0a1e3a1b5" + integrity sha512-9RJfTiQEKA/kZhMaEXND893nBqmYQ8qYa/G+uPdVnXF6D/FzpfI6kwBtWEcHx5FqDbA79O9n6fQJfrIj6M8jvQ== dependencies: postcss-selector-parser "^6.0.5" @@ -6259,110 +5709,100 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-normalize-charset@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.2.tgz#eb6130c8a8e950ce25f9ea512de1d9d6a6f81439" - integrity sha512-fEMhYXzO8My+gC009qDc/3bgnFP8Fv1Ic8uw4ec4YTlhIOw63tGPk1YFd7fk9bZUf1DAbkhiL/QPWs9JLqdF2g== - -postcss-normalize-display-values@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.2.tgz#8b5273c6c7d0a445e6ef226b8a5bb3204a55fb99" - integrity sha512-RxXoJPUR0shSjkMMzgEZDjGPrgXUVYyWA/YwQRicb48H15OClPuaDR7tYokLAlGZ2tCSENEN5WxjgxSD5m4cUw== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^5.0.3: +postcss-normalize-charset@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.3.tgz#b63fcc4ff5fbf65934fafaf83270b2da214711d1" - integrity sha512-U+rmhjrNBvIGYqr/1tD4wXPFFMKUbXsYXvlUCzLi0tOCUS6LoeEAnmVXXJY/MEB/1CKZZwBSs2tmzGawcygVBA== - dependencies: - postcss-value-parser "^4.2.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz#719fb9f9ca9835fcbd4fed8d6e0d72a79e7b5472" + integrity sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA== -postcss-normalize-repeat-style@^5.0.3: +postcss-normalize-display-values@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.3.tgz#488c0ad8aac0fa4f66ef56cc8d604b3fd9bf705f" - integrity sha512-uk1+xYx0AMbA3nLSNhbDrqbf/rx+Iuq5tVad2VNyaxxJzx79oGieJ6D9F6AfOL2GtiIbP7vTYlpYHtG+ERFXTg== + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.3.tgz#94cc82e20c51cc4ffba6b36e9618adc1e50db8c1" + integrity sha512-FIV5FY/qs4Ja32jiDb5mVj5iWBlS3N8tFcw2yg98+8MkRgyhtnBgSC0lxU+16AMHbjX5fbSJgw5AXLMolonuRQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-string@^5.0.3: +postcss-normalize-positions@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.4.tgz#4001f38c99675437b83277836fb4291887fcc6cc" + integrity sha512-qynirjBX0Lc73ROomZE3lzzmXXTu48/QiEzKgMeqh28+MfuHLsuqC9po4kj84igZqqFGovz8F8hf44hA3dPYmQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.4.tgz#d005adf9ee45fae78b673031a376c0c871315145" + integrity sha512-Innt+wctD7YpfeDR7r5Ik6krdyppyAg2HBRpX88fo5AYzC1Ut/l3xaxACG0KsbX49cO2n5EB13clPwuYVt8cMA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.4.tgz#b5e00a07597e7aa8a871817bfeac2bfaa59c3333" + integrity sha512-Dfk42l0+A1CDnVpgE606ENvdmksttLynEqTQf5FL3XGQOyqxjbo25+pglCUvziicTxjtI2NLUR6KkxyUWEVubQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.3.tgz#49e0a1d58a119d5435ef21893ad03136a6e8f0e6" - integrity sha512-Mf2V4JbIDboNGQhW6xW0YREDiYXoX3WrD3EjKkjvnpAJ6W4qqjLnK/c9aioyVFaWWHVdP5zVRw/9DI5S3oLDFw== + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.3.tgz#47210227bfcba5e52650d7a18654337090de7072" + integrity sha512-QRfjvFh11moN4PYnJ7hia4uJXeFotyK3t2jjg8lM9mswleGsNw2Lm3I5wO+l4k1FzK96EFwEVn8X8Ojrp2gP4g== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-timing-functions@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.2.tgz#db4f4f49721f47667afd1fdc5edb032f8d9cdb2e" - integrity sha512-Ao0PP6MoYsRU1LxeVUW740ioknvdIUmfr6uAA3xWlQJ9s69/Tupy8qwhuKG3xWfl+KvLMAP9p2WXF9cwuk/7Bg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-unicode@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.3.tgz#10f0d30093598a58c48a616491cc7fa53256dd43" - integrity sha512-uNC7BmS/7h6to2UWa4RFH8sOTzu2O9dVWPE/F9Vm9GdhONiD/c1kNaCLbmsFHlKWcEx7alNUChQ+jH/QAlqsQw== +postcss-normalize-unicode@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.4.tgz#02866096937005cdb2c17116c690f29505a1623d" + integrity sha512-W79Regn+a+eXTzB+oV/8XJ33s3pDyFTND2yDuUCo0Xa3QSy1HtNIfRVPXNubHxjhlqmMFADr3FSCHT84ITW3ig== dependencies: browserslist "^4.16.6" postcss-value-parser "^4.2.0" -postcss-normalize-url@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz#3b0322c425e31dd275174d0d5db0e466f50810fb" - integrity sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg== +postcss-normalize-url@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.5.tgz#c39efc12ff119f6f45f0b4f516902b12c8080e3a" + integrity sha512-Ws3tX+PcekYlXh+ycAt0wyzqGthkvVtZ9SZLutMVvHARxcpu4o7vvXcNoiNKyjKuWecnjS6HDI3fjBuDr5MQxQ== dependencies: normalize-url "^6.0.1" postcss-value-parser "^4.2.0" -postcss-normalize-whitespace@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.3.tgz#fb6bcc9ff2f834448b802657c7acd0956f4591d1" - integrity sha512-333JWRnX655fSoUbufJ10HJop3c8mrpKkCCUnEmgz/Cb/QEtW+/TMZwDAUt4lnwqP6tCCk0x0b58jqvDgiQm/A== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^5.0.4: +postcss-normalize-whitespace@^5.0.4: version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.4.tgz#f799dca87a7f17526d31a20085e61768d0b00534" - integrity sha512-taKtGDZtyYUMVYkg+MuJeBUiTF6cGHZmo/qcW7ibvW79UlyKuSHbo6dpCIiqI+j9oJsXWzP+ovIxoyLDOeQFdw== - dependencies: - cssnano-utils "^3.0.1" - postcss-value-parser "^4.2.0" - -postcss-reduce-idents@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.0.2.tgz#526b171979c063796cec87b2864e5657c412fec0" - integrity sha512-R53mUIa6hJC+m1vKSFVrs+wU2J7vPAm35IWE3kz5VV1sx8XBXV2PU8yXGqI8Jm9RzfL7EUiJ5Kml5t/eEeD1XA== + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.4.tgz#1d477e7da23fecef91fc4e37d462272c7b55c5ca" + integrity sha512-wsnuHolYZjMwWZJoTC9jeI2AcjA67v4UuidDrPN9RnX8KIZfE+r2Nd6XZRwHVwUiHmRvKQtxiqo64K+h8/imaw== dependencies: postcss-value-parser "^4.2.0" -postcss-reduce-initial@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz#fa424ce8aa88a89bc0b6d0f94871b24abe94c048" - integrity sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw== +postcss-ordered-values@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.5.tgz#e878af822a130c3f3709737e24cb815ca7c6d040" + integrity sha512-mfY7lXpq+8bDEHfP+muqibDPhZ5eP9zgBEF9XRvoQgXcQe2Db3G1wcvjbnfjXG6wYsl+0UIjikqq4ym1V2jGMQ== + dependencies: + cssnano-utils "^3.0.2" + postcss-value-parser "^4.2.0" + +postcss-reduce-idents@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.0.3.tgz#b632796275b4fa1a4040799969dd17167eaf4d8b" + integrity sha512-9bj9/Xhwiti0Z35kkguJX4G6yUYVw8S1kRLU4jFSCTEuHu4yJggf4rNUoVnT45lm/vU97Wd593CxspMDbHxy4w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.3.tgz#68891594defd648253703bbd8f1093162f19568d" + integrity sha512-c88TkSnQ/Dnwgb4OZbKPOBbCaauwEjbECP5uAuFPOzQ+XdjNjRH7SG0dteXrpp1LlIFEKK76iUGgmw2V0xeieA== dependencies: browserslist "^4.16.6" caniuse-api "^3.0.0" -postcss-reduce-transforms@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.3.tgz#df60fab34698a43073e8b87938c71df7a3b040ac" - integrity sha512-yDnTUab5i7auHiNwdcL1f+pBnqQFf+7eC4cbC7D8Lc1FkvNZhtpkdad+9U4wDdFb84haupMf0rA/Zc5LcTe/3A== +postcss-reduce-transforms@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.4.tgz#717e72d30befe857f7d2784dba10eb1157863712" + integrity sha512-VIJB9SFSaL8B/B7AXb7KHL6/GNNbbCHslgdzS9UDfBZYIA2nx8NLY7iD/BXFSO/1sRUILzBTfHCoW5inP37C5g== dependencies: postcss-value-parser "^4.2.0" -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" - integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.5: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.9" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== @@ -6377,37 +5817,32 @@ postcss-sort-media-queries@^4.1.0: dependencies: sort-css-media-queries "2.0.4" -postcss-svgo@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30" - integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA== +postcss-svgo@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.4.tgz#cfa8682f47b88f7cd75108ec499e133b43102abf" + integrity sha512-yDKHvULbnZtIrRqhZoA+rxreWpee28JSRH/gy9727u0UCgtpv1M/9WEWY3xySlFa0zQJcqf6oCBJPR5NwkmYpg== dependencies: - postcss-value-parser "^4.1.0" + postcss-value-parser "^4.2.0" svgo "^2.7.0" -postcss-unique-selectors@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.3.tgz#07fd116a8fbd9202e7030f7c4952e7b52c26c63d" - integrity sha512-V5tX2hadSSn+miVCluuK1IDGy+7jAXSOfRZ2DQ+s/4uQZb/orDYBjH0CHgFrXsRw78p4QTuEFA9kI6C956UnHQ== +postcss-unique-selectors@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.4.tgz#08e188126b634ddfa615fb1d6c262bafdd64826e" + integrity sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ== dependencies: postcss-selector-parser "^6.0.5" -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-value-parser@^4.2.0: +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss-zindex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.0.1.tgz#c585724beb69d356af8c7e68847b28d6298ece03" - integrity sha512-nwgtJJys+XmmSGoYCcgkf/VczP8Mp/0OfSv3v0+fw0uABY4yxw+eFs0Xp9nAZHIKnS5j+e9ywQ+RD+ONyvl5pA== +postcss-zindex@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.0.2.tgz#7e48aee54062c93418593035229ea06b92381251" + integrity sha512-KPQFjQu73H35HLHmE8Wv31ygfQoucxD52oRm4FPFv1emYhFMzUQdF8adaXCevFLIHPRp2rRYfbaDiEqZ4YjVtw== -postcss@^8.2.15, postcss@^8.3.11, postcss@^8.3.5, postcss@^8.3.7: +postcss@^8.3.11, postcss@^8.3.5, postcss@^8.3.7, postcss@^8.4.5: version "8.4.6" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== @@ -6435,14 +5870,14 @@ pretty-time@^1.1.0: integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== prism-react-renderer@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89" - integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" + integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== prismjs@^1.23.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" - integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== + version "1.27.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== process-nextick-args@~2.0.0: version "2.0.1" @@ -6465,13 +5900,13 @@ prompts@^2.4.1, prompts@^2.4.2: sisteransi "^1.0.5" prop-types@^15.6.2, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" - react-is "^16.8.1" + react-is "^16.13.1" property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" @@ -6480,12 +5915,12 @@ property-information@^5.0.0, property-information@^5.3.0: dependencies: xtend "^4.0.0" -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" + forwarded "0.2.0" ipaddr.js "1.9.1" pump@^3.0.0: @@ -6523,10 +5958,10 @@ pure-color@^1.2.0: resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== querystring@0.2.0: version "0.2.0" @@ -6562,13 +5997,13 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== dependencies: - bytes "3.1.0" - http-errors "1.7.2" + bytes "3.1.2" + http-errors "1.8.1" iconv-lite "0.4.24" unpipe "1.0.0" @@ -6652,7 +6087,7 @@ react-helmet@^6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -6695,24 +6130,24 @@ react-router-config@^5.1.1: "@babel/runtime" "^7.1.2" react-router-dom@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" - integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== + version "5.3.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363" + integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ== dependencies: - "@babel/runtime" "^7.1.2" + "@babel/runtime" "^7.12.13" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.2.0" + react-router "5.2.1" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.2.0, react-router@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" - integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== +react-router@5.2.1, react-router@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d" + integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ== dependencies: - "@babel/runtime" "^7.1.2" + "@babel/runtime" "^7.12.13" history "^4.9.0" hoist-non-react-statics "^3.1.0" loose-envify "^1.3.1" @@ -6729,9 +6164,9 @@ react-side-effect@^2.1.0: integrity sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ== react-textarea-autosize@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz#4f9374d357b0a6f6469956726722549124a1b2db" - integrity sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q== + version "8.3.3" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8" + integrity sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ== dependencies: "@babel/runtime" "^7.10.2" use-composed-ref "^1.0.0" @@ -6794,12 +6229,12 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== dependencies: - regenerate "^1.4.0" + regenerate "^1.4.2" regenerate-unicode-properties@^9.0.0: version "9.0.0" @@ -6808,15 +6243,15 @@ regenerate-unicode-properties@^9.0.0: dependencies: regenerate "^1.4.2" -regenerate@^1.4.0, regenerate@^1.4.2: +regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== regenerator-transform@^0.14.2: version "0.14.5" @@ -6826,9 +6261,9 @@ regenerator-transform@^0.14.2: "@babel/runtime" "^7.8.4" regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" @@ -6845,17 +6280,17 @@ regexpu-core@^4.5.4: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -regexpu-core@^4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" registry-auth-token@^4.0.0: version "4.2.1" @@ -6871,17 +6306,15 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -regjsgen@^0.5.1, regjsgen@^0.5.2: +regjsgen@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.6.4: - version "0.6.9" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" - integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== - dependencies: - jsesc "~0.5.0" +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== regjsparser@^0.7.0: version "0.7.0" @@ -6890,6 +6323,13 @@ regjsparser@^0.7.0: dependencies: jsesc "~0.5.0" +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + rehype-parse@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.2.tgz#aeb3fdd68085f9f796f1d3137ae2b85a98406964" @@ -6914,13 +6354,13 @@ remark-admonitions@^1.2.1: unist-util-visit "^2.0.1" remark-emoji@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.1.0.tgz#69165d1181b98a54ad5d9ef811003d53d7ebc7db" - integrity sha512-lDddGsxXURV01WS9WAiS9rO/cedO1pvr9tahtLhr6qCGFhHG4yZSJW3Ha4Nw9Uk1hLNmUBtPC0+m45Ms+xEitg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" + integrity sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w== dependencies: emoticon "^3.2.0" node-emoji "^1.10.0" - unist-util-visit "^2.0.2" + unist-util-visit "^2.0.3" remark-footnotes@2.0.0: version "2.0.0" @@ -7030,23 +6470,15 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve@^1.1.6: - version "1.21.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" - integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== +resolve@^1.1.6, resolve@^1.14.2, resolve@^1.3.2: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.8.0" + is-core-module "^2.8.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.14.2, resolve@^1.3.2: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -7093,10 +6525,10 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.1.0: - version "7.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" - integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== +rxjs@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d" + integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ== dependencies: tslib "^2.1.0" @@ -7105,7 +6537,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.2.0: +safe-buffer@5.2.1, 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== @@ -7146,16 +6578,7 @@ schema-utils@^2.6.5: ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== - dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -7223,10 +6646,10 @@ semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== dependencies: debug "2.6.9" depd "~1.1.2" @@ -7235,9 +6658,9 @@ send@0.17.1: escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.7.2" + http-errors "1.8.1" mime "1.6.0" - ms "2.1.1" + ms "2.1.3" on-finished "~2.3.0" range-parser "~1.2.1" statuses "~1.5.0" @@ -7276,15 +6699,15 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.1" + send "0.17.2" setimmediate@^1.0.5: version "1.0.5" @@ -7296,10 +6719,10 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== shallow-clone@^3.0.0: version "3.0.1" @@ -7335,17 +6758,17 @@ shelljs@^0.8.4: rechoir "^0.6.2" signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== sirv@^1.0.7: - version "1.0.11" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.11.tgz#81c19a29202048507d6ec0d8ba8910fda52eb5a4" - integrity sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg== + version "1.0.19" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" + integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== dependencies: - "@polka/url" "^1.0.0-next.9" - mime "^2.3.1" + "@polka/url" "^1.0.0-next.20" + mrmime "^1.0.0" totalist "^1.0.0" sisteransi@^1.0.5: @@ -7374,12 +6797,12 @@ slash@^4.0.0: integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== sockjs@^0.3.21: - version "0.3.21" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" - integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== dependencies: faye-websocket "^0.11.3" - uuid "^3.4.0" + uuid "^8.3.2" websocket-driver "^0.7.4" sort-css-media-queries@2.0.4: @@ -7478,25 +6901,7 @@ std-env@^3.0.1: resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.0.1.tgz#bc4cbc0e438610197e34c2d79c3df30b491f5182" integrity sha512-mC1Ps9l77/97qeOZc+HrOL7TIaOboHqMZ24dGVQrlxFcpPpfCHpH+qfUT7Dz+6mlG8+JPA1KfBQo19iC/+Ngcw== -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string-width@^4.2.2: +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.2: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7528,21 +6933,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7583,10 +6974,10 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -stylehacks@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.2.tgz#fa10e5181c6e8dc0bddb4a3fb372e9ac42bba2ad" - integrity sha512-114zeJdOpTrbQYRD4OU5UWJ99LKUaqCPJTU1HQ/n3q3BwmllFN8kHENaLnOeqVq6AhXrWfxHNZTl33iJ4oy3cQ== +stylehacks@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.3.tgz#2ef3de567bfa2be716d29a93bf3d208c133e8d04" + integrity sha512-ENcUdpf4yO0E1rubu8rkxI+JGQk4CgjchynZ4bDBJDfqdy+uhTRSWb8/F3Jtu+Bw5MW45Po3/aQGeIyyxgQtxg== dependencies: browserslist "^4.16.6" postcss-selector-parser "^6.0.4" @@ -7641,9 +7032,9 @@ tapable@^1.0.0: integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== 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== + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.4: version "5.3.1" @@ -7681,9 +7072,9 @@ timsort@^0.3.0: integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= tiny-invariant@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" + integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== tiny-warning@^1.0.0, tiny-warning@^1.0.3: version "1.0.3" @@ -7707,16 +7098,21 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + trim-trailing-lines@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" @@ -7732,27 +7128,7 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== -ts-essentials@^2.0.3: - version "2.0.12" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" - integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== - -tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - -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== - -tslib@^2.2.0, tslib@^2.3.1: +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -7762,7 +7138,7 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-is@~1.6.17, type-is@~1.6.18: +type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -7777,10 +7153,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -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" - integrity sha512-8NFExdfI24Ny8R3Vc6+uUytP/I7dpqk3JERlvxPWlrtx5YboqCgxAXYKPAifbPLV2zKbgmmPL53ufW7mUC/VOQ== +ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== unherit@^1.0.4: version "1.1.3" @@ -7790,24 +7166,11 @@ unherit@^1.0.4: inherits "^2.0.0" xtend "^4.0.0" -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" @@ -7816,21 +7179,11 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - unicode-match-property-value-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== - unicode-property-aliases-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" @@ -7859,11 +7212,6 @@ unified@^8.4.2: trough "^1.0.0" vfile "^4.0.0" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -7906,9 +7254,9 @@ unist-util-remove@2.0.0: unist-util-is "^4.0.0" unist-util-remove@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.0.1.tgz#fa13c424ff8e964f3aa20d1098b9a690c6bfaa39" - integrity sha512-YtuetK6o16CMfG+0u4nndsWpujgsHDHHLyE0yGpJLLn5xSjKeyGyzEBOI2XbmoUHCYabmNgX52uxlWoQhcvR7Q== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" + integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== dependencies: unist-util-is "^4.0.0" @@ -7927,7 +7275,7 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.2: +unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.2, unist-util-visit@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== @@ -7998,11 +7346,9 @@ url@^0.11.0: querystring "0.2.0" use-composed-ref@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" - integrity sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg== - dependencies: - ts-essentials "^2.0.3" + version "1.2.1" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.2.1.tgz#9bdcb5ccd894289105da2325e1210079f56bf849" + integrity sha512-6+X1FLlIcjvFMAeAD/hcxDT8tmyrWnbSPMU0EnxQuDLIxokuFzWliXBiYZuGIx+mrAMLBw0WFfCkaPw8ebzAhw== use-isomorphic-layout-effect@^1.0.0: version "1.1.1" @@ -8036,10 +7382,10 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== value-equal@^1.0.1: version "1.0.1" @@ -8075,15 +7421,15 @@ vfile@^4.0.0: vfile-message "^2.0.0" wait-on@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" - integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== + version "6.0.1" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.1.tgz#16bbc4d1e4ebdd41c5b4e63a2e16dbd1f4e5601e" + integrity sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw== dependencies: - axios "^0.21.1" - joi "^17.4.0" + axios "^0.25.0" + joi "^17.6.0" lodash "^4.17.21" minimist "^1.2.5" - rxjs "^7.1.0" + rxjs "^7.5.4" watchpack@^2.3.1: version "2.3.1" @@ -8105,6 +7451,11 @@ web-namespaces@^1.0.0, web-namespaces@^1.1.2: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webpack-bundle-analyzer@^4.4.2: version "4.5.0" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5" @@ -8120,7 +7471,7 @@ webpack-bundle-analyzer@^4.4.2: sirv "^1.0.7" ws "^7.3.1" -webpack-dev-middleware@^5.3.0: +webpack-dev-middleware@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== @@ -8132,18 +7483,19 @@ webpack-dev-middleware@^5.3.0: schema-utils "^4.0.0" webpack-dev-server@^4.7.1: - version "4.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" - integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q== + version "4.7.4" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" + integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" "@types/serve-index" "^1.9.1" "@types/sockjs" "^0.3.33" "@types/ws" "^8.2.2" ansi-html-community "^0.0.8" bonjour "^3.5.0" - chokidar "^3.5.2" + chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" @@ -8163,8 +7515,8 @@ webpack-dev-server@^4.7.1: sockjs "^0.3.21" spdy "^4.0.2" strip-ansi "^7.0.0" - webpack-dev-middleware "^5.3.0" - ws "^8.1.0" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" webpack-merge@^5.8.0: version "5.8.0" @@ -8188,12 +7540,12 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.61.0: - version "5.68.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.68.0.tgz#a653a58ed44280062e47257f260117e4be90d560" - integrity sha512-zUcqaUO0772UuuW2bzaES2Zjlm/y3kRBQDVFVCge+s2Y8mwuUTdperGaAv65/NtRL/1zanpSJOq/MD8u61vo6g== + version "5.69.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" + integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" @@ -8241,6 +7593,14 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -8292,14 +7652,14 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.3.1: - version "7.4.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" - integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== -ws@^8.1.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" - integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== +ws@^8.4.2: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== xdg-basedir@^4.0.0: version "4.0.0" @@ -8329,9 +7689,9 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yarn@^1.17.3: - version "1.22.10" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c" - integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA== + version "1.22.17" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.17.tgz#bf910747d22497b573131f7341c0e1d15c74036c" + integrity sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ== yocto-queue@^0.1.0: version "0.1.0" From aa4ed1fc32fae7b608cad86b67267b7d461003d4 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 18 Feb 2022 12:27:40 +0100 Subject: [PATCH 107/109] update call to action for contributions --- website/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 026917b58f..7edcda8532 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -39,7 +39,7 @@ module.exports = { announcementBar: { id: 'help_with_docs', // Any value that will identify this message. content: - 'Help us make it better., .', + 'Help us make this documentation better. Edit on github..', backgroundColor: '#fff', // Defaults to `#fff`. textColor: '#000', // Defaults to `#000`. }, From f5b1ad5fef86c6197120ae635f747ad857cfec29 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 18 Feb 2022 12:35:03 +0100 Subject: [PATCH 108/109] change github action to deploy website --- .github/workflows/documentation.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index fc0705998f..747b9ad879 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -46,14 +46,8 @@ jobs: - name: 🔨 Build run: | cd website - if [ -e yarn.lock ]; then yarn install --frozen-lockfile - elif [ -e package-lock.json ]; then - npm ci - else - npm i - fi - npm run build + yarn build - name: 📂 Sync files uses: SamKirkland/FTP-Deploy-Action@4.0.0 From ef52c46c1d35b93a4e625524ccafcc152d2e609b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 18 Feb 2022 12:38:06 +0100 Subject: [PATCH 109/109] update node version --- .github/workflows/documentation.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 747b9ad879..f78e95528f 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -20,7 +20,8 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '12.x' + node-version: 14.x + cache: yarn - name: Test Build run: | cd website @@ -41,13 +42,19 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '12.x' - + node-version: 14.x + cache: yarn - name: 🔨 Build run: | cd website + if [ -e yarn.lock ]; then yarn install --frozen-lockfile - yarn build + elif [ -e package-lock.json ]; then + npm ci + else + npm i + fi + npm run build - name: 📂 Sync files uses: SamKirkland/FTP-Deploy-Action@4.0.0