[Automated] Merged develop into main

This commit is contained in:
pypebot 2022-11-16 04:39:15 +01:00 committed by GitHub
commit 44364265d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 556 additions and 45 deletions

View file

@ -0,0 +1,177 @@
import os
import shutil
from time import sleep
from openpype.client.entities import (
get_last_version_by_subset_id,
get_representations,
get_subsets,
)
from openpype.lib import PreLaunchHook
from openpype.lib.local_settings import get_local_site_id
from openpype.lib.profiles_filtering import filter_profiles
from openpype.pipeline.load.utils import get_representation_path
from openpype.settings.lib import get_project_settings
class CopyLastPublishedWorkfile(PreLaunchHook):
"""Copy last published workfile as first workfile.
Prelaunch hook works only if last workfile leads to not existing file.
- That is possible only if it's first version.
"""
# Before `AddLastWorkfileToLaunchArgs`
order = -1
app_groups = ["blender", "photoshop", "tvpaint", "aftereffects"]
def execute(self):
"""Check if local workfile doesn't exist, else copy it.
1- Check if setting for this feature is enabled
2- Check if workfile in work area doesn't exist
3- Check if published workfile exists and is copied locally in publish
4- Substitute copied published workfile as first workfile
Returns:
None: This is a void method.
"""
sync_server = self.modules_manager.get("sync_server")
if not sync_server or not sync_server.enabled:
self.log.deubg("Sync server module is not enabled or available")
return
# Check there is no workfile available
last_workfile = self.data.get("last_workfile_path")
if os.path.exists(last_workfile):
self.log.debug(
"Last workfile exists. Skipping {} process.".format(
self.__class__.__name__
)
)
return
# Get data
project_name = self.data["project_name"]
task_name = self.data["task_name"]
task_type = self.data["task_type"]
host_name = self.application.host_name
# Check settings has enabled it
project_settings = get_project_settings(project_name)
profiles = project_settings["global"]["tools"]["Workfiles"][
"last_workfile_on_startup"
]
filter_data = {
"tasks": task_name,
"task_types": task_type,
"hosts": host_name,
}
last_workfile_settings = filter_profiles(profiles, filter_data)
use_last_published_workfile = last_workfile_settings.get(
"use_last_published_workfile"
)
if use_last_published_workfile is None:
self.log.info(
(
"Seems like old version of settings is used."
' Can\'t access custom templates in host "{}".'.format(
host_name
)
)
)
return
elif use_last_published_workfile is False:
self.log.info(
(
'Project "{}" has turned off to use last published'
' workfile as first workfile for host "{}"'.format(
project_name, host_name
)
)
)
return
self.log.info("Trying to fetch last published workfile...")
project_doc = self.data.get("project_doc")
asset_doc = self.data.get("asset_doc")
anatomy = self.data.get("anatomy")
# Check it can proceed
if not project_doc and not asset_doc:
return
# Get subset id
subset_id = next(
(
subset["_id"]
for subset in get_subsets(
project_name,
asset_ids=[asset_doc["_id"]],
fields=["_id", "data.family", "data.families"],
)
if subset["data"].get("family") == "workfile"
# Legacy compatibility
or "workfile" in subset["data"].get("families", {})
),
None,
)
if not subset_id:
self.log.debug(
'No any workfile for asset "{}".'.format(asset_doc["name"])
)
return
# Get workfile representation
last_version_doc = get_last_version_by_subset_id(
project_name, subset_id, fields=["_id"]
)
if not last_version_doc:
self.log.debug("Subset does not have any versions")
return
workfile_representation = next(
(
representation
for representation in get_representations(
project_name, version_ids=[last_version_doc["_id"]]
)
if representation["context"]["task"]["name"] == task_name
),
None,
)
if not workfile_representation:
self.log.debug(
'No published workfile for task "{}" and host "{}".'.format(
task_name, host_name
)
)
return
local_site_id = get_local_site_id()
sync_server.add_site(
project_name,
workfile_representation["_id"],
local_site_id,
force=True,
priority=99,
reset_timer=True,
)
while not sync_server.is_representation_on_site(
project_name, workfile_representation["_id"], local_site_id
):
sleep(5)
# Get paths
published_workfile_path = get_representation_path(
workfile_representation, root=anatomy.roots
)
local_workfile_dir = os.path.dirname(last_workfile)
# Copy file and substitute path
self.data["last_workfile_path"] = shutil.copy(
published_workfile_path, local_workfile_dir
)

View file

@ -0,0 +1,132 @@
import os
from openpype.pipeline import (
legacy_io,
load,
get_representation_path
)
from openpype.settings import get_project_settings
class AlembicStandinLoader(load.LoaderPlugin):
"""Load Alembic as Arnold Standin"""
families = ["animation", "model", "pointcache"]
representations = ["abc"]
label = "Import Alembic as Arnold Standin"
order = -5
icon = "code-fork"
color = "orange"
def load(self, context, name, namespace, options):
import maya.cmds as cmds
import mtoa.ui.arnoldmenu
from openpype.hosts.maya.api.pipeline import containerise
from openpype.hosts.maya.api.lib import unique_namespace
version = context["version"]
version_data = version.get("data", {})
family = version["data"]["families"]
self.log.info("version_data: {}\n".format(version_data))
self.log.info("family: {}\n".format(family))
frameStart = version_data.get("frameStart", None)
asset = context["asset"]["name"]
namespace = namespace or unique_namespace(
asset + "_",
prefix="_" if asset[0].isdigit() else "",
suffix="_",
)
# Root group
label = "{}:{}".format(namespace, name)
root = cmds.group(name=label, empty=True)
settings = get_project_settings(os.environ['AVALON_PROJECT'])
colors = settings["maya"]["load"]["colors"]
fps = legacy_io.Session["AVALON_FPS"]
c = colors.get(family[0])
if c is not None:
r = (float(c[0]) / 255)
g = (float(c[1]) / 255)
b = (float(c[2]) / 255)
cmds.setAttr(root + ".useOutlinerColor", 1)
cmds.setAttr(root + ".outlinerColor",
r, g, b)
transform_name = label + "_ABC"
standinShape = cmds.ls(mtoa.ui.arnoldmenu.createStandIn())[0]
standin = cmds.listRelatives(standinShape, parent=True,
typ="transform")
standin = cmds.rename(standin, transform_name)
standinShape = cmds.listRelatives(standin, children=True)[0]
cmds.parent(standin, root)
# Set the standin filepath
cmds.setAttr(standinShape + ".dso", self.fname, type="string")
cmds.setAttr(standinShape + ".abcFPS", float(fps))
if frameStart is None:
cmds.setAttr(standinShape + ".useFrameExtension", 0)
elif "model" in family:
cmds.setAttr(standinShape + ".useFrameExtension", 0)
else:
cmds.setAttr(standinShape + ".useFrameExtension", 1)
nodes = [root, standin]
self[:] = nodes
return containerise(
name=name,
namespace=namespace,
nodes=nodes,
context=context,
loader=self.__class__.__name__)
def update(self, container, representation):
import pymel.core as pm
path = get_representation_path(representation)
fps = legacy_io.Session["AVALON_FPS"]
# Update the standin
standins = list()
members = pm.sets(container['objectName'], query=True)
self.log.info("container:{}".format(container))
for member in members:
shape = member.getShape()
if (shape and shape.type() == "aiStandIn"):
standins.append(shape)
for standin in standins:
standin.dso.set(path)
standin.abcFPS.set(float(fps))
if "modelMain" in container['objectName']:
standin.useFrameExtension.set(0)
else:
standin.useFrameExtension.set(1)
container = pm.PyNode(container["objectName"])
container.representation.set(str(representation["_id"]))
def switch(self, container, representation):
self.update(container, representation)
def remove(self, container):
import maya.cmds as cmds
members = cmds.sets(container['objectName'], query=True)
cmds.lockNode(members, lock=False)
cmds.delete([container['objectName']] + members)
# Clean up the namespace
try:
cmds.namespace(removeNamespace=container['namespace'],
deleteNamespaceContent=True)
except RuntimeError:
pass

View file

@ -73,8 +73,8 @@ class YetiCacheLoader(load.LoaderPlugin):
c = colors.get(family)
if c is not None:
cmds.setAttr(group_name + ".useOutlinerColor", 1)
cmds.setAttr(group_name + ".outlinerColor",
cmds.setAttr(group_node + ".useOutlinerColor", 1)
cmds.setAttr(group_node + ".outlinerColor",
(float(c[0])/255),
(float(c[1])/255),
(float(c[2])/255)

View file

@ -6,7 +6,7 @@ class CollectOutputFrameRange(pyblish.api.ContextPlugin):
When instances are collected context does not contain `frameStart` and
`frameEnd` keys yet. They are collected in global plugin
`CollectAvalonEntities`.
`CollectContextEntities`.
"""
label = "Collect output frame range"
order = pyblish.api.CollectorOrder

View file

@ -39,7 +39,7 @@ class ValidateMarks(pyblish.api.ContextPlugin):
def get_expected_data(context):
scene_mark_in = context.data["sceneMarkIn"]
# Data collected in `CollectAvalonEntities`
# Data collected in `CollectContextEntities`
frame_end = context.data["frameEnd"]
frame_start = context.data["frameStart"]
handle_start = context.data["handleStart"]

View file

@ -13,7 +13,7 @@ class ValidateWorkfileData(pyblish.api.ContextPlugin):
targets = ["tvpaint_worker"]
def process(self, context):
# Data collected in `CollectAvalonEntities`
# Data collected in `CollectContextEntities`
frame_start = context.data["frameStart"]
frame_end = context.data["frameEnd"]
handle_start = context.data["handleStart"]

View file

@ -541,6 +541,13 @@ class FileDefItem(object):
return ext
return None
@property
def lower_ext(self):
ext = self.ext
if ext is not None:
return ext.lower()
return ext
@property
def is_dir(self):
if self.is_empty:

View file

@ -0,0 +1,37 @@
from aiohttp.web_response import Response
from openpype.lib import Logger
class SyncServerModuleRestApi:
"""
REST API endpoint used for calling from hosts when context change
happens in Workfile app.
"""
def __init__(self, user_module, server_manager):
self._log = None
self.module = user_module
self.server_manager = server_manager
self.prefix = "/sync_server"
self.register()
@property
def log(self):
if self._log is None:
self._log = Logger.get_logger(self.__class__.__name__)
return self._log
def register(self):
self.server_manager.add_route(
"POST",
self.prefix + "/reset_timer",
self.reset_timer,
)
async def reset_timer(self, _request):
"""Force timer to run immediately."""
self.module.reset_timer()
return Response(status=200)

View file

@ -236,6 +236,7 @@ class SyncServerThread(threading.Thread):
"""
def __init__(self, module):
self.log = Logger.get_logger(self.__class__.__name__)
super(SyncServerThread, self).__init__()
self.module = module
self.loop = None

View file

@ -136,14 +136,14 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
""" Start of Public API """
def add_site(self, project_name, representation_id, site_name=None,
force=False):
force=False, priority=None, reset_timer=False):
"""
Adds new site to representation to be synced.
'project_name' must have synchronization enabled (globally or
project only)
Used as a API endpoint from outside applications (Loader etc).
Used as an API endpoint from outside applications (Loader etc).
Use 'force' to reset existing site.
@ -152,6 +152,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
representation_id (string): MongoDB _id value
site_name (string): name of configured and active site
force (bool): reset site if exists
priority (int): set priority
reset_timer (bool): if delay timer should be reset, eg. user mark
some representation to be synced manually
Throws:
SiteAlreadyPresentError - if adding already existing site and
@ -167,7 +170,11 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
self.reset_site_on_representation(project_name,
representation_id,
site_name=site_name,
force=force)
force=force,
priority=priority)
if reset_timer:
self.reset_timer()
def remove_site(self, project_name, representation_id, site_name,
remove_local_files=False):
@ -911,7 +918,59 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
In case of user's involvement (reset site), start that right away.
"""
self.sync_server_thread.reset_timer()
if not self.enabled:
return
if self.sync_server_thread is None:
self._reset_timer_with_rest_api()
else:
self.sync_server_thread.reset_timer()
def is_representation_on_site(
self, project_name, representation_id, site_name
):
"""Checks if 'representation_id' has all files avail. on 'site_name'"""
representation = get_representation_by_id(project_name,
representation_id,
fields=["_id", "files"])
if not representation:
return False
on_site = False
for file_info in representation.get("files", []):
for site in file_info.get("sites", []):
if site["name"] != site_name:
continue
if (site.get("progress") or site.get("error") or
not site.get("created_dt")):
return False
on_site = True
return on_site
def _reset_timer_with_rest_api(self):
# POST to webserver sites to add to representations
webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL")
if not webserver_url:
self.log.warning("Couldn't find webserver url")
return
rest_api_url = "{}/sync_server/reset_timer".format(
webserver_url
)
try:
import requests
except Exception:
self.log.warning(
"Couldn't add sites to representations "
"('requests' is not available)"
)
return
requests.post(rest_api_url)
def get_enabled_projects(self):
"""Returns list of projects which have SyncServer enabled."""
@ -1544,12 +1603,12 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
Args:
project_name (string): name of project - force to db connection as
each file might come from different collection
new_file_id (string):
new_file_id (string): only present if file synced successfully
file (dictionary): info about processed file (pulled from DB)
representation (dictionary): parent repr of file (from DB)
site (string): label ('gdrive', 'S3')
error (string): exception message
progress (float): 0-1 of progress of upload/download
progress (float): 0-0.99 of progress of upload/download
priority (int): 0-100 set priority
Returns:
@ -1655,7 +1714,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
def reset_site_on_representation(self, project_name, representation_id,
side=None, file_id=None, site_name=None,
remove=False, pause=None, force=False):
remove=False, pause=None, force=False,
priority=None):
"""
Reset information about synchronization for particular 'file_id'
and provider.
@ -1678,6 +1738,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
remove (bool): if True remove site altogether
pause (bool or None): if True - pause, False - unpause
force (bool): hard reset - currently only for add_site
priority (int): set priority
Raises:
SiteAlreadyPresentError - if adding already existing site and
@ -1705,6 +1766,10 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
elem = {"name": site_name}
# Add priority
if priority:
elem["priority"] = priority
if file_id: # reset site for particular file
self._reset_site_for_file(project_name, representation_id,
elem, file_id, site_name)
@ -2089,6 +2154,15 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
def cli(self, click_group):
click_group.add_command(cli_main)
# Webserver module implementation
def webserver_initialization(self, server_manager):
"""Add routes for syncs."""
if self.tray_initialized:
from .rest_api import SyncServerModuleRestApi
self.rest_api_obj = SyncServerModuleRestApi(
self, server_manager
)
@click.group(SyncServerModule.name, help="SyncServer module related commands.")
def cli_main():

View file

@ -21,7 +21,7 @@ class TimersManagerModuleRestApi:
@property
def log(self):
if self._log is None:
self._log = Logger.get_logger(self.__ckass__.__name__)
self._log = Logger.get_logger(self.__class__.__name__)
return self._log
def register(self):

View file

@ -15,7 +15,6 @@ Provides:
import json
import pyblish.api
from openpype.pipeline import legacy_io
from openpype.pipeline.template_data import get_template_data
@ -53,7 +52,7 @@ class CollectAnatomyContextData(pyblish.api.ContextPlugin):
asset_entity = context.data.get("assetEntity")
task_name = None
if asset_entity:
task_name = legacy_io.Session["AVALON_TASK"]
task_name = context.data["task"]
anatomy_data = get_template_data(
project_entity, asset_entity, task_name, host_name, system_settings

View file

@ -3,6 +3,8 @@
Requires:
session -> AVALON_ASSET
context -> projectName
context -> asset
context -> task
Provides:
context -> projectEntity - Project document from database.
@ -13,20 +15,19 @@ Provides:
import pyblish.api
from openpype.client import get_project, get_asset_by_name
from openpype.pipeline import legacy_io, KnownPublishError
from openpype.pipeline import KnownPublishError
class CollectAvalonEntities(pyblish.api.ContextPlugin):
"""Collect Anatomy into Context."""
class CollectContextEntities(pyblish.api.ContextPlugin):
"""Collect entities into Context."""
order = pyblish.api.CollectorOrder - 0.1
label = "Collect Avalon Entities"
label = "Collect Context Entities"
def process(self, context):
legacy_io.install()
project_name = context.data["projectName"]
asset_name = legacy_io.Session["AVALON_ASSET"]
task_name = legacy_io.Session["AVALON_TASK"]
asset_name = context.data["asset"]
task_name = context.data["task"]
project_entity = get_project(project_name)
if not project_entity:

View file

@ -458,7 +458,8 @@
"hosts": [],
"task_types": [],
"tasks": [],
"enabled": true
"enabled": true,
"use_last_published_workfile": false
}
],
"open_workfile_tool_on_startup": [

View file

@ -303,5 +303,12 @@
"extensions": [
".mov"
]
},
"publish": {
"ValidateFrameRange": {
"enabled": true,
"optional": true,
"active": true
}
}
}

View file

@ -311,6 +311,24 @@
"object_type": "text"
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "publish",
"label": "Publish plugins",
"children": [
{
"type": "schema_template",
"name": "template_validate_plugin",
"template_data": [
{
"key": "ValidateFrameRange",
"label": "Validate frame range"
}
]
}
]
}
]
}

View file

@ -149,6 +149,11 @@
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "boolean",
"key": "use_last_published_workfile",
"label": "Use last published workfile"
}
]
}

View file

@ -0,0 +1,26 @@
[
{
"type": "dict",
"collapsible": true,
"key": "{key}",
"label": "{label}",
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "boolean",
"key": "optional",
"label": "Optional"
},
{
"type": "boolean",
"key": "active",
"label": "Active"
}
]
}
]

View file

@ -349,7 +349,7 @@ class FilesModel(QtGui.QStandardItemModel):
item.setData(file_item.filenames, FILENAMES_ROLE)
item.setData(file_item.directory, DIRPATH_ROLE)
item.setData(icon_pixmap, ITEM_ICON_ROLE)
item.setData(file_item.ext, EXT_ROLE)
item.setData(file_item.lower_ext, EXT_ROLE)
item.setData(file_item.is_dir, IS_DIR_ROLE)
item.setData(file_item.is_sequence, IS_SEQUENCE_ROLE)
@ -463,7 +463,7 @@ class FilesProxyModel(QtCore.QSortFilterProxyModel):
for filepath in filepaths:
if os.path.isfile(filepath):
_, ext = os.path.splitext(filepath)
if ext in self._allowed_extensions:
if ext.lower() in self._allowed_extensions:
return True
elif self._allow_folders:
@ -475,7 +475,7 @@ class FilesProxyModel(QtCore.QSortFilterProxyModel):
for filepath in filepaths:
if os.path.isfile(filepath):
_, ext = os.path.splitext(filepath)
if ext in self._allowed_extensions:
if ext.lower() in self._allowed_extensions:
filtered_paths.append(filepath)
elif self._allow_folders:

View file

@ -1543,15 +1543,37 @@
dependencies:
"@hapi/hoek" "^9.0.0"
"@jridgewell/gen-mapping@^0.3.0":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
dependencies:
"@jridgewell/set-array" "^1.0.1"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.9"
"@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==
version "3.1.0"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
"@jridgewell/set-array@^1.0.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
"@jridgewell/source-map@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb"
integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==
dependencies:
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@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==
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/trace-mapping@^0.3.0":
version "0.3.4"
@ -1561,6 +1583,14 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping@^0.3.9":
version "0.3.14"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed"
integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==
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"
@ -2140,10 +2170,10 @@ acorn@^6.1.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
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==
acorn@^8.0.4, acorn@^8.4.1, acorn@^8.5.0:
version "8.7.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
address@^1.0.1, address@^1.1.2:
version "1.1.2"
@ -6843,11 +6873,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@~0.7.2:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
sourcemap-codec@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
@ -7053,12 +7078,13 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.4:
terser "^5.7.2"
terser@^5.10.0, terser@^5.7.2:
version "5.10.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc"
integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==
version "5.14.2"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==
dependencies:
"@jridgewell/source-map" "^0.3.2"
acorn "^8.5.0"
commander "^2.20.0"
source-map "~0.7.2"
source-map-support "~0.5.20"
text-table@^0.2.0: